1 package net.sf.openrocket.preset;
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;
21 public abstract class ComponentPresetFactory {
23 public static ComponentPreset create( TypedPropertyMap props ) throws InvalidComponentPresetException {
25 ComponentPreset preset = new ComponentPreset();
26 // First do validation.
27 if ( !props.containsKey(TYPE)) {
28 throw new InvalidComponentPresetException("No Type specified " + props.toString() );
31 if (!props.containsKey(MANUFACTURER)) {
32 throw new InvalidComponentPresetException("No Manufacturer specified " + props.toString() );
35 if (!props.containsKey(PARTNO)) {
36 throw new InvalidComponentPresetException("No PartNo specified " + props.toString() );
41 // Should check for various bits of each of the types.
42 Type t = props.get(TYPE);
53 makeTransition(preset);
62 preset.computeDigest();
68 private static void makeBodyTube( ComponentPreset preset ) throws InvalidComponentPresetException {
70 checkRequiredFields( preset, LENGTH );
72 BodyTube bt = new BodyTube();
74 bt.setLength(preset.get(LENGTH));
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);
82 double outerRadius = preset.get(OUTER_DIAMETER)/2.0;
84 bt.setOuterRadius( outerRadius );
86 thickness = outerRadius - preset.get(INNER_DIAMETER)/2.0;
87 } else if ( hasThickness ) {
88 thickness = preset.get(THICKNESS);
90 throw new InvalidComponentPresetException("Body tube preset underspecified " + preset.toString());
92 bt.setThickness( thickness );
94 if ( ! hasId && ! hasThickness ) {
95 throw new InvalidComponentPresetException("Body tube preset underspecified " + preset.toString());
97 double innerRadius = preset.get(INNER_DIAMETER)/2.0;
98 double thickness = preset.get(THICKNESS);
99 bt.setOuterRadius(innerRadius + thickness);
100 bt.setThickness(thickness);
103 preset.put(OUTER_DIAMETER, bt.getOuterRadius() *2.0);
104 preset.put(INNER_DIAMETER, bt.getInnerRadius() *2.0);
105 preset.put(THICKNESS, bt.getThickness());
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();
113 Material m = Material.newMaterial(Material.Type.BULK, materialName, preset.get(MASS)/bt.getComponentVolume(), false);
114 preset.put(MATERIAL, m);
120 private static void makeNoseCone( ComponentPreset preset ) throws InvalidComponentPresetException {
122 checkRequiredFields( preset, LENGTH, SHAPE, OUTER_DIAMETER );
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();
131 String materialName = "NoseConeCustom";
132 if ( preset.has(MATERIAL) ) {
133 materialName = preset.get(MATERIAL).getName();
136 Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
137 preset.put(MATERIAL, m);
143 private static void makeTransition( ComponentPreset preset ) throws InvalidComponentPresetException {
144 checkRequiredFields(preset, LENGTH, OUTER_DIAMETER, FORE_OUTER_DIAMETER);
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();
153 String materialName = "TransitionCustom";
154 if ( preset.has(MATERIAL) ) {
155 materialName = preset.get(MATERIAL).getName();
158 Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
159 preset.put(MATERIAL, m);
165 private static void makeBulkHead( ComponentPreset preset ) throws InvalidComponentPresetException {
166 checkRequiredFields(preset, LENGTH, OUTER_DIAMETER );
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();
176 double volume = Math.pow(preset.get(OUTER_DIAMETER),2) * Math.PI / 4.0;
177 double density = mass / volume;
179 String materialName = "TransitionCustom";
180 if ( preset.has(MATERIAL) ) {
181 materialName = preset.get(MATERIAL).getName();
184 Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
185 preset.put(MATERIAL, m);
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());