142b3d13cb5525efd3ab0f441bfa50aa20a47863
[debian/openrocket] / core / src / net / sf / openrocket / motor / Manufacturer.java
1 package net.sf.openrocket.motor;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashSet;
6 import java.util.List;
7 import java.util.Locale;
8 import java.util.Set;
9 import java.util.concurrent.ConcurrentHashMap;
10
11 /**
12  * Class containing information about motor manufacturers.
13  * 
14  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
15  */
16 public class Manufacturer {
17
18         private static class ManufacturerList extends ConcurrentHashMap<String,Manufacturer> {
19                 
20                 void add( Manufacturer m ) {
21                         for( String s : m.getAllNames() ) {
22                                 Manufacturer previousRegistered;
23                                 if ( (previousRegistered = putIfAbsent( s, m )) != null ) {
24                                         throw new IllegalStateException("Manufacturer name clash between " +
25                                                         "manufacturers " + previousRegistered + " and " + m + " name " + s);
26                                 }
27                         }
28                 }
29                 
30         }
31         private static ManufacturerList manufacturers = new ManufacturerList();
32
33         static {
34                 
35                 // AeroTech has many name combinations...
36                 List<String> names = new ArrayList<String>();
37                 for (String s : new String[] { "A", "AT", "AERO", "AEROT", "AEROTECH" }) {
38                         names.add(s);
39                         names.add(s + "-RMS");
40                         names.add(s + "-RCS");
41                         names.add("RCS-" + s);
42                         names.add(s + "-APOGEE");
43                 }
44                 names.add("ISP");
45                 
46                 // Aerotech has single-use, reload and hybrid motors
47                 manufacturers.add(new Manufacturer("AeroTech", "AeroTech", Motor.Type.UNKNOWN,
48                                 names.toArray(new String[0])));
49                 
50                 manufacturers.add(new Manufacturer("Alpha Hybrid Rocketry LLC", "Alpha Hybrid Rocketry", Motor.Type.HYBRID,
51                                 "AHR", "ALPHA", "ALPHA HYBRID", "ALPHA HYBRIDS", "ALPHA HYBRIDS ROCKETRY"));
52                 
53                 // TODO: HIGH: AMW/ProX - how to classify?
54                 
55                 manufacturers.add(new Manufacturer("Animal Motor Works", "Animal Motor Works", Motor.Type.RELOAD,
56                                 "AMW", "AW", "ANIMAL"));
57                 
58                 manufacturers.add(new Manufacturer("Apogee", "Apogee", Motor.Type.SINGLE,
59                                 "AP", "APOG", "P"));
60                 
61                 manufacturers.add(new Manufacturer("Cesaroni Technology Inc.", "Cesaroni Technology", Motor.Type.RELOAD,
62                                 "CES", "CESARONI", "CESARONI TECHNOLOGY INCORPORATED", "CTI",
63                                 "CS", "CSR", "PRO38", "ABC"));
64                 
65                 manufacturers.add(new Manufacturer("Contrail Rockets", "Contrail Rockets", Motor.Type.HYBRID,
66                                 "CR", "CONTR", "CONTRAIL", "CONTRAIL ROCKET"));
67                 
68                 manufacturers.add(new Manufacturer("Estes", "Estes", Motor.Type.SINGLE,
69                                 "E", "ES"));
70                 
71                 // Ellis Mountain has both single-use and reload motors
72                 manufacturers.add(new Manufacturer("Ellis Mountain", "Ellis Mountain", Motor.Type.UNKNOWN,
73                                 "EM", "ELLIS", "ELLIS MOUNTAIN ROCKET", "ELLIS MOUNTAIN ROCKETS"));
74                 
75                 manufacturers.add(new Manufacturer("Gorilla Rocket Motors", "Gorilla Rocket Motors", Motor.Type.RELOAD,
76                                 "GR", "GORILLA", "GORILLA ROCKET", "GORILLA ROCKETS", "GORILLA MOTOR",
77                                 "GORILLA MOTORS", "GORILLA ROCKET MOTOR"));
78                 
79                 manufacturers.add(new Manufacturer("HyperTEK", "HyperTEK", Motor.Type.HYBRID,
80                                 "H", "HT", "HYPER"));
81                 
82                 manufacturers.add(new Manufacturer("Kosdon by AeroTech", "Kosdon by AeroTech", Motor.Type.RELOAD,
83                                 "K", "KBA", "K-AT", "KOS", "KOSDON", "KOSDON/AT", "KOSDON/AEROTECH"));
84                 
85                 manufacturers.add(new Manufacturer("Loki Research", "Loki Research", Motor.Type.RELOAD,
86                                 "LOKI", "LR"));
87                 
88                 manufacturers.add(new Manufacturer("Public Missiles, Ltd.", "Public Missiles", Motor.Type.SINGLE,
89                                 "PM", "PML", "PUBLIC MISSILES LIMITED"));
90                 
91                 manufacturers.add(new Manufacturer("Propulsion Polymers", "Propulsion Polymers", Motor.Type.HYBRID,
92                                 "PP", "PROP", "PROPULSION"));
93                 
94                 manufacturers.add(new Manufacturer("Quest", "Quest", Motor.Type.SINGLE,
95                                 "Q", "QU"));
96                 
97                 manufacturers.add(new Manufacturer("RATT Works", "RATT Works", Motor.Type.HYBRID,
98                                 "RATT", "RT", "RTW"));
99                 
100                 manufacturers.add(new Manufacturer("Roadrunner Rocketry", "Roadrunner Rocketry", Motor.Type.SINGLE,
101                                 "RR", "ROADRUNNER"));
102                 
103                 manufacturers.add(new Manufacturer("Rocketvision", "Rocketvision", Motor.Type.SINGLE,
104                                 "RV", "ROCKET VISION"));
105                 
106                 manufacturers.add(new Manufacturer("Sky Ripper Systems", "Sky Ripper Systems", Motor.Type.HYBRID,
107                                 "SR", "SRS", "SKYR", "SKYRIPPER", "SKY RIPPER", "SKYRIPPER SYSTEMS"));
108                 
109                 manufacturers.add(new Manufacturer("West Coast Hybrids", "West Coast Hybrids", Motor.Type.HYBRID,
110                                 "WCH", "WCR", "WEST COAST", "WEST COAST HYBRID"));
111                 
112                 // German WECO Feuerwerk, previously Sachsen Feuerwerk
113                 manufacturers.add(new Manufacturer("WECO Feuerwerk", "WECO Feuerwerk", Motor.Type.SINGLE,
114                                 "WECO", "WECO FEUERWERKS", "SF", "SACHSEN", "SACHSEN FEUERWERK",
115                                 "SACHSEN FEUERWERKS"));
116                 
117         }
118         
119         
120         
121         private final String displayName;
122         private final String simpleName;
123         private final Set<String> allNames;
124         private final Set<String> searchNames;
125         private final Motor.Type motorType;
126         
127         
128         private Manufacturer(String displayName, String simpleName, Motor.Type motorType, String... alternateNames) {
129                 this.displayName = displayName;
130                 this.simpleName = simpleName;
131                 this.motorType = motorType;
132                 if (motorType == null) {
133                         throw new IllegalArgumentException("motorType cannot be null");
134                 }
135                 
136                 Set<String> all = new HashSet<String>();
137                 Set<String> search = new HashSet<String>();
138                 
139                 all.add(displayName);
140                 all.add(simpleName);
141                 search.add(generateSearchString(displayName));
142                 search.add(generateSearchString(simpleName));
143                 
144                 for (String name : alternateNames) {
145                         all.add(name);
146                         search.add(generateSearchString(name));
147                 }
148                 
149                 this.allNames = Collections.unmodifiableSet(all);
150                 this.searchNames = Collections.unmodifiableSet(search);
151         }
152         
153         
154         /**
155          * Returns the display name of the manufacturer.  This is the value that
156          * should be presented in the UI to the user.
157          * 
158          * @return      the display name
159          */
160         public String getDisplayName() {
161                 return displayName;
162         }
163         
164         
165         /**
166          * Returns the simple name of the manufacturer.  This should be used for example
167          * when saving the manufacturer for compatibility.
168          * 
169          * @return      the simple name.
170          */
171         public String getSimpleName() {
172                 return simpleName;
173         }
174         
175         
176         /**
177          * Return all names of the manufacturer.  This includes all kinds of
178          * codes that correspond to the manufacturer (for example "A" for AeroTech).
179          * 
180          * @return      an unmodifiable set of the alternative names.
181          */
182         public Set<String> getAllNames() {
183                 return allNames;
184         }
185         
186         
187         /**
188          * Return the motor type that this manufacturer produces if it produces only one motor type.
189          * If the manufacturer manufactures multiple motor types or the type is unknown,
190          * type <code>UNKNOWN</code> is returned. 
191          * 
192          * @return      the manufactured motor type, or <code>UNKNOWN</code>.
193          */
194         public Motor.Type getMotorType() {
195                 return motorType;
196         }
197         
198         
199         /**
200          * Check whether the display, simple or any of the alternative names matches the
201          * specified name.  Matching is performed case insensitively and ignoring any
202          * non-letter and non-number characters.
203          * 
204          * @param name  the name to search for.
205          * @return              whether this manufacturer matches the request.
206          */
207         public boolean matches(String name) {
208                 if (name == null)
209                         return false;
210                 return this.searchNames.contains(generateSearchString(name));
211         }
212         
213         
214         /**
215          * Return the display name of the manufacturer.
216          */
217         @Override
218         public String toString() {
219                 return displayName;
220         }
221         
222         
223         /**
224          * Returns a manufacturer for the given name.  The manufacturer is searched for
225          * within the manufacturers and if a match is found the corresponding
226          * object is returned.  If not, a new manufacturer is returned with display and
227          * simple name the name specified.  Subsequent requests for the same (or corresponding)
228          * manufacturer name will return the same object.
229          * 
230          * @param name  the manufacturer name to search for.
231          * @return              the Manufacturer object corresponding the name.
232          */
233         public static Manufacturer getManufacturer(String name) {
234                 Manufacturer m = manufacturers.get(name);
235                 if ( m != null ) {
236                         return m;
237                 }
238
239                 m = new Manufacturer(name.trim(), name.trim(), Motor.Type.UNKNOWN);
240
241                 Manufacturer oldManu = manufacturers.putIfAbsent(name, m);
242                 return  (oldManu != null) ? oldManu : m;
243         }
244         
245         
246         
247         
248         private String generateSearchString(String str) {
249                 return str.toLowerCase(Locale.getDefault()).replaceAll("[^a-zA-Z0-9]+", " ").trim();
250         }
251         
252 }