From c96809f2b87c51e378e6274653b9d85c9bc49255 Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Mon, 2 Apr 2012 20:06:47 +0000 Subject: [PATCH] Revamp construction of ComponentPresets. Validation and data munging done in the ComponentPreset.create() factory method. git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@504 180e2498-e6e9-4542-8430-84ac67f01cd8 --- .../database/ComponentPresetDao.java | 18 ++- .../file/preset/ColumnDefinition.java | 47 +----- .../file/preset/PresetCSVReader.java | 54 +++---- .../sf/openrocket/preset/ComponentPreset.java | 148 ++++++++++++------ .../InvalidComponentPresetException.java | 25 +++ 5 files changed, 173 insertions(+), 119 deletions(-) create mode 100644 core/src/net/sf/openrocket/preset/InvalidComponentPresetException.java diff --git a/core/src/net/sf/openrocket/database/ComponentPresetDao.java b/core/src/net/sf/openrocket/database/ComponentPresetDao.java index d76e71df..17a85c4e 100644 --- a/core/src/net/sf/openrocket/database/ComponentPresetDao.java +++ b/core/src/net/sf/openrocket/database/ComponentPresetDao.java @@ -7,6 +7,9 @@ import java.util.List; import net.sf.openrocket.file.preset.PresetCSVReader; import net.sf.openrocket.preset.ComponentPreset; +import net.sf.openrocket.preset.InvalidComponentPresetException; +import net.sf.openrocket.preset.TypedPropertyMap; +import net.sf.openrocket.util.BugException; public class ComponentPresetDao { @@ -20,9 +23,14 @@ public class ComponentPresetDao { InputStream is = ComponentPresetDao.class.getResourceAsStream("/datafiles/bodytubepresets.csv"); PresetCSVReader parser = new PresetCSVReader(is); - List list = parser.parse(); - for( ComponentPreset preset : list ) { - templates.add(preset); + List list = parser.parse(); + for( TypedPropertyMap o : list ) { + try { + ComponentPreset preset = ComponentPreset.create(o); + this.insert(preset); + } catch ( InvalidComponentPresetException ex ) { + throw new BugException( ex ); + } } } @@ -30,4 +38,8 @@ public class ComponentPresetDao { return templates; } + public void insert( ComponentPreset preset ) { + templates.add(preset); + } + } diff --git a/core/src/net/sf/openrocket/file/preset/ColumnDefinition.java b/core/src/net/sf/openrocket/file/preset/ColumnDefinition.java index 3e62286b..53492559 100644 --- a/core/src/net/sf/openrocket/file/preset/ColumnDefinition.java +++ b/core/src/net/sf/openrocket/file/preset/ColumnDefinition.java @@ -1,46 +1,15 @@ package net.sf.openrocket.file.preset; -import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.TypedKey; +import net.sf.openrocket.preset.TypedPropertyMap; -public interface ColumnDefinition { - - public void setProperty( ComponentPreset preset, String value ); - - public static class Manufactuer implements ColumnDefinition { - @Override - public void setProperty( ComponentPreset preset, String value ) { - preset.setManufacturer(value); - } - } - public static class PartNumber implements ColumnDefinition { - @Override - public void setProperty( ComponentPreset preset, String value ) { - preset.setPartNo(value); - } - } - public static class Type implements ColumnDefinition { - @Override - public void setProperty( ComponentPreset preset, String value ) { - ComponentPreset.Type t = ComponentPreset.Type.valueOf(value); - if ( t == null ) { - throw new RuntimeException("Invalid ComponentPreset Type: " + value); - } - preset.setType(t); - } +public class ColumnDefinition { + TypedKey key; + public ColumnDefinition( TypedKey key ) { + this.key = key; } - public static class Parameter implements ColumnDefinition { - TypedKey key; - public Parameter( TypedKey key ) { - this.key = key; - } - @Override - public void setProperty( ComponentPreset preset, String value ) { - Object o = key.parseFromString(value); - preset.put(key, o); - } + public void setProperty( TypedPropertyMap preset, String value ) { + T o = (T) key.parseFromString(value); + preset.put(key, o); } - - - } diff --git a/core/src/net/sf/openrocket/file/preset/PresetCSVReader.java b/core/src/net/sf/openrocket/file/preset/PresetCSVReader.java index 9210f6ab..f15ace93 100644 --- a/core/src/net/sf/openrocket/file/preset/PresetCSVReader.java +++ b/core/src/net/sf/openrocket/file/preset/PresetCSVReader.java @@ -8,63 +8,63 @@ import java.util.List; import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.TypedKey; +import net.sf.openrocket.preset.TypedPropertyMap; import au.com.bytecode.opencsv.CSVReader; public class PresetCSVReader { - + private InputStream is; - private ColumnDefinition[] columns; - + private ColumnDefinition[] columns; + public PresetCSVReader(InputStream is) { this.is = is; } - - public List parse() throws IOException { - - List templates = new ArrayList(); - + + public List parse() throws IOException { + + List templates = new ArrayList(); + InputStreamReader r = new InputStreamReader(is); - + // Create the CSV reader. Use comma separator and double-quote escaping. CSVReader reader = new CSVReader(r, ',', '"'); - + String[] headers = reader.readNext(); if (headers == null || headers.length == 0) { return templates; } - + columns = new ColumnDefinition[headers.length]; for (int i = 0; i < headers.length; i++) { String h = headers[i]; - if ("Manufacturer".equals(h)) { - columns[i] = new ColumnDefinition.Manufactuer(); - } else if ("PartNo".equals(h)) { - columns[i] = new ColumnDefinition.PartNumber(); - } else if ("Type".equals(h)) { - columns[i] = new ColumnDefinition.Type(); - } else { - TypedKey key = ComponentPreset.keyMap.get(h); - if (key == null) { - throw new RuntimeException("Invalid parameter key " + h + " in file"); - } - columns[i] = new ColumnDefinition.Parameter(key); + TypedKey key = ComponentPreset.keyMap.get(h); + if (key == null) { + throw new RuntimeException("Invalid parameter key " + h + " in file"); } + columns[i] = new ColumnDefinition(key); } - + String[] line; while ((line = reader.readNext()) != null) { - ComponentPreset preset = new ComponentPreset(); + TypedPropertyMap preset = new TypedPropertyMap(); for (int i = 0; i < headers.length; i++) { if (i > line.length) { break; } String value = line[i]; + if ( value == null ) { + continue; + } + value = value.trim(); + if ( value.length() == 0 ) { + continue; + } columns[i].setProperty(preset, value); } templates.add(preset); } - + return templates; } - + } diff --git a/core/src/net/sf/openrocket/preset/ComponentPreset.java b/core/src/net/sf/openrocket/preset/ComponentPreset.java index b8daf911..e3406577 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPreset.java +++ b/core/src/net/sf/openrocket/preset/ComponentPreset.java @@ -4,6 +4,8 @@ import java.util.HashMap; import java.util.Map; import net.sf.openrocket.material.Material; +import net.sf.openrocket.motor.Manufacturer; +import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.util.BugException; @@ -18,17 +20,19 @@ import net.sf.openrocket.util.BugException; */ public class ComponentPreset { - private final Map, Object> properties = new HashMap, Object>(); + private final TypedPropertyMap properties = new TypedPropertyMap(); // TODO - Implement clone. - // Implement "freezing" so the object cannot be modified. public enum Type { BODY_TUBE, NOSE_CONE } + public final static TypedKey MANUFACTURER = new TypedKey("Manufacturer", Manufacturer.class); + public final static TypedKey PARTNO = new TypedKey("PartNo",String.class); + public final static TypedKey TYPE = new TypedKey("Type",Type.class); public final static TypedKey LENGTH = new TypedKey("Length", Double.class); public final static TypedKey INNER_DIAMETER = new TypedKey("InnerDiameter", Double.class); public final static TypedKey OUTER_DIAMETER = new TypedKey("OuterDiameter", Double.class); @@ -40,6 +44,9 @@ public class ComponentPreset { public final static Map> keyMap = new HashMap>(); static { + keyMap.put(MANUFACTURER.getName(), MANUFACTURER); + keyMap.put(PARTNO.getName(), PARTNO); + keyMap.put(TYPE.getName(), TYPE); keyMap.put(LENGTH.getName(), LENGTH); keyMap.put(INNER_DIAMETER.getName(), INNER_DIAMETER); keyMap.put(OUTER_DIAMETER.getName(), OUTER_DIAMETER); @@ -50,69 +57,110 @@ public class ComponentPreset { keyMap.put(MASS.getName(), MASS); } - private String manufacturer; - private String partNo; - private String partDescription; - private Type type; - - - public String getManufacturer() { - return manufacturer; - } - - public void setManufacturer(String manufacturer) { - this.manufacturer = manufacturer; - } - - public String getPartNo() { - return partNo; - } - - public void setPartNo(String partNo) { - this.partNo = partNo; - } - - public String getPartDescription() { - return partDescription; - } - - public void setPartDescription(String partDescription) { - this.partDescription = partDescription; - } - - public Type getType() { - return type; + 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: { + break; + } + } + + return preset; + } - - public void setType(Type type) { - this.type = type; + + // Private constructor to encourage use of factory. + private ComponentPreset() { + } - - public boolean has(Object key) { return properties.containsKey(key); } - @SuppressWarnings("unchecked") public T get(TypedKey key) { - Object value = properties.get(key); + T value = properties.get(key); if (value == null) { - throw new BugException("Preset of type " + type + " did not contain key " + key + " mfg=" + manufacturer + " partNo=" + partNo); + throw new BugException("Preset did not contain key " + key + " " + properties.toString()); } return (T) value; } - @SuppressWarnings("unchecked") - public T put(TypedKey key, T value) { - return (T) properties.put(key, value); - } - - - @Override public String toString() { - return partNo; + return get(MANUFACTURER).toString() + " " + get(PARTNO); } + } diff --git a/core/src/net/sf/openrocket/preset/InvalidComponentPresetException.java b/core/src/net/sf/openrocket/preset/InvalidComponentPresetException.java new file mode 100644 index 00000000..53066d13 --- /dev/null +++ b/core/src/net/sf/openrocket/preset/InvalidComponentPresetException.java @@ -0,0 +1,25 @@ +package net.sf.openrocket.preset; + +public class InvalidComponentPresetException extends Exception { + + public InvalidComponentPresetException() { + super(); + // TODO Auto-generated constructor stub + } + + public InvalidComponentPresetException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + public InvalidComponentPresetException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public InvalidComponentPresetException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + +} -- 2.47.2