1 package net.sf.openrocket.motor;
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.HashSet;
7 import java.util.Locale;
9 import java.util.concurrent.ConcurrentHashMap;
12 * Class containing information about motor manufacturers.
14 * @author Sampo Niskanen <sampo.niskanen@iki.fi>
16 public class Manufacturer {
18 private static class ManufacturerList extends ConcurrentHashMap<String,Manufacturer> {
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);
31 private static ManufacturerList manufacturers = new ManufacturerList();
35 // AeroTech has many name combinations...
36 List<String> names = new ArrayList<String>();
37 for (String s : new String[] { "A", "AT", "AERO", "AEROT", "AEROTECH" }) {
39 names.add(s + "-RMS");
40 names.add(s + "-RCS");
41 names.add("RCS-" + s);
42 names.add(s + "-APOGEE");
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])));
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"));
53 // TODO: HIGH: AMW/ProX - how to classify?
55 manufacturers.add(new Manufacturer("Animal Motor Works", "Animal Motor Works", Motor.Type.RELOAD,
56 "AMW", "AW", "ANIMAL"));
58 manufacturers.add(new Manufacturer("Apogee", "Apogee", Motor.Type.SINGLE,
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"));
65 manufacturers.add(new Manufacturer("Contrail Rockets", "Contrail Rockets", Motor.Type.HYBRID,
66 "CR", "CONTR", "CONTRAIL", "CONTRAIL ROCKET"));
68 manufacturers.add(new Manufacturer("Estes", "Estes", Motor.Type.SINGLE,
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"));
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"));
79 manufacturers.add(new Manufacturer("HyperTEK", "HyperTEK", Motor.Type.HYBRID,
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"));
85 manufacturers.add(new Manufacturer("Loki Research", "Loki Research", Motor.Type.RELOAD,
88 manufacturers.add(new Manufacturer("Public Missiles, Ltd.", "Public Missiles", Motor.Type.SINGLE,
89 "PM", "PML", "PUBLIC MISSILES LIMITED"));
91 manufacturers.add(new Manufacturer("Propulsion Polymers", "Propulsion Polymers", Motor.Type.HYBRID,
92 "PP", "PROP", "PROPULSION"));
94 manufacturers.add(new Manufacturer("Quest", "Quest", Motor.Type.SINGLE,
97 manufacturers.add(new Manufacturer("RATT Works", "RATT Works", Motor.Type.HYBRID,
98 "RATT", "RT", "RTW"));
100 manufacturers.add(new Manufacturer("Roadrunner Rocketry", "Roadrunner Rocketry", Motor.Type.SINGLE,
101 "RR", "ROADRUNNER"));
103 manufacturers.add(new Manufacturer("Rocketvision", "Rocketvision", Motor.Type.SINGLE,
104 "RV", "ROCKET VISION"));
106 manufacturers.add(new Manufacturer("Sky Ripper Systems", "Sky Ripper Systems", Motor.Type.HYBRID,
107 "SR", "SRS", "SKYR", "SKYRIPPER", "SKY RIPPER", "SKYRIPPER SYSTEMS"));
109 manufacturers.add(new Manufacturer("West Coast Hybrids", "West Coast Hybrids", Motor.Type.HYBRID,
110 "WCH", "WCR", "WEST COAST", "WEST COAST HYBRID"));
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"));
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;
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");
136 Set<String> all = new HashSet<String>();
137 Set<String> search = new HashSet<String>();
139 all.add(displayName);
141 search.add(generateSearchString(displayName));
142 search.add(generateSearchString(simpleName));
144 for (String name : alternateNames) {
146 search.add(generateSearchString(name));
149 this.allNames = Collections.unmodifiableSet(all);
150 this.searchNames = Collections.unmodifiableSet(search);
155 * Returns the display name of the manufacturer. This is the value that
156 * should be presented in the UI to the user.
158 * @return the display name
160 public String getDisplayName() {
166 * Returns the simple name of the manufacturer. This should be used for example
167 * when saving the manufacturer for compatibility.
169 * @return the simple name.
171 public String getSimpleName() {
177 * Return all names of the manufacturer. This includes all kinds of
178 * codes that correspond to the manufacturer (for example "A" for AeroTech).
180 * @return an unmodifiable set of the alternative names.
182 public Set<String> getAllNames() {
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.
192 * @return the manufactured motor type, or <code>UNKNOWN</code>.
194 public Motor.Type getMotorType() {
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.
204 * @param name the name to search for.
205 * @return whether this manufacturer matches the request.
207 public boolean matches(String name) {
210 return this.searchNames.contains(generateSearchString(name));
215 * Return the display name of the manufacturer.
218 public String toString() {
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.
230 * @param name the manufacturer name to search for.
231 * @return the Manufacturer object corresponding the name.
233 public static Manufacturer getManufacturer(String name) {
234 Manufacturer m = manufacturers.get(name);
239 m = new Manufacturer(name.trim(), name.trim(), Motor.Type.UNKNOWN);
241 Manufacturer oldManu = manufacturers.putIfAbsent(name, m);
242 return (oldManu != null) ? oldManu : m;
248 private String generateSearchString(String str) {
249 return str.toLowerCase(Locale.getDefault()).replaceAll("[^a-zA-Z0-9]+", " ").trim();