Refactored the ComponentPreset.create method into the ComponentPresetFactory object...
[debian/openrocket] / core / src / net / sf / openrocket / preset / ComponentPresetFactory.java
1 package net.sf.openrocket.preset;
2
3 import static net.sf.openrocket.preset.ComponentPreset.FORE_OUTER_DIAMETER;
4 import static net.sf.openrocket.preset.ComponentPreset.INNER_DIAMETER;
5 import static net.sf.openrocket.preset.ComponentPreset.LENGTH;
6 import static net.sf.openrocket.preset.ComponentPreset.MANUFACTURER;
7 import static net.sf.openrocket.preset.ComponentPreset.MASS;
8 import static net.sf.openrocket.preset.ComponentPreset.MATERIAL;
9 import static net.sf.openrocket.preset.ComponentPreset.OUTER_DIAMETER;
10 import static net.sf.openrocket.preset.ComponentPreset.PARTNO;
11 import static net.sf.openrocket.preset.ComponentPreset.SHAPE;
12 import static net.sf.openrocket.preset.ComponentPreset.THICKNESS;
13 import static net.sf.openrocket.preset.ComponentPreset.TYPE;
14 import net.sf.openrocket.material.Material;
15 import net.sf.openrocket.preset.ComponentPreset.Type;
16 import net.sf.openrocket.rocketcomponent.BodyTube;
17 import net.sf.openrocket.rocketcomponent.Bulkhead;
18 import net.sf.openrocket.rocketcomponent.NoseCone;
19 import net.sf.openrocket.rocketcomponent.Transition;
20
21 public abstract class ComponentPresetFactory {
22
23         public static ComponentPreset create( TypedPropertyMap props ) throws InvalidComponentPresetException {
24
25                 ComponentPreset preset = new ComponentPreset();
26                 // First do validation.
27                 if ( !props.containsKey(TYPE)) {
28                         throw new InvalidComponentPresetException("No Type specified " + props.toString() );
29                 }
30
31                 if (!props.containsKey(MANUFACTURER)) {
32                         throw new InvalidComponentPresetException("No Manufacturer specified " + props.toString() );
33                 }
34
35                 if (!props.containsKey(PARTNO)) {
36                         throw new InvalidComponentPresetException("No PartNo specified " + props.toString() );
37                 }
38
39                 preset.putAll(props);
40
41                 // Should check for various bits of each of the types.
42                 Type t = props.get(TYPE);
43                 switch ( t ) {
44                 case BODY_TUBE: {
45                         makeBodyTube(preset);
46                         break;
47                 }
48                 case NOSE_CONE: {
49                         makeNoseCone(preset);
50                         break;
51                 }
52                 case TRANSITION: {
53                         makeTransition(preset);
54                         break;
55                 }
56                 case BULK_HEAD: {
57                         makeBulkHead(preset);
58                         break;
59                 }
60                 }
61
62                 preset.computeDigest();
63
64                 return preset;
65
66         }
67
68         private static void makeBodyTube( ComponentPreset preset ) throws InvalidComponentPresetException {
69                 
70                 checkRequiredFields( preset, LENGTH );
71
72                 BodyTube bt = new BodyTube();
73
74                 bt.setLength(preset.get(LENGTH));
75
76                 // Need to verify contains 2 of OD, thickness, ID.  Compute the third.
77                 boolean hasOd = preset.has(OUTER_DIAMETER);
78                 boolean hasId = preset.has(INNER_DIAMETER);
79                 boolean hasThickness = preset.has(THICKNESS);
80
81                 if ( hasOd ) {
82                         double outerRadius = preset.get(OUTER_DIAMETER)/2.0;
83                         double thickness = 0;
84                         bt.setOuterRadius( outerRadius );
85                         if ( hasId ) {
86                                 thickness = outerRadius - preset.get(INNER_DIAMETER)/2.0;
87                         } else if ( hasThickness ) {
88                                 thickness = preset.get(THICKNESS);
89                         } else {
90                                 throw new InvalidComponentPresetException("Body tube preset underspecified " + preset.toString());
91                         }
92                         bt.setThickness( thickness );
93                 } else {
94                         if ( ! hasId && ! hasThickness ) {
95                                 throw new InvalidComponentPresetException("Body tube preset underspecified " + preset.toString());
96                         }
97                         double innerRadius = preset.get(INNER_DIAMETER)/2.0;
98                         double thickness = preset.get(THICKNESS);
99                         bt.setOuterRadius(innerRadius + thickness);
100                         bt.setThickness(thickness);
101                 }
102
103                 preset.put(OUTER_DIAMETER, bt.getOuterRadius() *2.0);
104                 preset.put(INNER_DIAMETER, bt.getInnerRadius() *2.0);
105                 preset.put(THICKNESS, bt.getThickness());
106
107                 // Need to translate Mass to Density.
108                 if ( preset.has(MASS) ) {
109                         String materialName = "TubeCustom";
110                         if ( preset.has(MATERIAL) ) {
111                                 materialName = preset.get(MATERIAL).getName();
112                         }
113                         Material m = Material.newMaterial(Material.Type.BULK, materialName, preset.get(MASS)/bt.getComponentVolume(), false);
114                         preset.put(MATERIAL, m);
115                 }
116
117
118         }
119
120         private static void makeNoseCone( ComponentPreset preset ) throws InvalidComponentPresetException {
121
122                 checkRequiredFields( preset, LENGTH, SHAPE, OUTER_DIAMETER );
123
124                 if ( preset.has(MASS) ) {
125                         // compute a density for this component
126                         double mass = preset.get(MASS);
127                         NoseCone nc = new NoseCone();
128                         nc.loadPreset(preset);
129                         double density = mass / nc.getComponentVolume();
130
131                         String materialName = "NoseConeCustom";
132                         if ( preset.has(MATERIAL) ) {
133                                 materialName = preset.get(MATERIAL).getName();
134                         }
135
136                         Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
137                         preset.put(MATERIAL, m);
138
139                 }
140
141         }
142
143         private static void makeTransition( ComponentPreset preset ) throws InvalidComponentPresetException {
144                 checkRequiredFields(preset, LENGTH, OUTER_DIAMETER, FORE_OUTER_DIAMETER);
145
146                 if ( preset.has(MASS) ) {
147                         // compute a density for this component
148                         double mass = preset.get(MASS);
149                         Transition tr = new Transition();
150                         tr.loadPreset(preset);
151                         double density = mass / tr.getComponentVolume();
152
153                         String materialName = "TransitionCustom";
154                         if ( preset.has(MATERIAL) ) {
155                                 materialName = preset.get(MATERIAL).getName();
156                         }
157
158                         Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
159                         preset.put(MATERIAL, m);
160
161                 }
162
163         }
164
165         private static void makeBulkHead( ComponentPreset preset ) throws InvalidComponentPresetException {
166                 checkRequiredFields(preset, LENGTH, OUTER_DIAMETER );
167
168                 if ( preset.has(MASS) ) {
169                         // compute a density for this component
170                         double mass = preset.get(MASS);
171                         Bulkhead tr = new Bulkhead();
172                         tr.loadPreset(preset);
173                         // FIXME - Bulkhead.getComponentVolume does not exist!
174                         // double density = mass / tr.getComponentVolume();
175
176                         double volume = Math.pow(preset.get(OUTER_DIAMETER),2) * Math.PI / 4.0;
177                         double density = mass / volume;
178
179                         String materialName = "TransitionCustom";
180                         if ( preset.has(MATERIAL) ) {
181                                 materialName = preset.get(MATERIAL).getName();
182                         }
183
184                         Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
185                         preset.put(MATERIAL, m);
186
187                 }
188
189         }
190
191         private static void checkRequiredFields( ComponentPreset preset, TypedKey<?> ... keys ) throws InvalidComponentPresetException {
192                 for( TypedKey<?> key: keys ) {
193                         if (! preset.has(key) ) {
194                                 throw new InvalidComponentPresetException( "No " + key.getName() + " specified for " + preset.getType().name() + " preset " + preset.toString());
195                         }
196                 }
197         }
198
199 }