Refactored the ComponentPreset.create method into the ComponentPresetFactory object to make code maintenance easier. Added support for Bulk heads.

This commit is contained in:
Kevin Ruland 2012-04-16 19:18:25 +00:00
parent f69ed1ea2f
commit d1c83cb9b4
4 changed files with 266 additions and 148 deletions

View File

@ -0,0 +1,31 @@
Manufacturer,PartNo,Description,Type,OuterDiameter,Length,Material,Mass
Semroc,BTC-5,Solid Balsa Tube Adapter - Series 5,BULK_HEAD,0.013081,0.01905,Balsa,0.000283495
Semroc,BTC-7,Solid Balsa Tube Adapter - Series 7,BULK_HEAD,0.018161,0.0254,Balsa,0.000737087
Semroc,BTC-8,Solid Balsa Tube Adapter - Series 8,BULK_HEAD,0.021971,0.0254,Balsa,0.001077281
Semroc,BTC-8F,Solid Balsa Tube Adapter - Series 8F,BULK_HEAD,0.022479,0.0254,Balsa,0.001077281
Semroc,BTC-9,Solid Balsa Tube Adapter - Series 9,BULK_HEAD,0.02413,0.0381,Balsa,0.001275727
Semroc,BTC-10,Solid Balsa Tube Adapter - Series 10,BULK_HEAD,0.0254,0.0381,Balsa,0.001814368
Semroc,BTC-11,Solid Balsa Tube Adapter - Series 11,BULK_HEAD,0.028702,0.0381,Balsa,0.001956115
Semroc,BTC-13,Solid Balsa Tube Adapter - Series 13,BULK_HEAD,0.03302,0.04445,Balsa,0.003543687
Semroc,BTC-16,Solid Balsa Tube Adapter - Series 16,BULK_HEAD,0.04064,0.04445,Balsa,0.004961161
Semroc,BTC-18,Solid Balsa Tube Adapter - Series 18,BULK_HEAD,0.04572,0.04445,Balsa,0.005669899
Semroc,BTC-20,Solid Balsa Tube Adapter - Series 20,BULK_HEAD,0.0508,0.05334,Balsa,0.007512616
Semroc,BTC-085,Solid Balsa Tube Adapter - Series 85,BULK_HEAD,0.021971,0.0381,Balsa,0.001615921
Semroc,BTC-115,Solid Balsa Tube Adapter - Series 115,BULK_HEAD,0.02921,0.04445,Balsa,0.003175143
Semroc,BTC-125,Solid Balsa Tube Adapter - Series 125,BULK_HEAD,0.03175,0.0508,Balsa,0.004535919
Semroc,BTC-150,Solid Balsa Tube Adapter - Series 150,BULK_HEAD,0.0381,0.0508,Balsa,0.006662131
Semroc,BTC-175,Solid Balsa Tube Adapter - Series 175,BULK_HEAD,0.04445,0.05715,Balsa,0.00949708
Semroc,BTC-225,Solid Balsa Tube Adapter - Series 225,BULK_HEAD,0.05715,0.0635,Balsa,0.018001928
Semroc,BTC-275,Solid Balsa Tube Adapter - Series 275,BULK_HEAD,0.06985,0.0762,Balsa,0.032176674
Semroc,NB-3,Solid Balsa Tube Adapter - Series BT-3,BULK_HEAD,0.0088646,0.01905,Balsa,0.000198446
Semroc,NB-5,Solid Balsa Tube Adapter - Series BT-5,BULK_HEAD,0.013081,0.01905,Balsa,0.000283495
Semroc,NB-20,Solid Balsa Tube Adapter - Series BT-20,BULK_HEAD,0.018034,0.01905,Balsa,0.00056699
Semroc,NB-30,Solid Balsa Tube Adapter - Series BT-30,BULK_HEAD,0.018415,0.01905,Balsa,0.00056699
Semroc,NB-40,Solid Balsa Tube Adapter - Series BT-40,BULK_HEAD,0.019431,0.0254,Balsa,0.000793786
Semroc,NB-50,Solid Balsa Tube Adapter - Series BT-50,BULK_HEAD,0.02413,0.0254,Balsa,0.00113398
Semroc,NB-50L,Solid Balsa Tube Adapter - Series BT-50,BULK_HEAD,0.02413,0.030226,Balsa,0.002182911
Semroc,NB-55,Solid Balsa Tube Adapter - Series BT-55,BULK_HEAD,0.0325882,0.03175,Balsa,0.003260192
Semroc,NB-60,Solid Balsa Tube Adapter - Series BT-60,BULK_HEAD,0.040513,0.0381,Balsa,0.004819414
Semroc,NB-65,Solid Balsa Tube Adapter - Series BT-65,BULK_HEAD,0.04445,0.04445,Balsa,0.005953393
Semroc,NB-70,Solid Balsa Tube Adapter - Series BT-70,BULK_HEAD,0.055245,0.0508,Balsa,0.006236888
Semroc,NB-80,Solid Balsa Tube Adapter - Series BT-80,BULK_HEAD,0.0649732,0.0762,Balsa,0.010489312
1 Manufacturer PartNo Description Type OuterDiameter Length Material Mass
2 Semroc BTC-5 Solid Balsa Tube Adapter - Series 5 BULK_HEAD 0.013081 0.01905 Balsa 0.000283495
3 Semroc BTC-7 Solid Balsa Tube Adapter - Series 7 BULK_HEAD 0.018161 0.0254 Balsa 0.000737087
4 Semroc BTC-8 Solid Balsa Tube Adapter - Series 8 BULK_HEAD 0.021971 0.0254 Balsa 0.001077281
5 Semroc BTC-8F Solid Balsa Tube Adapter - Series 8F BULK_HEAD 0.022479 0.0254 Balsa 0.001077281
6 Semroc BTC-9 Solid Balsa Tube Adapter - Series 9 BULK_HEAD 0.02413 0.0381 Balsa 0.001275727
7 Semroc BTC-10 Solid Balsa Tube Adapter - Series 10 BULK_HEAD 0.0254 0.0381 Balsa 0.001814368
8 Semroc BTC-11 Solid Balsa Tube Adapter - Series 11 BULK_HEAD 0.028702 0.0381 Balsa 0.001956115
9 Semroc BTC-13 Solid Balsa Tube Adapter - Series 13 BULK_HEAD 0.03302 0.04445 Balsa 0.003543687
10 Semroc BTC-16 Solid Balsa Tube Adapter - Series 16 BULK_HEAD 0.04064 0.04445 Balsa 0.004961161
11 Semroc BTC-18 Solid Balsa Tube Adapter - Series 18 BULK_HEAD 0.04572 0.04445 Balsa 0.005669899
12 Semroc BTC-20 Solid Balsa Tube Adapter - Series 20 BULK_HEAD 0.0508 0.05334 Balsa 0.007512616
13 Semroc BTC-085 Solid Balsa Tube Adapter - Series 85 BULK_HEAD 0.021971 0.0381 Balsa 0.001615921
14 Semroc BTC-115 Solid Balsa Tube Adapter - Series 115 BULK_HEAD 0.02921 0.04445 Balsa 0.003175143
15 Semroc BTC-125 Solid Balsa Tube Adapter - Series 125 BULK_HEAD 0.03175 0.0508 Balsa 0.004535919
16 Semroc BTC-150 Solid Balsa Tube Adapter - Series 150 BULK_HEAD 0.0381 0.0508 Balsa 0.006662131
17 Semroc BTC-175 Solid Balsa Tube Adapter - Series 175 BULK_HEAD 0.04445 0.05715 Balsa 0.00949708
18 Semroc BTC-225 Solid Balsa Tube Adapter - Series 225 BULK_HEAD 0.05715 0.0635 Balsa 0.018001928
19 Semroc BTC-275 Solid Balsa Tube Adapter - Series 275 BULK_HEAD 0.06985 0.0762 Balsa 0.032176674
20 Semroc NB-3 Solid Balsa Tube Adapter - Series BT-3 BULK_HEAD 0.0088646 0.01905 Balsa 0.000198446
21 Semroc NB-5 Solid Balsa Tube Adapter - Series BT-5 BULK_HEAD 0.013081 0.01905 Balsa 0.000283495
22 Semroc NB-20 Solid Balsa Tube Adapter - Series BT-20 BULK_HEAD 0.018034 0.01905 Balsa 0.00056699
23 Semroc NB-30 Solid Balsa Tube Adapter - Series BT-30 BULK_HEAD 0.018415 0.01905 Balsa 0.00056699
24 Semroc NB-40 Solid Balsa Tube Adapter - Series BT-40 BULK_HEAD 0.019431 0.0254 Balsa 0.000793786
25 Semroc NB-50 Solid Balsa Tube Adapter - Series BT-50 BULK_HEAD 0.02413 0.0254 Balsa 0.00113398
26 Semroc NB-50L Solid Balsa Tube Adapter - Series BT-50 BULK_HEAD 0.02413 0.030226 Balsa 0.002182911
27 Semroc NB-55 Solid Balsa Tube Adapter - Series BT-55 BULK_HEAD 0.0325882 0.03175 Balsa 0.003260192
28 Semroc NB-60 Solid Balsa Tube Adapter - Series BT-60 BULK_HEAD 0.040513 0.0381 Balsa 0.004819414
29 Semroc NB-65 Solid Balsa Tube Adapter - Series BT-65 BULK_HEAD 0.04445 0.04445 Balsa 0.005953393
30 Semroc NB-70 Solid Balsa Tube Adapter - Series BT-70 BULK_HEAD 0.055245 0.0508 Balsa 0.006236888
31 Semroc NB-80 Solid Balsa Tube Adapter - Series BT-80 BULK_HEAD 0.0649732 0.0762 Balsa 0.010489312

