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