--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Locale;
+
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+
+public abstract class BaseColumnParser implements RocksimComponentFileColumnParser {
+
+ protected String columnHeader;
+ protected boolean isConfigured = false;
+ protected int columnIndex;
+
+ public BaseColumnParser(String columnHeader) {
+ super();
+ this.columnHeader = columnHeader.toLowerCase(Locale.US);
+ }
+
+ @Override
+ public void configure(String[] headers) {
+ if ( headers == null ) {
+ return;
+ }
+ for( int i =0; i< headers.length; i++ ) {
+ if ( columnHeader.equals(headers[i].toLowerCase(Locale.US))) {
+ columnIndex = i;
+ isConfigured = true;
+ return;
+ }
+ }
+ }
+
+ @Override
+ final public void parse(String[] data, TypedPropertyMap props) {
+ if ( isConfigured ) {
+ doParse(data[columnIndex], data, props);
+ }
+ }
+
+ protected abstract void doParse(String columnData, String[] data, TypedPropertyMap props );
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPresetFactory;
+import net.sf.openrocket.preset.InvalidComponentPresetException;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public abstract class BaseComponentLoader extends RocksimComponentFileLoader {
+
+ List<ComponentPreset> presets;
+
+ public BaseComponentLoader(Map<String, Material> materials) {
+ super();
+ presets = new ArrayList<ComponentPreset>();
+
+ fileColumns.add( new ManufacturerColumnParser() );
+ fileColumns.add( new StringColumnParser("Part No.", ComponentPreset.PARTNO));
+ fileColumns.add( new StringColumnParser("Desc.", ComponentPreset.DESCRIPTION));
+ fileColumns.add(new MaterialColumnParser(materials));
+ fileColumns.add(new DoubleUnitColumnParser("Mass","Mass units",ComponentPreset.MASS));
+
+ }
+
+ protected abstract ComponentPreset.Type getComponentPresetType();
+
+ public List<ComponentPreset> getPresets() {
+ return presets;
+ }
+
+ @Override
+ protected void postProcess(TypedPropertyMap props) {
+ try {
+ props.put(ComponentPreset.TYPE, getComponentPresetType());
+ ComponentPreset preset = ComponentPresetFactory.create(props);
+ presets.add(preset);
+ } catch ( InvalidComponentPresetException ex ) {
+ System.err.println(ex.getMessage());
+ System.err.println(props);
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import net.sf.openrocket.unit.Unit;
+import net.sf.openrocket.unit.UnitGroup;
+
+
+public abstract class BaseUnitColumnParser extends BaseColumnParser {
+
+ protected String unitHeader;
+ protected int unitIndex;
+ protected boolean unitConfigured;
+
+ protected static Map<String,Unit> rocksimUnits;
+
+ static {
+ rocksimUnits = new HashMap<String,Unit>();
+ rocksimUnits.put("0", UnitGroup.UNITS_LENGTH.getUnit("in"));
+ rocksimUnits.put("1", UnitGroup.UNITS_LENGTH.getUnit("mm"));
+ }
+
+ protected String mungeUnitNameString( String name ) {
+ String newString = name.toLowerCase(Locale.US);
+ return newString.replace(".", "");
+ }
+
+ public BaseUnitColumnParser(String columnHeader, String unitHeader) {
+ super(columnHeader);
+ this.unitHeader = unitHeader.toLowerCase(Locale.US);
+ }
+
+ @Override
+ public void configure(String[] headers) {
+ // super configure will set columnIndex;
+ super.configure(headers);
+
+ // This indicates the actual dimension column was found.
+ if ( isConfigured ) {
+ // Look for the unit column proceeding it
+ for( int i=columnIndex-1; i>=0; i-- ) {
+ if ( unitHeader.equals(headers[i].toLowerCase(Locale.US))) {
+ unitConfigured = true;
+ unitIndex = i;
+ return;
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+
+public class BodyTubeLoader extends BaseComponentLoader {
+
+ public BodyTubeLoader(Map<String, Material> materials) {
+ super(materials);
+ fileColumns.add(new DoubleUnitColumnParser("ID","Units",ComponentPreset.INNER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("OD","Units",ComponentPreset.OUTER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Length","Units",ComponentPreset.LENGTH));
+
+ }
+
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.BODY_TUBE;
+ }
+
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.BODY_TUBE;
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public class BulkHeadLoader extends BaseComponentLoader {
+
+ public BulkHeadLoader(Map<String, Material> materials) {
+ super(materials);
+ fileColumns.add(new DoubleUnitColumnParser("OD","Units",ComponentPreset.OUTER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Length","Units",ComponentPreset.LENGTH));
+
+ }
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.BULK_HEAD;
+ }
+
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.BULKHEAD;
+ }
+
+ @Override
+ protected void postProcess(TypedPropertyMap props) {
+ props.put(ComponentPreset.FILLED, true);
+ super.postProcess(props);
+ }
+
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+
+public class CenteringRingLoader extends BodyTubeLoader {
+
+ public CenteringRingLoader(Map<String, Material> materials) {
+ super(materials);
+ }
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.CENTERING_RING;
+ }
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.CENTERING_RING;
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import net.sf.openrocket.preset.TypedKey;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public class DoubleColumnParser extends BaseColumnParser {
+
+ private TypedKey<Double> propKey;
+
+ public DoubleColumnParser(String columnHeader, TypedKey<Double> propKey) {
+ super(columnHeader);
+ this.propKey = propKey;
+ }
+
+ @Override
+ protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
+ double value = Double.valueOf(columnData);
+ props.put(propKey, value);
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import net.sf.openrocket.preset.TypedKey;
+import net.sf.openrocket.preset.TypedPropertyMap;
+import net.sf.openrocket.unit.Unit;
+import net.sf.openrocket.unit.UnitGroup;
+
+public class DoubleUnitColumnParser extends BaseUnitColumnParser {
+
+ private TypedKey<Double> propKey;
+
+ public DoubleUnitColumnParser(String columnHeader, String unitHeader,
+ TypedKey<Double> propKey) {
+ super(columnHeader, unitHeader);
+ this.propKey = propKey;
+ }
+
+ @Override
+ protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
+ try {
+ if (columnData == null || "".equals(columnData) ) {
+ return;
+ }
+ double value = Double.valueOf(columnData);
+
+ if ( unitConfigured ) {
+ String unitName = data[unitIndex];
+
+ Unit unit = rocksimUnits.get(unitName);
+ if ( unit == null ) {
+ if ( unitName == null || "" .equals(unitName) ) {
+ // Hmm no data... Lets assume SI
+ if ( propKey.getUnitGroup() == UnitGroup.UNITS_LENGTH ) {
+ unit = UnitGroup.UNITS_LENGTH.getUnit("in");
+ } else {
+ unit= UnitGroup.UNITS_MASS.getUnit("oz");
+ }
+ } else {
+ unitName = super.mungeUnitNameString(unitName);
+ UnitGroup group = propKey.getUnitGroup();
+ unit = group.getUnit(unitName);
+ }
+ }
+
+ value = unit.fromUnit(value);
+ }
+
+ props.put(propKey, value);
+ }
+ catch ( NumberFormatException nex) {
+ }
+ }
+
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+
+public class EngineBlockLoader extends BodyTubeLoader {
+
+ public EngineBlockLoader(Map<String, Material> materials) {
+ super(materials);
+ }
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.ENGINE_BLOCK;
+ }
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.ENGINE_BLOCK;
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import net.sf.openrocket.motor.Manufacturer;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public class ManufacturerColumnParser extends BaseColumnParser {
+
+ public ManufacturerColumnParser() {
+ super("Mfg.");
+ }
+
+ @Override
+ protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
+ Manufacturer m = Manufacturer.getManufacturer(columnData);
+ props.put(ComponentPreset.MANUFACTURER, m);
+
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Collections;
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public class MaterialColumnParser extends BaseColumnParser {
+
+ private Map<String,Material> materialMap = Collections.<String,Material>emptyMap();
+
+ // FIXME - BULK vs other types.
+
+ public MaterialColumnParser(Map<String,Material> materialMap) {
+ super("Material");
+ }
+
+ @Override
+ protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
+
+ Material m = materialMap.get(columnData);
+ if ( m == null ) {
+ m = new Material.Bulk(columnData, 0.0, true);
+ }
+ props.put(ComponentPreset.MATERIAL, m);
+
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.TypedKey;
+import net.sf.openrocket.preset.TypedPropertyMap;
+import net.sf.openrocket.util.BugException;
+
+public class MaterialLoader extends RocksimComponentFileLoader {
+
+ private Map<String,Material> materialMap = new HashMap<String,Material>();
+
+ private final static TypedKey<String> MATERIALNAME = new TypedKey<String>("MaterialName", String.class);
+ private final static TypedKey<String> UNITS = new TypedKey<String>("Units", String.class);
+ private final static TypedKey<Double> DENSITY = new TypedKey<Double>("Density", Double.class);
+
+ public MaterialLoader() {
+ super();
+ fileColumns.add( new StringColumnParser("Material Name", MATERIALNAME) );
+ fileColumns.add( new StringColumnParser("Units", UNITS));
+ fileColumns.add( new DoubleColumnParser("Density", DENSITY));
+ }
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.MATERIAL;
+ }
+
+ public Map<String, Material> getMaterialMap() {
+ return materialMap;
+ }
+
+ @Override
+ protected void postProcess(TypedPropertyMap props) {
+ String name = props.get(MATERIALNAME);
+ String unit = props.get(UNITS);
+ double density = props.get(DENSITY);
+
+ String cleanedMaterialName = stripAll(name, '"').trim();
+
+ if ( "g/cm".equals( unit ) ) {
+ materialMap.put( cleanedMaterialName, new Material.Line(cleanedMaterialName, 0.1d * density, true));
+ } else if ( "g/cm2".equals(unit) ) {
+ materialMap.put( cleanedMaterialName, new Material.Surface(cleanedMaterialName, 10.0d * density, true));
+ } else if ( "g/cm3".equals(unit) ) {
+ materialMap.put( cleanedMaterialName, new Material.Bulk(cleanedMaterialName, 1000.0d * density, true));
+ } else if ( "kg/m3".equals(unit) ) {
+ materialMap.put( cleanedMaterialName, new Material.Bulk(cleanedMaterialName, density, true));
+ } else if ( "lb/ft3".equals(unit) ) {
+ materialMap.put( cleanedMaterialName, new Material.Bulk(cleanedMaterialName, 16.0184634d * density, true));
+ } else if ( "oz/in".equals(unit) ) {
+ materialMap.put( cleanedMaterialName, new Material.Line(cleanedMaterialName, 1.11612296d * density, true));
+ } else if ( "oz/in2".equals(unit ) ) {
+ materialMap.put( cleanedMaterialName, new Material.Surface(cleanedMaterialName, 43.94184876d * density, true));
+ } else {
+ throw new BugException("Unknown unit in Materials file: " + unit);
+ }
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public class NoseConeLoader extends BaseComponentLoader {
+
+ public NoseConeLoader(Map<String, Material> materials) {
+ super(materials);
+ fileColumns.add(new DoubleUnitColumnParser("Outer Dia","Units",ComponentPreset.AFT_OUTER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Length","Units",ComponentPreset.LENGTH));
+ fileColumns.add(new DoubleUnitColumnParser("Insert Length","Units",ComponentPreset.AFT_SHOULDER_LENGTH));
+ fileColumns.add(new DoubleUnitColumnParser("Insert OD","Units",ComponentPreset.AFT_SHOULDER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Thickness","Units",ComponentPreset.THICKNESS));
+ fileColumns.add(new ShapeColumnParser() );
+ }
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.NOSE_CONE;
+ }
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.NOSE_CONE;
+ }
+
+ @Override
+ protected void postProcess(TypedPropertyMap props) {
+
+ if ( props.containsKey( ComponentPreset.THICKNESS )) {
+ double thickness = props.get(ComponentPreset.THICKNESS);
+ if ( thickness == 0d ) {
+ props.remove( ComponentPreset.THICKNESS );
+ props.put(ComponentPreset.FILLED, true);
+ }
+ }
+ super.postProcess(props);
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public interface RocksimComponentFileColumnParser {
+
+ /**
+ * Examine the array of column headers and configure parsing for this type.
+ *
+ * @param headers
+ */
+ public void configure( String[] headers );
+
+ /**
+ * Examine the data array, parse the appropriate data and push into props.
+ *
+ * @param data
+ * @param props
+ */
+ public void parse( String[] data, TypedPropertyMap props );
+
+}
package net.sf.openrocket.preset.loader;
-import au.com.bytecode.opencsv.CSVReader;
-import net.sf.openrocket.database.Databases;
-import net.sf.openrocket.file.preset.ColumnDefinition;
-import net.sf.openrocket.file.rocksim.RocksimNoseConeCode;
-import net.sf.openrocket.gui.print.PrintUnit;
-import net.sf.openrocket.gui.util.SwingPreferences;
-import net.sf.openrocket.material.Material;
-import net.sf.openrocket.preset.ComponentPreset;
-import net.sf.openrocket.preset.ComponentPresetFactory;
-import net.sf.openrocket.preset.InvalidComponentPresetException;
-import net.sf.openrocket.preset.TypedKey;
-import net.sf.openrocket.preset.TypedPropertyMap;
-import net.sf.openrocket.preset.xml.OpenRocketComponentSaver;
-import net.sf.openrocket.startup.Application;
-import net.sf.openrocket.unit.UnitGroup;
-import net.sf.openrocket.util.ArrayList;
-import net.sf.openrocket.util.BugException;
-
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.StringReader;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
+
+import net.sf.openrocket.gui.print.PrintUnit;
+import net.sf.openrocket.preset.TypedPropertyMap;
+import net.sf.openrocket.unit.Unit;
+import net.sf.openrocket.unit.UnitGroup;
+import net.sf.openrocket.util.ArrayList;
+import au.com.bytecode.opencsv.CSVReader;
/**
* Primary entry point for parsing component CSV files that are in Rocksim format.
*/
-public class RocksimComponentFileLoader {
-
- /**
- * Common unit of measure key. Rocksim format allows different types of units.
- */
- public final static TypedKey<String> UNITS_OF_MEASURE = new TypedKey<String>("Units", String.class);
-
- /**
+public abstract class RocksimComponentFileLoader {
+
+ public static String basePath = "";
+
+ protected List<RocksimComponentFileColumnParser> fileColumns;
+
+ public RocksimComponentFileLoader() {
+ super();
+ fileColumns = new ArrayList<RocksimComponentFileColumnParser>();
+ }
+
+ protected abstract RocksimComponentFileType getFileType();
+
+ public void load() {
+ load( getFileType() );
+ }
+ /**
* Read a comma separated component file and return the parsed contents as a list of string arrays. Not for
* production use - just here for smoke testing.
*
* component data file; the element in the list itself is an array of String, where each item in the array
* is a column (cell) in the row. The string array is in sequential order as it appeared in the file.
*/
- public static List<String[]> load(RocksimComponentFileType type) {
- return load(RocksimComponentFileLoader.class.getResourceAsStream("/giantleaprocketry/" + type.getDefaultFileName()));
+ private void load(RocksimComponentFileType type) {
+ File dir = new File(basePath);
+ if ( !dir.exists() ) {
+ throw new IllegalArgumentException( basePath + " does not exist" );
+ }
+ if ( !dir.isDirectory() ) {
+ throw new IllegalArgumentException( basePath + " is not directory" );
+ }
+ if ( !dir.canRead() ) {
+ throw new IllegalArgumentException ( basePath + " is not readable" );
+ }
+ try {
+ FileInputStream fis = new FileInputStream( new File(dir, type.getDefaultFileName()));
+ load(fis);
+ } catch (FileNotFoundException ex) {
+ // FIXME?
+ }
}
/**
* component data file; the element in the list itself is an array of String, where each item in the array
* is a column (cell) in the row. The string array is in sequential order as it appeared in the file.
*/
- public static List<String[]> load(File file) throws FileNotFoundException {
- return load(new FileInputStream(file));
+ private void load(File file) throws FileNotFoundException {
+ load(new FileInputStream(file));
}
/**
* component data file; the element in the list itself is an array of String, where each item in the array
* is a column (cell) in the row. The string array is in sequential order as it appeared in the file.
*/
- public static List<String[]> load(InputStream is) {
+ private void load(InputStream is) {
if (is == null) {
- return new ArrayList<String[]>();
+ return;
}
InputStreamReader r = null;
try {
CSVReader reader = new CSVReader(r, ',', '\'', '\\');
//Read and throw away the header row.
- reader.readNext();
-
+ parseHeaders(reader.readNext());
+
+ String[] data = null;
+ while( (data = reader.readNext()) != null ) {
+ // detect empty lines and skip:
+ if ( data.length == 0 ) {
+ continue;
+ }
+ if ( data.length == 1 && "".equals(data[0].trim())) {
+ continue;
+ }
+ parseData(data);
+ }
//Read the rest of the file as data rows.
- return reader.readAll();
+ return;
}
catch (IOException e) {
}
}
}
- return new ArrayList<String[]>();
}
+ protected void parseHeaders( String[] headers ) {
+ for( RocksimComponentFileColumnParser column : fileColumns ) {
+ column.configure(headers);
+ }
+ }
+
+ protected void parseData( String[] data ) {
+ if ( data == null || data.length == 0 ) {
+ return;
+ }
+ TypedPropertyMap props = new TypedPropertyMap();
+
+ preProcess( data );
+
+ for( RocksimComponentFileColumnParser column : fileColumns ) {
+ column.parse(data, props);
+ }
+ postProcess( props );
+ }
+
+ protected void preProcess( String[] data ) {
+ for( int i = 0; i< data.length; i++ ) {
+ String d = data[i];
+ if (d == null) {
+ continue;
+ }
+ d = d.trim();
+ d = stripAll(d, '"');
+
+ data[i] = d;
+ }
+ }
+
+ protected abstract void postProcess( TypedPropertyMap props );
+
/**
* Rocksim CSV units are either inches or mm. A value of 0 or "in." indicate inches. A value of 1 or "mm" indicate
* millimeters.
* @param units the value from the file
* @return true if it's inches
*/
- private static boolean isInches(String units) {
+ protected static boolean isInches(String units) {
String tmp = units.trim().toLowerCase();
return "0".equals(tmp) || tmp.startsWith("in");
}
* @param value the original value within the CSV file
* @return the value in meters
*/
- private static double convertLength(String units, double value) {
+ protected static double convertLength(String units, double value) {
if (isInches(units)) {
return PrintUnit.INCHES.toMeters(value);
}
return PrintUnit.MILLIMETERS.toMeters(value);
}
}
+
+ protected static double convertMass(String units, double value ) {
+ if ( "oz".equals(units) ) {
+ Unit u = UnitGroup.UNITS_MASS.getUnit(2);
+ return u.fromUnit(value);
+ }
+ return value;
+ }
/**
* Remove all occurrences of the given character. Note: this is done because some manufacturers embed double
* @param toBeRemoved the character to remove
* @return target, minus every occurrence of toBeRemoved
*/
- private static String stripAll(String target, Character toBeRemoved) {
+ protected static String stripAll(String target, Character toBeRemoved) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < target.length(); i++) {
Character c = target.charAt(i);
* @param target the target string to be operated upon
* @return target, with the first letter of each word in uppercase
*/
- private static String toCamelCase(String target) {
+ protected static String toCamelCase(String target) {
StringBuilder sb = new StringBuilder();
String[] t = target.split("[ ]");
if (t != null && t.length > 0) {
}
}
- /**
- * The core loading method, shared by all component types.
- *
- * @param theData the data as read from the CSV file
- * @param keyMap the list of typed keys that specify the preset's expected columns
- * @param materialMap a map of material name to OR Material; this is sourced from a MATERIAL.CSV file that must
- * accompany the component CSV file.
- * @param type the kind of component
- * @return a collection of preset's
- */
- private static Collection<ComponentPreset> commonLoader(final List<String[]> theData,
- final List<TypedKey<?>> keyMap,
- final Map<String, Material> materialMap,
- final ComponentPreset.Type type) {
- Collection<ComponentPreset> result = new ArrayList<ComponentPreset>();
- List<TypedPropertyMap> templates = new java.util.ArrayList<TypedPropertyMap>();
- Set<String> favorites = Application.getPreferences().getComponentFavorites();
- Integer uom = null;
-
- ColumnDefinition[] columns = new ColumnDefinition[keyMap.size()];
- for (int i = 0; i < keyMap.size(); i++) {
- TypedKey key = keyMap.get(i);
- if (key != null) {
- columns[i] = new ColumnDefinition(key);
- if (key.getName().equals("Units")) {
- uom = i;
- }
- }
- }
-
- for (int i = 0; i < theData.size(); i++) {
- String[] item = theData.get(i);
- TypedPropertyMap preset = new TypedPropertyMap();
-
- for (int j = 0; j < columns.length; j++) {
- if (j < item.length) {
- String value = item[j];
- if (value == null) {
- continue;
- }
- value = value.trim();
- value = stripAll(value, '"');
- if (value.length() == 0) {
- continue;
- }
- final TypedKey typedKey = columns[j].getKey();
- //If it's the material, then pull it out of our internal map. The map references the
- //data from the associated MATERIAL.CSV file that is mandatory.
- if (typedKey.equals(ComponentPreset.MATERIAL)) {
- preset.put(ComponentPreset.MATERIAL, materialMap.get(value));
- }
- //The shape of a nosecone or transition must get mapped from Rocksim to OR.
- else if (typedKey.equals(ComponentPreset.SHAPE)) {
- preset.put(ComponentPreset.SHAPE, RocksimNoseConeCode.fromShapeNameOrCode(value).asOpenRocket());
- }
- else {
- //Rocksim allows different types of length units. They must be converted and normalized to OR.
- final UnitGroup unitGroup = typedKey.getUnitGroup();
- if (unitGroup != null && unitGroup.equals(UnitGroup.UNITS_LENGTH)) {
- columns[j].setProperty(preset, convertLength(item[uom], Double.valueOf(value)));
- }
- else {
- columns[j].setProperty(preset, value);
- }
- }
- }
- }
- //Set what kind of component this is.
- preset.put(ComponentPreset.TYPE, type);
- //Add to the collection.
- templates.add(preset);
- }
-
- for (TypedPropertyMap o : templates) {
- try {
- ComponentPreset preset = ComponentPresetFactory.create(o);
- if (favorites.contains(preset.preferenceKey())) {
- preset.setFavorite(true);
- }
- result.add(preset);
- }
- catch (InvalidComponentPresetException ex) {
- throw new BugException(ex);
- }
- }
-
- return result;
- }
-
- static class BodyTubeLoader {
- private final static int MFG_INDEX = 0;
- private final static int PART_NO_INDEX = 1;
- private final static int DESCRIPTION_INDEX = 2;
- private final static int UNITS_INDEX = 3;
- private final static int ID_INDEX = 4;
- private final static int OD_INDEX = 5;
- private final static int LENGTH_INDEX = 6;
- private final static int MATERIAL_INDEX = 7;
-
- public final static List<TypedKey<?>> keyMap = new ArrayList<TypedKey<?>>(8);
-
- static {
- keyMap.add(MFG_INDEX, ComponentPreset.MANUFACTURER);
- keyMap.add(PART_NO_INDEX, ComponentPreset.PARTNO);
- keyMap.add(DESCRIPTION_INDEX, ComponentPreset.DESCRIPTION);
- keyMap.add(UNITS_INDEX, UNITS_OF_MEASURE);
- keyMap.add(ID_INDEX, ComponentPreset.INNER_DIAMETER);
- keyMap.add(OD_INDEX, ComponentPreset.OUTER_DIAMETER);
- keyMap.add(LENGTH_INDEX, ComponentPreset.LENGTH);
- keyMap.add(MATERIAL_INDEX, ComponentPreset.MATERIAL);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.BODY_TUBE);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.BODY_TUBE);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.BODY_TUBE);
- }
-
- }
-
- /**
- * Tube coupler parser. Although there are additional fields in the file, they are not used by
- * most (any?) manufacturers so we ignore them entirely.
- */
- static class TubeCouplerLoader extends BodyTubeLoader {
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.TUBE_COUPLER);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.TUBE_COUPLER);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.TUBE_COUPLER);
- }
- }
-
- /**
- * Engine block parser. Although there are additional fields in the file, they are not used by
- * most (any?) manufacturers so we ignore them entirely.
- */
- static class EngineBlockLoader extends BodyTubeLoader {
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.ENGINE_BLOCK);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.ENGINE_BLOCK);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.ENGINE_BLOCK);
- }
- }
-
-
- static class BulkheadLoader extends BodyTubeLoader {
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.BULKHEAD);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.BULK_HEAD);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.BULK_HEAD);
- }
- }
-
- static class CenteringRingLoader extends BodyTubeLoader {
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.CENTERING_RING);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.CENTERING_RING);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.CENTERING_RING);
- }
- }
-
- static class NoseConeLoader {
- public static final int MFG_INDEX = 0;
- public static final int PART_NO_INDEX = 1;
- public static final int DESCRIPTION_INDEX = 2;
- public static final int UNITS_INDEX = 3;
- public static final int LENGTH_INDEX = 4;
- public static final int OUTER_DIA_INDEX = 5;
- public static final int LD_RATIO_INDEX = 6;
- public static final int INSERT_LENGTH_INDEX = 7;
- public static final int INSERT_OD_INDEX = 8;
- public static final int THICKNESS_INDEX = 9;
- public static final int SHAPE_INDEX = 10;
- public static final int CONFIG_INDEX = 11;
- public static final int MATERIAL_INDEX = 12;
- public static final int CG_LOC_INDEX = 13;
- public static final int MASS_UNITS_INDEX = 14;
- public static final int MASS_INDEX = 15;
- public static final int BASE_EXT_LEN_INDEX = 16;
-
- public final static TypedKey<Double> LD_RATIO = new TypedKey<Double>("Len/Dia Ratio", Double.class);
- public final static TypedKey<Double> BASE_EXT_LEN = new TypedKey<Double>("Base Ext Len", Double.class, UnitGroup.UNITS_LENGTH);
- public final static TypedKey<String> CONFIG = new TypedKey<String>("Config", String.class);
- public final static TypedKey<Double> CG_LOC = new TypedKey<Double>("CG Loc", Double.class, UnitGroup.UNITS_LENGTH);
- public final static List<TypedKey<?>> keyMap = new ArrayList<TypedKey<?>>(17);
-
- static {
- keyMap.add(MFG_INDEX, ComponentPreset.MANUFACTURER);
- keyMap.add(PART_NO_INDEX, ComponentPreset.PARTNO);
- keyMap.add(DESCRIPTION_INDEX, ComponentPreset.DESCRIPTION);
- keyMap.add(UNITS_INDEX, UNITS_OF_MEASURE);
- keyMap.add(LENGTH_INDEX, ComponentPreset.LENGTH);
- keyMap.add(OUTER_DIA_INDEX, ComponentPreset.AFT_OUTER_DIAMETER);
- keyMap.add(LD_RATIO_INDEX, LD_RATIO);
- keyMap.add(INSERT_LENGTH_INDEX, ComponentPreset.AFT_SHOULDER_LENGTH);
- keyMap.add(INSERT_OD_INDEX, ComponentPreset.AFT_SHOULDER_DIAMETER);
- keyMap.add(THICKNESS_INDEX, ComponentPreset.THICKNESS);
- keyMap.add(SHAPE_INDEX, ComponentPreset.SHAPE);
- keyMap.add(CONFIG_INDEX, CONFIG);
- keyMap.add(MATERIAL_INDEX, ComponentPreset.MATERIAL);
- keyMap.add(CG_LOC_INDEX, CG_LOC);
- keyMap.add(MASS_UNITS_INDEX, UNITS_OF_MEASURE);
- keyMap.add(MASS_INDEX, ComponentPreset.MASS);
- keyMap.add(BASE_EXT_LEN_INDEX, BASE_EXT_LEN);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.NOSE_CONE);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.NOSE_CONE);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.NOSE_CONE);
- }
- }
-
- static class TransitionLoader {
- public static final int MFG_INDEX = 0;
- public static final int PART_NO_INDEX = 1;
- public static final int DESCRIPTION_INDEX = 2;
- public static final int UNITS_INDEX = 3;
- public static final int FRONT_INSERT_LENGTH_INDEX = 4;
- public static final int FRONT_INSERT_OD_INDEX = 5;
- public static final int FRONT_OD_INDEX = 6;
- public static final int LENGTH_INDEX = 7;
- public static final int REAR_OD_INDEX = 8;
- public static final int CORE_DIA_INDEX = 9;
- public static final int REAR_INSERT_LENGTH_INDEX = 10;
- public static final int REAR_INSERT_OD_INDEX = 11;
- public static final int THICKNESS_INDEX = 12;
- public static final int CONFIG_INDEX = 13;
- public static final int MATERIAL_INDEX = 14;
- public static final int CG_LOC_INDEX = 15;
- public static final int MASS_UNITS_INDEX = 16;
- public static final int MASS_INDEX = 17;
- public static final int SHAPE_INDEX = 18;
-
- public final static TypedKey<String> CONFIG = new TypedKey<String>("Config", String.class);
- public final static TypedKey<String> IGNORE = new TypedKey<String>("Ignore", String.class);
- public final static TypedKey<Double> CG_LOC = new TypedKey<Double>("CG Loc", Double.class, UnitGroup.UNITS_LENGTH);
- public final static List<TypedKey<?>> keyMap = new ArrayList<TypedKey<?>>(19);
-
- static {
- keyMap.add(MFG_INDEX, ComponentPreset.MANUFACTURER);
- keyMap.add(PART_NO_INDEX, ComponentPreset.PARTNO);
- keyMap.add(DESCRIPTION_INDEX, ComponentPreset.DESCRIPTION);
- keyMap.add(UNITS_INDEX, UNITS_OF_MEASURE);
- keyMap.add(FRONT_INSERT_LENGTH_INDEX, ComponentPreset.FORE_SHOULDER_LENGTH);
- keyMap.add(FRONT_INSERT_OD_INDEX, ComponentPreset.FORE_SHOULDER_DIAMETER);
- keyMap.add(FRONT_OD_INDEX, ComponentPreset.FORE_OUTER_DIAMETER);
- keyMap.add(LENGTH_INDEX, ComponentPreset.LENGTH);
- keyMap.add(REAR_OD_INDEX, ComponentPreset.AFT_OUTER_DIAMETER);
- keyMap.add(CORE_DIA_INDEX, IGNORE);
- keyMap.add(REAR_INSERT_LENGTH_INDEX, ComponentPreset.AFT_SHOULDER_LENGTH);
- keyMap.add(REAR_INSERT_OD_INDEX, ComponentPreset.AFT_SHOULDER_DIAMETER);
- keyMap.add(THICKNESS_INDEX, ComponentPreset.THICKNESS);
- keyMap.add(CONFIG_INDEX, CONFIG);
- keyMap.add(MATERIAL_INDEX, ComponentPreset.MATERIAL);
- keyMap.add(CG_LOC_INDEX, CG_LOC);
- keyMap.add(MASS_UNITS_INDEX, UNITS_OF_MEASURE);
- keyMap.add(MASS_INDEX, ComponentPreset.MASS);
- keyMap.add(SHAPE_INDEX, ComponentPreset.SHAPE);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap) {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.TRANSITION);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.TRANSITION);
- }
-
- public Collection<ComponentPreset> load(Map<String, Material> materialMap, File file) throws
- FileNotFoundException {
- List<String[]> data = RocksimComponentFileLoader.load(file);
- return commonLoader(data, keyMap, materialMap, ComponentPreset.Type.TRANSITION);
- }
- }
-
- static class MaterialLoader {
- private final static int MATERIAL_INDEX = 0;
- private final static int UNITS_INDEX = 1;
- private final static int DENSITY_INDEX = 2;
- private final static int LOW_INDEX = 3;
- private final static int HIGH_INDEX = 4;
- private final static int CLASS_INDEX = 5;
- private final static int ROCKETRY_USE_INDEX = 6;
- private final static int BODY_TUBES_INDEX = 7;
- public static final int FIN_SETS_INDEX = 8;
- public static final int LAUNCH_LUGS_INDEX = 9;
- public static final int CORDS_INDEX = 10;
- public static final int NOSE_INDEX = 11;
- public static final int PARACHUTE_INDEX = 12;
- public static final int STREAMER_INDEX = 13;
- public static final int TRANSITION_INDEX = 14;
- public static final int RING_INDEX = 15;
- public static final int BULKHEAD_INDEX = 16;
- public static final int ENGINE_BLOCK_INDEX = 17;
- public static final int SLEEVE_INDEX = 18;
- public static final int TUBE_COUPLER_INDEX = 19;
- public static final int KNOWN_DIM_TYPE_INDEX = 27;
- public static final int KNOWN_DIM_UNITS_INDEX = 28;
- public static final int KNOWN_DIM_VALUE_INDEX = 29;
-
- public final static List<TypedKey<?>> keyMap = new ArrayList<TypedKey<?>>(8);
- public final static TypedKey<String> MATERIAL_NAME = new TypedKey<String>("Material Name", String.class);
- public final static TypedKey<Double> DENSITY = new TypedKey<Double>("Density", Double.class);
-
- static class MaterialAdapter {
- Material.Type type;
- double conversionFactor;
-
- MaterialAdapter(Material.Type theType, double cf) {
- type = theType;
- conversionFactor = cf;
- }
- }
-
- private final static Map<String, MaterialAdapter> materialAdapterMap = new HashMap<String, MaterialAdapter>();
-
- static {
- materialAdapterMap.put("g/cm", new MaterialAdapter(Material.Type.LINE, 0.1d));
- materialAdapterMap.put("g/cm2", new MaterialAdapter(Material.Type.SURFACE, 10.0d));
- materialAdapterMap.put("g/cm3", new MaterialAdapter(Material.Type.BULK, 1000.0d));
- materialAdapterMap.put("kg/m3", new MaterialAdapter(Material.Type.BULK, 1d));
- materialAdapterMap.put("lb/ft3", new MaterialAdapter(Material.Type.BULK, 16.0184634d));
- materialAdapterMap.put("oz/in", new MaterialAdapter(Material.Type.LINE, 1.11612296d));
- materialAdapterMap.put("oz/in2", new MaterialAdapter(Material.Type.SURFACE, 43.9418487));
-
- keyMap.add(MATERIAL_INDEX, MATERIAL_NAME);
- keyMap.add(UNITS_INDEX, UNITS_OF_MEASURE);
- keyMap.add(DENSITY_INDEX, DENSITY);
- }
-
- static Map<String, Material> load() {
- List<String[]> data = RocksimComponentFileLoader.load(RocksimComponentFileType.MATERIAL);
- Map<String, Material> materialMap = new HashMap<String, Material>();
-
- for (int i = 0; i < data.size(); i++) {
- try {
- String[] strings = data.get(i);
- MaterialAdapter ma = materialAdapterMap.get(strings[UNITS_INDEX]);
- double metricDensity = ma.conversionFactor * Double.parseDouble(strings[DENSITY_INDEX]);
- final String cleanedMaterialName = stripAll(strings[MATERIAL_INDEX], '"').trim();
- final Material material = Databases.findMaterial(ma.type, cleanedMaterialName,
- metricDensity, true);
- materialMap.put(cleanedMaterialName, material);
- materialMap.put(cleanedMaterialName.toLowerCase(), material);
- materialMap.put(toCamelCase(cleanedMaterialName), material);
- }
- catch (Exception e) {
- //Trap a bad row and move on
- //TODO: log it? Display to user?
- }
- }
- return materialMap;
- }
- }
-
- public static void main(String[] args) {
- Application.setPreferences(new SwingPreferences());
- Map<String, Material> materialMap = MaterialLoader.load();
- Collection<ComponentPreset> presetNC = new NoseConeLoader().load(materialMap);
- Collection<ComponentPreset> presetBC = new BodyTubeLoader().load(materialMap);
- Collection<ComponentPreset> presetBH = new BulkheadLoader().load(materialMap);
- Collection<ComponentPreset> presetCR = new CenteringRingLoader().load(materialMap);
- Collection<ComponentPreset> presetTC = new TubeCouplerLoader().load(materialMap);
- Collection<ComponentPreset> presetTR = new TransitionLoader().load(materialMap);
- Collection<ComponentPreset> presetEB = new EngineBlockLoader().load(materialMap);
-/*
- for (Iterator<ComponentPreset> iterator = presetNC.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
- for (Iterator<ComponentPreset> iterator = presetBC.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
- for (Iterator<ComponentPreset> iterator = presetBH.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
- for (Iterator<ComponentPreset> iterator = presetCR.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
- for (Iterator<ComponentPreset> iterator = presetTC.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
- for (Iterator<ComponentPreset> iterator = presetTR.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
- for (Iterator<ComponentPreset> iterator = presetEB.iterator(); iterator.hasNext(); ) {
- ComponentPreset next = iterator.next();
- System.err.println(next);
- }
-*/
- List<ComponentPreset> allPresets = new ArrayList<ComponentPreset>();
- allPresets.addAll(presetBC);
- allPresets.addAll(presetBH);
- allPresets.addAll(presetCR);
- allPresets.addAll(presetEB);
- allPresets.addAll(presetNC);
- allPresets.addAll(presetTC);
- allPresets.addAll(presetTR);
-
- String xml = new OpenRocketComponentSaver().marshalToOpenRocketComponent(new ArrayList<Material>(materialMap.values()), allPresets);
- System.err.println(xml);
- try {
- List<ComponentPreset> presets = new OpenRocketComponentSaver().unmarshalFromOpenRocketComponent(new StringReader(xml));
- }
- catch (InvalidComponentPresetException e) {
- e.printStackTrace();
- }
- }
}
//Errata:
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Map;
+
+import net.sf.openrocket.gui.util.SwingPreferences;
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.xml.OpenRocketComponentSaver;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.util.ArrayList;
+
+public class RocksimComponentFileTranslator {
+
+ private static void printUsage() {
+ System.err.println("RocksimComponentFileLoader <dir> <file>");
+ System.err.println("<dir> is base directory for a set of Rocksim component csv files");
+ System.err.println("<file> is where the orc file is written");
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ // How to control logging?
+
+ if ( args.length < 2 || args.length > 2 ) {
+ printUsage();
+ throw new IllegalArgumentException("Invalid Command Line Params");
+ }
+
+ List<ComponentPreset> allPresets = new ArrayList<ComponentPreset>();
+
+ RocksimComponentFileLoader.basePath = args[0];
+
+ System.err.println("Loading csv files from directory " + args[0]);
+
+ Application.setPreferences(new SwingPreferences());
+
+ MaterialLoader mats = new MaterialLoader();
+ mats.load();
+
+ Map<String, Material> materialMap = mats.getMaterialMap();
+ System.err.println("\tMaterial types loaded: " + materialMap.size());
+
+ {
+ BodyTubeLoader bts = new BodyTubeLoader(materialMap);
+ bts.load();
+ allPresets.addAll(bts.getPresets());
+ System.err.println("\tBody Tubes loaded: " + bts.getPresets().size());
+ }
+ {
+ BulkHeadLoader bhs = new BulkHeadLoader(materialMap);
+ bhs.load();
+ allPresets.addAll(bhs.getPresets());
+ System.err.println("\tBody Tubes loaded: " + bhs.getPresets().size());
+ }
+ {
+ CenteringRingLoader crs = new CenteringRingLoader(materialMap);
+ crs.load();
+ allPresets.addAll(crs.getPresets());
+ System.err.println("\tCentering Rings loaded: " + crs.getPresets().size());
+ }
+ {
+ TubeCouplerLoader tcs = new TubeCouplerLoader(materialMap);
+ tcs.load();
+ allPresets.addAll(tcs.getPresets());
+ System.err.println("\tTube Couplers loaded: " + tcs.getPresets().size());
+ }
+ {
+ EngineBlockLoader ebs = new EngineBlockLoader(materialMap);
+ ebs.load();
+ allPresets.addAll(ebs.getPresets());
+ System.err.println("\tEngine Blocks loaded: " + ebs.getPresets().size());
+ }
+ {
+ NoseConeLoader ncs = new NoseConeLoader(materialMap);
+ ncs.load();
+ allPresets.addAll(ncs.getPresets());
+ System.err.println("\tNose Cones loaded: " + ncs.getPresets().size());
+ }
+ {
+ TransitionLoader trs = new TransitionLoader(materialMap);
+ trs.load();
+ allPresets.addAll(trs.getPresets());
+ System.err.println("\tTransitions loaded: " + trs.getPresets().size());
+ }
+ System.err.println("\tMarshalling to XML");
+ String xml = new OpenRocketComponentSaver().marshalToOpenRocketComponent(new ArrayList<Material>(materialMap.values()), allPresets);
+
+ // Try parsing the file
+ System.err.println("\tValidating XML");
+ List<ComponentPreset> presets = new OpenRocketComponentSaver().unmarshalFromOpenRocketComponent(new StringReader(xml));
+
+ System.err.println("\tWriting to file " + args[1]);
+ File outfile = new File(args[1]);
+ FileWriter fos = new FileWriter(outfile);
+ fos.write(xml);
+ fos.flush();
+ fos.close();
+
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Locale;
+
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.TypedPropertyMap;
+import net.sf.openrocket.rocketcomponent.Transition;
+import net.sf.openrocket.rocketcomponent.Transition.Shape;
+import net.sf.openrocket.util.BugException;
+
+public class ShapeColumnParser extends BaseColumnParser {
+
+ public ShapeColumnParser() {
+ super("Shape");
+ }
+
+ @Override
+ protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
+ Transition.Shape shape = null;
+ String lc = columnData.toLowerCase(Locale.US);
+ if ( "ogive".equals(lc) ) {
+ shape = Shape.OGIVE;
+ }
+ if ( "conical".equals(lc) ) {
+ shape = Shape.CONICAL;
+ }
+ if ( "cone".equals(lc) ) {
+ shape = Shape.CONICAL;
+ }
+ if ( "elliptical".equals(lc) ) {
+ shape = Shape.ELLIPSOID;
+ }
+ if ( "parabolic".equals(lc) ) {
+ shape = Shape.PARABOLIC;
+ }
+ if ( "sears-haack".equals(lc) ) {
+ shape = Shape.HAACK;
+ }
+ if ( "power-series".equals(lc) ) {
+ shape = Shape.POWER;
+ }
+ if ( "1".equals(lc) ) {
+ shape = Shape.OGIVE;
+ }
+ if( "0". equals(lc) ) {
+ shape = Shape.CONICAL;
+ }
+ if ( shape == null ) {
+ throw new BugException("Invalid shape parameter: " + columnData);
+ }
+ props.put(ComponentPreset.SHAPE, shape);
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import net.sf.openrocket.preset.TypedKey;
+import net.sf.openrocket.preset.TypedPropertyMap;
+
+public class StringColumnParser extends BaseColumnParser {
+
+ private TypedKey<String> propKey;
+
+ public StringColumnParser(String columnHeader, TypedKey<String> propKey) {
+ super(columnHeader);
+ this.propKey = propKey;
+ }
+
+ @Override
+ protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
+ props.put(propKey, columnData);
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+
+public class TransitionLoader extends NoseConeLoader {
+
+ public TransitionLoader(Map<String, Material> materials) {
+ super(materials);
+ fileColumns.add(new DoubleUnitColumnParser("Front Insert Len","Units",ComponentPreset.FORE_SHOULDER_LENGTH));
+ fileColumns.add(new DoubleUnitColumnParser("Front Insert OD","Units",ComponentPreset.FORE_SHOULDER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Front OD","Units",ComponentPreset.FORE_OUTER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Rear Insert Len","Units",ComponentPreset.AFT_SHOULDER_LENGTH));
+ fileColumns.add(new DoubleUnitColumnParser("Rear Insert OD","Units",ComponentPreset.AFT_SHOULDER_DIAMETER));
+ fileColumns.add(new DoubleUnitColumnParser("Rear OD","Units",ComponentPreset.AFT_OUTER_DIAMETER));
+ }
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.TRANSITION;
+ }
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.TRANSITION;
+ }
+
+}
--- /dev/null
+package net.sf.openrocket.preset.loader;
+
+import java.util.Map;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.ComponentPreset.Type;
+
+public class TubeCouplerLoader extends BodyTubeLoader {
+
+ public TubeCouplerLoader(Map<String, Material> materials) {
+ super(materials);
+ }
+
+ @Override
+ protected Type getComponentPresetType() {
+ return ComponentPreset.Type.TUBE_COUPLER;
+ }
+
+ @Override
+ protected RocksimComponentFileType getFileType() {
+ return RocksimComponentFileType.TUBE_COUPLER;
+ }
+
+}
package net.sf.openrocket.preset.xml;
-import net.sf.openrocket.logging.LogHelper;
-import net.sf.openrocket.material.Material;
-import net.sf.openrocket.preset.ComponentPreset;
-import net.sf.openrocket.preset.InvalidComponentPresetException;
-import net.sf.openrocket.startup.Application;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.List;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+import net.sf.openrocket.material.Material;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.InvalidComponentPresetException;
+
/**
* The active manager class that is the entry point for writing *.orc files.
*/
public class OpenRocketComponentSaver {
- /**
- * The logger.
- */
- private static final LogHelper log = Application.getLogger();
-
- /**
- * This method marshals an OpenRocketDocument (OR design) to Rocksim-compliant XML.
- *
- * @param theMaterialList the list of materials to be included
- * @param thePresetList the list of presets to be included
- *
- * @return ORC-compliant XML
- */
- public String marshalToOpenRocketComponent(List<Material> theMaterialList, List<ComponentPreset> thePresetList) {
-
- try {
- JAXBContext binder = JAXBContext.newInstance(OpenRocketComponentDTO.class);
- Marshaller marshaller = binder.createMarshaller();
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
- StringWriter sw = new StringWriter();
-
- marshaller.marshal(toOpenRocketComponentDTO(theMaterialList, thePresetList), sw);
- return sw.toString();
- }
- catch (Exception e) {
- log.error("Could not marshal a preset list. " + e.getMessage());
- }
-
- return null;
- }
-
- /**
- * This method unmarshals from a Reader that is presumed to be open on an XML file in .orc format.
- *
- * @param is an open reader; StringBufferInputStream could not be used because it's deprecated and does not handle
- * UTF characters correctly
- *
- * @return a list of ComponentPresets
- *
- * @throws InvalidComponentPresetException
- *
- */
- public List<ComponentPreset> unmarshalFromOpenRocketComponent(Reader is) throws InvalidComponentPresetException {
- return fromOpenRocketComponent(is).asComponentPresets();
- }
-
- /**
- * Write an XML representation of a list of presets.
- *
- * @param dest the stream to write the data to
- * @param theMaterialList the list of materials to be included
- * @param thePresetList the list of presets to be included
- *
- * @throws IOException thrown if the stream could not be written
- */
- public void save(OutputStream dest, List<Material> theMaterialList, List<ComponentPreset> thePresetList) throws
- IOException {
- log.info("Saving .orc file");
-
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, "UTF-8"));
- writer.write(marshalToOpenRocketComponent(theMaterialList, thePresetList));
- writer.flush();
- writer.close();
- }
-
- /**
- * Read from an open Reader instance XML in .orc format and reconstruct an OpenRocketComponentDTO instance.
- *
- * @param is an open Reader; assumed to be opened on a file of XML in .orc format
- *
- * @return the OpenRocketComponentDTO that is a POJO representation of the XML; null if the data could not be read
- * or was in an invalid format
- */
- private OpenRocketComponentDTO fromOpenRocketComponent(Reader is) {
- try {
- JAXBContext bind = JAXBContext.newInstance(OpenRocketComponentDTO.class);
- Unmarshaller unmarshaller = bind.createUnmarshaller();
- return (OpenRocketComponentDTO) unmarshaller.unmarshal(is);
- }
- catch (JAXBException e) {
- log.error("Could not unmarshal the .orc file. ", e);
- }
- return null;
- }
-
- /**
- * Root conversion method. It iterates over all subcomponents.
- *
- * @return a corresponding ORC representation
- */
- private OpenRocketComponentDTO toOpenRocketComponentDTO(List<Material> theMaterialList, List<ComponentPreset> thePresetList) {
- OpenRocketComponentDTO rsd = new OpenRocketComponentDTO();
-
- if (theMaterialList != null) {
- for (Material material : theMaterialList) {
- rsd.addMaterial(new MaterialDTO(material));
- }
- }
-
- if (thePresetList != null) {
- for (ComponentPreset componentPreset : thePresetList) {
- rsd.addComponent(toComponentDTO(componentPreset));
- }
- }
- return rsd;
- }
-
- /**
- * Factory method that maps a preset to the corresponding DTO handler.
- *
- * @param thePreset the preset for which a handler will be found
- *
- * @return a subclass of BaseComponentDTO that can be used for marshalling/unmarshalling a preset; null if not found
- * for the preset type
- */
- private static BaseComponentDTO toComponentDTO(ComponentPreset thePreset) {
- switch (thePreset.getType()) {
- case BODY_TUBE:
- return new BodyTubeDTO(thePreset);
- case TUBE_COUPLER:
- return new TubeCouplerDTO(thePreset);
- case NOSE_CONE:
- return new NoseConeDTO(thePreset);
- case TRANSITION:
- return new TransitionDTO(thePreset);
- case BULK_HEAD:
- return new BulkHeadDTO(thePreset);
- case CENTERING_RING:
- return new CenteringRingDTO(thePreset);
- case ENGINE_BLOCK:
- return new EngineBlockDTO(thePreset);
- }
-
- return null;
- }
+ /**
+ * This method marshals an OpenRocketDocument (OR design) to Rocksim-compliant XML.
+ *
+ * @param theMaterialList the list of materials to be included
+ * @param thePresetList the list of presets to be included
+ *
+ * @return ORC-compliant XML
+ * @throws JAXBException
+ */
+ public String marshalToOpenRocketComponent(List<Material> theMaterialList, List<ComponentPreset> thePresetList) throws JAXBException {
+
+ JAXBContext binder = JAXBContext.newInstance(OpenRocketComponentDTO.class);
+ Marshaller marshaller = binder.createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+ StringWriter sw = new StringWriter();
+
+ marshaller.marshal(toOpenRocketComponentDTO(theMaterialList, thePresetList), sw);
+ return sw.toString();
+
+ }
+
+ /**
+ * This method unmarshals from a Reader that is presumed to be open on an XML file in .orc format.
+ *
+ * @param is an open reader; StringBufferInputStream could not be used because it's deprecated and does not handle
+ * UTF characters correctly
+ *
+ * @return a list of ComponentPresets
+ *
+ * @throws InvalidComponentPresetException
+ *
+ */
+ public List<ComponentPreset> unmarshalFromOpenRocketComponent(Reader is) throws JAXBException, InvalidComponentPresetException {
+ return fromOpenRocketComponent(is).asComponentPresets();
+ }
+
+ /**
+ * Write an XML representation of a list of presets.
+ *
+ * @param dest the stream to write the data to
+ * @param theMaterialList the list of materials to be included
+ * @param thePresetList the list of presets to be included
+ * @throws JAXBException
+ * @throws IOException thrown if the stream could not be written
+ */
+ public void save(OutputStream dest, List<Material> theMaterialList, List<ComponentPreset> thePresetList) throws IOException, JAXBException {
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, "UTF-8"));
+ writer.write(marshalToOpenRocketComponent(theMaterialList, thePresetList));
+ writer.flush();
+ writer.close();
+ }
+
+ /**
+ * Read from an open Reader instance XML in .orc format and reconstruct an OpenRocketComponentDTO instance.
+ *
+ * @param is an open Reader; assumed to be opened on a file of XML in .orc format
+ *
+ * @return the OpenRocketComponentDTO that is a POJO representation of the XML; null if the data could not be read
+ * or was in an invalid format
+ */
+ private OpenRocketComponentDTO fromOpenRocketComponent(Reader is) throws JAXBException {
+ JAXBContext bind = JAXBContext.newInstance(OpenRocketComponentDTO.class);
+ Unmarshaller unmarshaller = bind.createUnmarshaller();
+ return (OpenRocketComponentDTO) unmarshaller.unmarshal(is);
+ }
+
+ /**
+ * Root conversion method. It iterates over all subcomponents.
+ *
+ * @return a corresponding ORC representation
+ */
+ private OpenRocketComponentDTO toOpenRocketComponentDTO(List<Material> theMaterialList, List<ComponentPreset> thePresetList) {
+ OpenRocketComponentDTO rsd = new OpenRocketComponentDTO();
+
+ if (theMaterialList != null) {
+ for (Material material : theMaterialList) {
+ rsd.addMaterial(new MaterialDTO(material));
+ }
+ }
+
+ if (thePresetList != null) {
+ for (ComponentPreset componentPreset : thePresetList) {
+ rsd.addComponent(toComponentDTO(componentPreset));
+ }
+ }
+ return rsd;
+ }
+
+ /**
+ * Factory method that maps a preset to the corresponding DTO handler.
+ *
+ * @param thePreset the preset for which a handler will be found
+ *
+ * @return a subclass of BaseComponentDTO that can be used for marshalling/unmarshalling a preset; null if not found
+ * for the preset type
+ */
+ private static BaseComponentDTO toComponentDTO(ComponentPreset thePreset) {
+ switch (thePreset.getType()) {
+ case BODY_TUBE:
+ return new BodyTubeDTO(thePreset);
+ case TUBE_COUPLER:
+ return new TubeCouplerDTO(thePreset);
+ case NOSE_CONE:
+ return new NoseConeDTO(thePreset);
+ case TRANSITION:
+ return new TransitionDTO(thePreset);
+ case BULK_HEAD:
+ return new BulkHeadDTO(thePreset);
+ case CENTERING_RING:
+ return new CenteringRingDTO(thePreset);
+ case ENGINE_BLOCK:
+ return new EngineBlockDTO(thePreset);
+ }
+
+ return null;
+ }
}