View File

@ -12,6 +12,7 @@ import net.sf.openrocket.file.Loader;
import net.sf.openrocket.file.preset.PresetCSVReader;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.ComponentPresetFactory;
import net.sf.openrocket.preset.InvalidComponentPresetException;
import net.sf.openrocket.preset.TypedPropertyMap;
import net.sf.openrocket.startup.Application;
@ -37,7 +38,7 @@ public class ComponentPresetDatabase extends Database<ComponentPreset> implement
List<TypedPropertyMap> list = parser.parse();
for( TypedPropertyMap o : list ) {
try {
ComponentPreset preset = ComponentPreset.create(o);
ComponentPreset preset = ComponentPresetFactory.create(o);
if ( favorites.contains(preset.preferenceKey())) {
preset.setFavorite(true);
}

View File

@ -61,8 +61,14 @@ public class ComponentPreset implements Comparable<ComponentPreset> {
ComponentPreset.SHAPE,
ComponentPreset.FORE_OUTER_DIAMETER,
ComponentPreset.OUTER_DIAMETER,
ComponentPreset.LENGTH
} ) ;
ComponentPreset.LENGTH} ),
BULK_HEAD( new TypedKey<?>[] {
ComponentPreset.MANUFACTURER,
ComponentPreset.PARTNO,
ComponentPreset.DESCRIPTION,
ComponentPreset.OUTER_DIAMETER,
ComponentPreset.LENGTH} );
Type[] compatibleTypes;
TypedKey<?>[] displayedColumns;
@ -135,150 +141,8 @@ public class ComponentPreset implements Comparable<ComponentPreset> {
keyMap.put(MASS.getName(), MASS);
}
public static ComponentPreset create( TypedPropertyMap props ) throws InvalidComponentPresetException {
ComponentPreset preset = new ComponentPreset();
// First do validation.
if ( !props.containsKey(TYPE)) {
throw new InvalidComponentPresetException("No Type specified " + props.toString() );
}
if (!props.containsKey(MANUFACTURER)) {
throw new InvalidComponentPresetException("No Manufacturer specified " + props.toString() );
}
if (!props.containsKey(PARTNO)) {
throw new InvalidComponentPresetException("No PartNo specified " + props.toString() );
}
preset.properties.putAll(props);
// Should check for various bits of each of the types.
Type t = props.get(TYPE);
switch ( t ) {
case BODY_TUBE: {
if ( !props.containsKey(LENGTH) ) {
throw new InvalidComponentPresetException( "No Length specified for body tube preset " + props.toString());
}
BodyTube bt = new BodyTube();
bt.setLength(props.get(LENGTH));
// Need to verify contains 2 of OD, thickness, ID. Compute the third.
boolean hasOd = props.containsKey(OUTER_DIAMETER);
boolean hasId = props.containsKey(INNER_DIAMETER);
boolean hasThickness = props.containsKey(THICKNESS);
if ( hasOd ) {
double outerRadius = props.get(OUTER_DIAMETER)/2.0;
double thickness = 0;
bt.setOuterRadius( outerRadius );
if ( hasId ) {
thickness = outerRadius - props.get(INNER_DIAMETER)/2.0;
} else if ( hasThickness ) {
thickness = props.get(THICKNESS);
} else {
throw new InvalidComponentPresetException("Body tube preset underspecified " + props.toString());
}
bt.setThickness( thickness );
} else {
if ( ! hasId && ! hasThickness ) {
throw new InvalidComponentPresetException("Body tube preset underspecified " + props.toString());
}
double innerRadius = props.get(INNER_DIAMETER)/2.0;
double thickness = props.get(THICKNESS);
bt.setOuterRadius(innerRadius + thickness);
bt.setThickness(thickness);
}
preset.properties.put(OUTER_DIAMETER, bt.getOuterRadius() *2.0);
preset.properties.put(INNER_DIAMETER, bt.getInnerRadius() *2.0);
preset.properties.put(THICKNESS, bt.getThickness());
// Need to translate Mass to Density.
if ( props.containsKey(MASS) ) {
String materialName = "TubeCustom";
if ( props.containsKey(MATERIAL) ) {
materialName = props.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName, props.get(MASS)/bt.getComponentVolume(), false);
preset.properties.put(MATERIAL, m);
}
break;
}
case NOSE_CONE: {
if ( !props.containsKey(LENGTH) ) {
throw new InvalidComponentPresetException( "No Length specified for nose cone preset " + props.toString());
}
if ( !props.containsKey(SHAPE) ) {
throw new InvalidComponentPresetException( "No Shape specified for nose cone preset " + props.toString());
}
if ( !props.containsKey(OUTER_DIAMETER) ) {
throw new InvalidComponentPresetException( "No Outer Diameter specified for nose cone preset " + props.toString());
}
if ( props.containsKey(MASS) ) {
// compute a density for this component
double mass = props.get(MASS);
NoseCone nc = new NoseCone();
nc.loadPreset(preset);
double density = mass / nc.getComponentVolume();
String materialName = "NoseConeCustom";
if ( props.containsKey(MATERIAL) ) {
materialName = props.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
preset.properties.put(MATERIAL, m);
}
break;
}
case TRANSITION: {
if ( !props.containsKey(LENGTH) ) {
throw new InvalidComponentPresetException( "No Length specified for transition preset " + props.toString());
}
if ( !props.containsKey(OUTER_DIAMETER) ) {
throw new InvalidComponentPresetException( "No Outer Diameter specified for transition preset " + props.toString());
}
if ( !props.containsKey(FORE_OUTER_DIAMETER) ) {
throw new InvalidComponentPresetException( "No Fore Outer Diameter specified for transition preset " + props.toString());
}
if ( props.containsKey(MASS) ) {
// compute a density for this component
double mass = props.get(MASS);
Transition tr = new Transition();
tr.loadPreset(preset);
double density = mass / tr.getComponentVolume();
String materialName = "TransitionCustom";
if ( props.containsKey(MATERIAL) ) {
materialName = props.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
preset.properties.put(MATERIAL, m);
}
break;
}
}
preset.computeDigest();
return preset;
}
// Private constructor to encourage use of factory.
private ComponentPreset() {
// package scope constructor to encourage use of factory.
ComponentPreset() {
}
/**
@ -314,6 +178,26 @@ public class ComponentPreset implements Comparable<ComponentPreset> {
return properties.containsKey(key);
}
/**
* Package scope so the ComponentPresetFactory can call it.
* @param other
*/
void putAll(TypedPropertyMap other) {
if (other == null) {
return;
}
properties.putAll(other);
}
/**
* Package scope so the ComponentPresetFactory can call it.
* @param key
* @param value
*/
<T> void put( TypedKey<T> key, T value ) {
properties.put(key, value);
}
public <T> T get(TypedKey<T> key) {
T value = properties.get(key);
if (value == null) {
@ -349,7 +233,10 @@ public class ComponentPreset implements Comparable<ComponentPreset> {
return get(MANUFACTURER).toString() + "|" + get(PARTNO);
}
private void computeDigest() {
/**
* Package scope so the factory can call it.
*/
void computeDigest() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();

View File

@ -0,0 +1,199 @@
package net.sf.openrocket.preset;
import static net.sf.openrocket.preset.ComponentPreset.FORE_OUTER_DIAMETER;
import static net.sf.openrocket.preset.ComponentPreset.INNER_DIAMETER;
import static net.sf.openrocket.preset.ComponentPreset.LENGTH;
import static net.sf.openrocket.preset.ComponentPreset.MANUFACTURER;
import static net.sf.openrocket.preset.ComponentPreset.MASS;
import static net.sf.openrocket.preset.ComponentPreset.MATERIAL;
import static net.sf.openrocket.preset.ComponentPreset.OUTER_DIAMETER;
import static net.sf.openrocket.preset.ComponentPreset.PARTNO;
import static net.sf.openrocket.preset.ComponentPreset.SHAPE;
import static net.sf.openrocket.preset.ComponentPreset.THICKNESS;
import static net.sf.openrocket.preset.ComponentPreset.TYPE;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset.Type;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.Bulkhead;
import net.sf.openrocket.rocketcomponent.NoseCone;
import net.sf.openrocket.rocketcomponent.Transition;
public abstract class ComponentPresetFactory {
public static ComponentPreset create( TypedPropertyMap props ) throws InvalidComponentPresetException {
ComponentPreset preset = new ComponentPreset();
// First do validation.
if ( !props.containsKey(TYPE)) {
throw new InvalidComponentPresetException("No Type specified " + props.toString() );
}
if (!props.containsKey(MANUFACTURER)) {
throw new InvalidComponentPresetException("No Manufacturer specified " + props.toString() );
}
if (!props.containsKey(PARTNO)) {
throw new InvalidComponentPresetException("No PartNo specified " + props.toString() );
}
preset.putAll(props);
// Should check for various bits of each of the types.
Type t = props.get(TYPE);
switch ( t ) {
case BODY_TUBE: {
makeBodyTube(preset);
break;
}
case NOSE_CONE: {
makeNoseCone(preset);
break;
}
case TRANSITION: {
makeTransition(preset);
break;
}
case BULK_HEAD: {
makeBulkHead(preset);
break;
}
}
preset.computeDigest();
return preset;
}
private static void makeBodyTube( ComponentPreset preset ) throws InvalidComponentPresetException {
checkRequiredFields( preset, LENGTH );
BodyTube bt = new BodyTube();
bt.setLength(preset.get(LENGTH));
// Need to verify contains 2 of OD, thickness, ID. Compute the third.
boolean hasOd = preset.has(OUTER_DIAMETER);
boolean hasId = preset.has(INNER_DIAMETER);
boolean hasThickness = preset.has(THICKNESS);
if ( hasOd ) {
double outerRadius = preset.get(OUTER_DIAMETER)/2.0;
double thickness = 0;
bt.setOuterRadius( outerRadius );
if ( hasId ) {
thickness = outerRadius - preset.get(INNER_DIAMETER)/2.0;
} else if ( hasThickness ) {
thickness = preset.get(THICKNESS);
} else {
throw new InvalidComponentPresetException("Body tube preset underspecified " + preset.toString());
}
bt.setThickness( thickness );
} else {
if ( ! hasId && ! hasThickness ) {
throw new InvalidComponentPresetException("Body tube preset underspecified " + preset.toString());
}
double innerRadius = preset.get(INNER_DIAMETER)/2.0;
double thickness = preset.get(THICKNESS);
bt.setOuterRadius(innerRadius + thickness);
bt.setThickness(thickness);
}
preset.put(OUTER_DIAMETER, bt.getOuterRadius() *2.0);
preset.put(INNER_DIAMETER, bt.getInnerRadius() *2.0);
preset.put(THICKNESS, bt.getThickness());
// Need to translate Mass to Density.
if ( preset.has(MASS) ) {
String materialName = "TubeCustom";
if ( preset.has(MATERIAL) ) {
materialName = preset.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName, preset.get(MASS)/bt.getComponentVolume(), false);
preset.put(MATERIAL, m);
}
}
private static void makeNoseCone( ComponentPreset preset ) throws InvalidComponentPresetException {
checkRequiredFields( preset, LENGTH, SHAPE, OUTER_DIAMETER );
if ( preset.has(MASS) ) {
// compute a density for this component
double mass = preset.get(MASS);
NoseCone nc = new NoseCone();
nc.loadPreset(preset);
double density = mass / nc.getComponentVolume();
String materialName = "NoseConeCustom";
if ( preset.has(MATERIAL) ) {
materialName = preset.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
preset.put(MATERIAL, m);
}
}
private static void makeTransition( ComponentPreset preset ) throws InvalidComponentPresetException {
checkRequiredFields(preset, LENGTH, OUTER_DIAMETER, FORE_OUTER_DIAMETER);
if ( preset.has(MASS) ) {
// compute a density for this component
double mass = preset.get(MASS);
Transition tr = new Transition();
tr.loadPreset(preset);
double density = mass / tr.getComponentVolume();
String materialName = "TransitionCustom";
if ( preset.has(MATERIAL) ) {
materialName = preset.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
preset.put(MATERIAL, m);
}
}
private static void makeBulkHead( ComponentPreset preset ) throws InvalidComponentPresetException {
checkRequiredFields(preset, LENGTH, OUTER_DIAMETER );
if ( preset.has(MASS) ) {
// compute a density for this component
double mass = preset.get(MASS);
Bulkhead tr = new Bulkhead();
tr.loadPreset(preset);
// FIXME - Bulkhead.getComponentVolume does not exist!
// double density = mass / tr.getComponentVolume();
double volume = Math.pow(preset.get(OUTER_DIAMETER),2) * Math.PI / 4.0;
double density = mass / volume;
String materialName = "TransitionCustom";
if ( preset.has(MATERIAL) ) {
materialName = preset.get(MATERIAL).getName();
}
Material m = Material.newMaterial(Material.Type.BULK, materialName,density, false);
preset.put(MATERIAL, m);
}
}
private static void checkRequiredFields( ComponentPreset preset, TypedKey<?> ... keys ) throws InvalidComponentPresetException {
for( TypedKey<?> key: keys ) {
if (! preset.has(key) ) {
throw new InvalidComponentPresetException( "No " + key.getName() + " specified for " + preset.getType().name() + " preset " + preset.toString());
}
}
}
}