Added ability to open *.csv files to menu.
This commit is contained in:
parent
1ee93fdab0
commit
90ebc01268
@ -8,6 +8,8 @@ import net.sf.openrocket.l10n.ResourceBundleTranslator;
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.loader.MaterialHolder;
|
||||
import net.sf.openrocket.preset.loader.RocksimComponentFileTranslator;
|
||||
import net.sf.openrocket.preset.xml.OpenRocketComponentLoader;
|
||||
import net.sf.openrocket.preset.xml.OpenRocketComponentSaver;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
@ -37,14 +39,11 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A UI for editing component presets. Currently this is a standalone application - run the main within this class.
|
||||
* TODO: Full I18n
|
||||
* TODO: Open .csv
|
||||
* TODO: Save As .csv
|
||||
* TODO: Full I18n TODO: Save As .csv
|
||||
*/
|
||||
public class ComponentPresetPanel extends JPanel implements PresetResultListener {
|
||||
|
||||
@ -224,17 +223,6 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
add(addBtn, "cell 0 1,alignx left,aligny top");
|
||||
}
|
||||
|
||||
private boolean saveAndHandleError() {
|
||||
try {
|
||||
return saveAsORC();
|
||||
}
|
||||
catch (Exception e1) {
|
||||
JOptionPane.showMessageDialog(ComponentPresetPanel.this, e1.getLocalizedMessage(),
|
||||
"Error saving ORC file.", JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method from the PresetEditorDialog to notify this class when a preset has been saved. The 'save' is
|
||||
* really just a call back here so the preset can be added to the master table. It's not to be confused with the
|
||||
@ -247,9 +235,11 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
if (preset != null) {
|
||||
DataTableModel model = (DataTableModel) table.getModel();
|
||||
//Is this a new preset?
|
||||
String description = preset.has(ComponentPreset.DESCRIPTION) ? preset.get(ComponentPreset.DESCRIPTION) :
|
||||
preset.getPartNo();
|
||||
if (!editingSelected) {
|
||||
model.addRow(new Object[]{preset.getManufacturer().getDisplayName(), preset.getType().name(),
|
||||
preset.getPartNo(), preset.get(ComponentPreset.DESCRIPTION), Icons.EDIT_DELETE}, preset);
|
||||
preset.getPartNo(), description, Icons.EDIT_DELETE}, preset);
|
||||
}
|
||||
else {
|
||||
//This is a modified preset; update all of the columns and the stored associated instance.
|
||||
@ -257,7 +247,7 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
model.setValueAt(preset.getManufacturer().getDisplayName(), row, 0);
|
||||
model.setValueAt(preset.getType().name(), row, 1);
|
||||
model.setValueAt(preset.getPartNo(), row, 2);
|
||||
model.setValueAt(preset.get(ComponentPreset.DESCRIPTION), row, 3);
|
||||
model.setValueAt(description, row, 3);
|
||||
model.associated.set(row, preset);
|
||||
}
|
||||
}
|
||||
@ -338,8 +328,9 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
private boolean openComponentFile() {
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
chooser.addChoosableFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
|
||||
|
||||
chooser.addChoosableFileFilter(FileHelper.CSV_FILE_FILTER);
|
||||
chooser.setFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||
if (lastDirectory != null) {
|
||||
chooser.setCurrentDirectory(lastDirectory);
|
||||
}
|
||||
@ -362,9 +353,18 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
}
|
||||
|
||||
lastDirectory = file.getParentFile();
|
||||
List<ComponentPreset> presets = null;
|
||||
|
||||
Collection<ComponentPreset> presets = new OpenRocketComponentLoader().load(new FileInputStream(file),
|
||||
file.getName());
|
||||
if (file.getName().toLowerCase().endsWith(".orc")) {
|
||||
presets = (List<ComponentPreset>) new OpenRocketComponentLoader().load(new FileInputStream(file), file.getName());
|
||||
}
|
||||
else {
|
||||
if (file.getName().toLowerCase().endsWith(".csv")) {
|
||||
file = file.getParentFile();
|
||||
}
|
||||
presets = new ArrayList<ComponentPreset>();
|
||||
MaterialHolder materialHolder = RocksimComponentFileTranslator.loadAll(presets, file);
|
||||
}
|
||||
if (presets != null) {
|
||||
for (ComponentPreset next : presets) {
|
||||
notifyResult(next);
|
||||
@ -373,6 +373,7 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
JOptionPane.showMessageDialog(ComponentPresetPanel.this, "Unable to open OpenRocket component file: " +
|
||||
file.getName() + " Invalid format. " + e.getMessage());
|
||||
openedFile = null;
|
||||
@ -381,6 +382,17 @@ public class ComponentPresetPanel extends JPanel implements PresetResultListener
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean saveAndHandleError() {
|
||||
try {
|
||||
return saveAsORC();
|
||||
}
|
||||
catch (Exception e1) {
|
||||
JOptionPane.showMessageDialog(ComponentPresetPanel.this, e1.getLocalizedMessage(),
|
||||
"Error saving ORC file.", JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the contents of the table model as XML in .orc format.
|
||||
*
|
||||
|
@ -1,21 +1,20 @@
|
||||
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;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class BaseComponentLoader extends RocksimComponentFileLoader {
|
||||
|
||||
List<ComponentPreset> presets;
|
||||
|
||||
public BaseComponentLoader(MaterialHolder materials) {
|
||||
super();
|
||||
public BaseComponentLoader(MaterialHolder materials, File theBasePathToLoadFrom) {
|
||||
super(theBasePathToLoadFrom);
|
||||
presets = new ArrayList<ComponentPreset>();
|
||||
|
||||
fileColumns.add( new ManufacturerColumnParser() );
|
||||
@ -27,14 +26,18 @@ public abstract class BaseComponentLoader extends RocksimComponentFileLoader {
|
||||
}
|
||||
|
||||
protected abstract ComponentPreset.Type getComponentPresetType();
|
||||
|
||||
|
||||
public List<ComponentPreset> getPresets() {
|
||||
return presets;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void postProcess(TypedPropertyMap props) {
|
||||
try {
|
||||
//Some Rocksim files don't contain description, so set it to the part no when not available.
|
||||
if (!props.containsKey(ComponentPreset.DESCRIPTION)) {
|
||||
props.put(ComponentPreset.DESCRIPTION, props.get(ComponentPreset.PARTNO));
|
||||
}
|
||||
props.put(ComponentPreset.TYPE, getComponentPresetType());
|
||||
ComponentPreset preset = ComponentPresetFactory.create(props);
|
||||
presets.add(preset);
|
||||
|
@ -1,22 +1,21 @@
|
||||
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 java.io.File;
|
||||
|
||||
public class BodyTubeLoader extends BaseComponentLoader {
|
||||
|
||||
public BodyTubeLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public BodyTubeLoader(MaterialHolder materials, File theBasePathToLoadFrom) {
|
||||
super(materials, theBasePathToLoadFrom);
|
||||
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;
|
||||
|
@ -4,15 +4,17 @@ import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
import net.sf.openrocket.preset.TypedPropertyMap;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class BulkHeadLoader extends BaseComponentLoader {
|
||||
|
||||
public BulkHeadLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public BulkHeadLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
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;
|
||||
|
@ -3,10 +3,12 @@ package net.sf.openrocket.preset.loader;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class CenteringRingLoader extends BodyTubeLoader {
|
||||
|
||||
public CenteringRingLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public CenteringRingLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,13 +22,13 @@ public class DoubleUnitColumnParser extends BaseUnitColumnParser {
|
||||
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) ) {
|
||||
if ( unitName == null || "" .equals(unitName) || "?".equals(unitName)) {
|
||||
// Hmm no data... Lets assume SI
|
||||
if ( propKey.getUnitGroup() == UnitGroup.UNITS_LENGTH ) {
|
||||
unit = UnitGroup.UNITS_LENGTH.getUnit("in");
|
||||
@ -41,14 +41,16 @@ public class DoubleUnitColumnParser extends BaseUnitColumnParser {
|
||||
unit = group.getUnit(unitName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
value = unit.fromUnit(value);
|
||||
}
|
||||
|
||||
|
||||
props.put(propKey, value);
|
||||
}
|
||||
catch ( NumberFormatException nex) {
|
||||
}
|
||||
catch ( IllegalArgumentException iae) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3,10 +3,12 @@ package net.sf.openrocket.preset.loader;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class EngineBlockLoader extends BodyTubeLoader {
|
||||
|
||||
public EngineBlockLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public EngineBlockLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,17 +3,19 @@ package net.sf.openrocket.preset.loader;
|
||||
import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LaunchLugLoader extends BaseComponentLoader {
|
||||
|
||||
public LaunchLugLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public LaunchLugLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
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.LAUNCH_LUG;
|
||||
|
@ -17,7 +17,7 @@ public class MassColumnParser extends DoubleUnitColumnParser {
|
||||
|
||||
@Override
|
||||
protected void doParse(String columnData, String[] data, TypedPropertyMap props) {
|
||||
if ( columnData == null || "".equals(columnData.trim())) {
|
||||
if ( columnData == null || "".equals(columnData.trim()) || "?".equals(columnData.trim())) {
|
||||
return;
|
||||
}
|
||||
double d = Double.valueOf(columnData);
|
||||
|
@ -1,23 +1,22 @@
|
||||
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;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MaterialLoader extends RocksimComponentFileLoader {
|
||||
|
||||
private MaterialHolder materialMap = new MaterialHolder();
|
||||
|
||||
|
||||
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();
|
||||
|
||||
public MaterialLoader(File theBasePathToLoadFrom) {
|
||||
super(theBasePathToLoadFrom);
|
||||
fileColumns.add( new StringColumnParser("Material Name", MATERIALNAME) );
|
||||
fileColumns.add( new StringColumnParser("Units", UNITS));
|
||||
fileColumns.add( new DoubleColumnParser("Density", DENSITY));
|
||||
@ -37,9 +36,9 @@ public class MaterialLoader extends RocksimComponentFileLoader {
|
||||
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( new Material.Line(cleanedMaterialName, 0.1d * density, true));
|
||||
} else if ( "g/cm2".equals(unit) ) {
|
||||
|
@ -4,10 +4,12 @@ import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
import net.sf.openrocket.preset.TypedPropertyMap;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class NoseConeLoader extends BaseComponentLoader {
|
||||
|
||||
public NoseConeLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public NoseConeLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
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));
|
||||
|
@ -5,12 +5,14 @@ import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
import net.sf.openrocket.preset.TypedPropertyMap;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ParachuteLoader extends BaseComponentLoader {
|
||||
|
||||
private final MaterialHolder materials;
|
||||
|
||||
public ParachuteLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public ParachuteLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
this.materials = materials;
|
||||
fileColumns.add(new IntegerColumnParser("n sides", ComponentPreset.SIDES));
|
||||
fileColumns.add(new DoubleUnitColumnParser("OD","Units",ComponentPreset.DIAMETER));
|
||||
@ -21,7 +23,7 @@ public class ParachuteLoader extends BaseComponentLoader {
|
||||
fileColumns.add( new SurfaceMaterialColumnParser(materials,"Chute Material", ComponentPreset.MATERIAL));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Type getComponentPresetType() {
|
||||
return ComponentPreset.Type.PARACHUTE;
|
||||
@ -41,7 +43,7 @@ public class ParachuteLoader extends BaseComponentLoader {
|
||||
// Fix the material since some files use bulk materials for streamers.
|
||||
Double thickness = props.get( ComponentPreset.THICKNESS );
|
||||
Material.Surface material = (Material.Surface) props.get( ComponentPreset.MATERIAL );
|
||||
|
||||
|
||||
material = materials.getSurfaceMaterial(material, thickness);
|
||||
props.put(ComponentPreset.MATERIAL, material);
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
package net.sf.openrocket.preset.loader;
|
||||
|
||||
import au.com.bytecode.opencsv.CSVReader;
|
||||
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 java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -8,64 +15,77 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
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 abstract class RocksimComponentFileLoader {
|
||||
|
||||
public static String basePath = "";
|
||||
|
||||
protected List<RocksimComponentFileColumnParser> fileColumns;
|
||||
|
||||
public RocksimComponentFileLoader() {
|
||||
super();
|
||||
fileColumns = new ArrayList<RocksimComponentFileColumnParser>();
|
||||
}
|
||||
private String basePath = "";
|
||||
|
||||
private File dir;
|
||||
|
||||
protected List<RocksimComponentFileColumnParser> fileColumns = new ArrayList<RocksimComponentFileColumnParser>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param theBasePathToLoadFrom base path
|
||||
*/
|
||||
public RocksimComponentFileLoader(File theBasePathToLoadFrom) {
|
||||
dir = theBasePathToLoadFrom;
|
||||
basePath = dir.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param theBasePathToLoadFrom base path
|
||||
*/
|
||||
public RocksimComponentFileLoader(String theBasePathToLoadFrom) {
|
||||
dir = new File(basePath);
|
||||
basePath = theBasePathToLoadFrom;
|
||||
}
|
||||
|
||||
protected abstract RocksimComponentFileType getFileType();
|
||||
|
||||
|
||||
public void load() {
|
||||
load( getFileType() );
|
||||
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.
|
||||
*
|
||||
* @param type the type of component file to read; uses the default file name
|
||||
*
|
||||
* @return a list (guaranteed never to be null) of string arrays. Each element of the list represents a row in the
|
||||
* 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.
|
||||
*/
|
||||
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?
|
||||
}
|
||||
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?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a comma separated component file and return the parsed contents as a list of string arrays.
|
||||
*
|
||||
* @param file the file to read and parse
|
||||
*
|
||||
* @return a list (guaranteed never to be null) of string arrays. Each element of the list represents a row in the
|
||||
* 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.
|
||||
@ -78,13 +98,14 @@ public abstract class RocksimComponentFileLoader {
|
||||
* Read a comma separated component file and return the parsed contents as a list of string arrays.
|
||||
*
|
||||
* @param is the stream to read and parse
|
||||
*
|
||||
* @return a list (guaranteed never to be null) of string arrays. Each element of the list represents a row in the
|
||||
* 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.
|
||||
*/
|
||||
private void load(InputStream is) {
|
||||
if (is == null) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
InputStreamReader r = null;
|
||||
try {
|
||||
@ -97,15 +118,15 @@ public abstract class RocksimComponentFileLoader {
|
||||
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);
|
||||
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;
|
||||
@ -124,29 +145,29 @@ public abstract class RocksimComponentFileLoader {
|
||||
|
||||
}
|
||||
|
||||
protected void parseHeaders( String[] headers ) {
|
||||
for( RocksimComponentFileColumnParser column : fileColumns ) {
|
||||
column.configure(headers);
|
||||
}
|
||||
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 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];
|
||||
|
||||
protected void preProcess(String[] data) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
String d = data[i];
|
||||
if (d == null) {
|
||||
continue;
|
||||
}
|
||||
@ -154,16 +175,17 @@ public abstract class RocksimComponentFileLoader {
|
||||
d = stripAll(d, '"');
|
||||
|
||||
data[i] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void postProcess( TypedPropertyMap props );
|
||||
|
||||
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
|
||||
*/
|
||||
protected static boolean isInches(String units) {
|
||||
@ -176,6 +198,7 @@ public abstract class RocksimComponentFileLoader {
|
||||
*
|
||||
* @param units a Rocksim CSV string representing the kind of units.
|
||||
* @param value the original value within the CSV file
|
||||
*
|
||||
* @return the value in meters
|
||||
*/
|
||||
protected static double convertLength(String units, double value) {
|
||||
@ -186,22 +209,23 @@ public abstract class RocksimComponentFileLoader {
|
||||
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;
|
||||
|
||||
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
|
||||
* quotes in their descriptions or material names. Those are stripped away because they cause all sorts of
|
||||
* matching/lookup issues.
|
||||
* Remove all occurrences of the given character. Note: this is done because some manufacturers embed double quotes
|
||||
* in their descriptions or material names. Those are stripped away because they cause all sorts of matching/lookup
|
||||
* issues.
|
||||
*
|
||||
* @param target the target string to be operated upon
|
||||
* @param toBeRemoved the character to remove
|
||||
*
|
||||
* @return target, minus every occurrence of toBeRemoved
|
||||
*/
|
||||
protected static String stripAll(String target, Character toBeRemoved) {
|
||||
@ -216,12 +240,13 @@ public abstract class RocksimComponentFileLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all words in a given string to Camel Case (first letter capitalized). Words are assumed to be
|
||||
* separated by a space. Note: this is done because some manufacturers define their material name in Camel Case
|
||||
* but the component part references the material in lower case. That causes matching/lookup issues that's
|
||||
* easiest handled this way (rather than converting everything to lower case.
|
||||
* Convert all words in a given string to Camel Case (first letter capitalized). Words are assumed to be separated
|
||||
* by a space. Note: this is done because some manufacturers define their material name in Camel Case but the
|
||||
* component part references the material in lower case. That causes matching/lookup issues that's easiest handled
|
||||
* this way (rather than converting everything to lower case.
|
||||
*
|
||||
* @param target the target string to be operated upon
|
||||
*
|
||||
* @return target, with the first letter of each word in uppercase
|
||||
*/
|
||||
protected static String toCamelCase(String target) {
|
||||
|
@ -1,11 +1,5 @@
|
||||
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;
|
||||
@ -14,112 +8,142 @@ import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.startup.Startup;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.List;
|
||||
|
||||
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");
|
||||
}
|
||||
private static PrintStream LOGGER = System.err;
|
||||
|
||||
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");
|
||||
}
|
||||
private static void printUsage() {
|
||||
LOGGER.println("RocksimComponentFileLoader <dir> <file>");
|
||||
LOGGER.println("<dir> is base directory for a set of Rocksim component csv files");
|
||||
LOGGER.println("<file> is where the orc file is written");
|
||||
}
|
||||
|
||||
List<ComponentPreset> allPresets = new ArrayList<ComponentPreset>();
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
RocksimComponentFileLoader.basePath = args[0];
|
||||
|
||||
System.err.println("Loading csv files from directory " + args[0]);
|
||||
|
||||
Startup.initializeLogging();
|
||||
Application.setPreferences(new SwingPreferences());
|
||||
// How to control logging?
|
||||
|
||||
MaterialLoader mats = new MaterialLoader();
|
||||
mats.load();
|
||||
if (args.length < 2 || args.length > 2) {
|
||||
printUsage();
|
||||
throw new IllegalArgumentException("Invalid Command Line Params");
|
||||
}
|
||||
|
||||
MaterialHolder 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("\tBulkheads 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());
|
||||
}
|
||||
{
|
||||
LaunchLugLoader lls = new LaunchLugLoader(materialMap);
|
||||
lls.load();
|
||||
allPresets.addAll(lls.getPresets());
|
||||
System.err.println("\tLaunch Lugs loaded: " + lls.getPresets().size());
|
||||
}
|
||||
{
|
||||
StreamerLoader sts = new StreamerLoader(materialMap);
|
||||
sts.load();
|
||||
allPresets.addAll(sts.getPresets());
|
||||
System.err.println("\tStreamers loaded: " + sts.getPresets().size());
|
||||
}
|
||||
{
|
||||
ParachuteLoader pcs = new ParachuteLoader(materialMap);
|
||||
pcs.load();
|
||||
allPresets.addAll(pcs.getPresets());
|
||||
System.err.println("Parachutes loaded: " + pcs.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();
|
||||
|
||||
}
|
||||
List<ComponentPreset> allPresets = new ArrayList<ComponentPreset>();
|
||||
|
||||
LOGGER.println("Loading csv files from directory " + args[0]);
|
||||
|
||||
Startup.initializeLogging();
|
||||
Application.setPreferences(new SwingPreferences());
|
||||
|
||||
MaterialHolder materialMap = loadAll(allPresets, new File(args[0]));
|
||||
LOGGER.println("\tMarshalling to XML");
|
||||
String xml = new OpenRocketComponentSaver().marshalToOpenRocketComponent(new ArrayList<Material>(materialMap.values()), allPresets);
|
||||
|
||||
// Try parsing the file
|
||||
LOGGER.println("\tValidating XML");
|
||||
List<ComponentPreset> presets = new OpenRocketComponentSaver().unmarshalFromOpenRocketComponent(new StringReader(xml));
|
||||
|
||||
LOGGER.println("\tWriting to file " + args[1]);
|
||||
File outfile = new File(args[1]);
|
||||
FileWriter fos = new FileWriter(outfile);
|
||||
fos.write(xml);
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a print stream as a logger. Defaults to System.err.
|
||||
*
|
||||
* @param ps a stream to log to
|
||||
*/
|
||||
public static void setLogger(PrintStream ps) {
|
||||
if (ps != null) {
|
||||
LOGGER = ps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all presets. The loaded presets are added to the list parameter. The loaded materials are returned in the
|
||||
* MaterialHolder instance.
|
||||
*
|
||||
* @param theAllPresets a list of ComponentPreset that gets populated as the result of loading; must not be null on
|
||||
* invocation
|
||||
*
|
||||
* @return a holder of the materials loaded
|
||||
*/
|
||||
public static MaterialHolder loadAll(final List<ComponentPreset> theAllPresets, File theBasePathToLoadFrom) {
|
||||
MaterialLoader mats = new MaterialLoader(theBasePathToLoadFrom);
|
||||
mats.load();
|
||||
|
||||
MaterialHolder materialMap = mats.getMaterialMap();
|
||||
LOGGER.println("\tMaterial types loaded: " + materialMap.size());
|
||||
|
||||
{
|
||||
BodyTubeLoader bts = new BodyTubeLoader(materialMap, theBasePathToLoadFrom);
|
||||
bts.load();
|
||||
theAllPresets.addAll(bts.getPresets());
|
||||
LOGGER.println("\tBody Tubes loaded: " + bts.getPresets().size());
|
||||
}
|
||||
{
|
||||
BulkHeadLoader bhs = new BulkHeadLoader(materialMap, theBasePathToLoadFrom);
|
||||
bhs.load();
|
||||
theAllPresets.addAll(bhs.getPresets());
|
||||
LOGGER.println("\tBulkheads loaded: " + bhs.getPresets().size());
|
||||
}
|
||||
{
|
||||
CenteringRingLoader crs = new CenteringRingLoader(materialMap, theBasePathToLoadFrom);
|
||||
crs.load();
|
||||
theAllPresets.addAll(crs.getPresets());
|
||||
LOGGER.println("\tCentering Rings loaded: " + crs.getPresets().size());
|
||||
}
|
||||
{
|
||||
TubeCouplerLoader tcs = new TubeCouplerLoader(materialMap, theBasePathToLoadFrom);
|
||||
tcs.load();
|
||||
theAllPresets.addAll(tcs.getPresets());
|
||||
LOGGER.println("\tTube Couplers loaded: " + tcs.getPresets().size());
|
||||
}
|
||||
{
|
||||
EngineBlockLoader ebs = new EngineBlockLoader(materialMap, theBasePathToLoadFrom);
|
||||
ebs.load();
|
||||
theAllPresets.addAll(ebs.getPresets());
|
||||
LOGGER.println("\tEngine Blocks loaded: " + ebs.getPresets().size());
|
||||
}
|
||||
{
|
||||
NoseConeLoader ncs = new NoseConeLoader(materialMap, theBasePathToLoadFrom);
|
||||
ncs.load();
|
||||
theAllPresets.addAll(ncs.getPresets());
|
||||
LOGGER.println("\tNose Cones loaded: " + ncs.getPresets().size());
|
||||
}
|
||||
{
|
||||
TransitionLoader trs = new TransitionLoader(materialMap, theBasePathToLoadFrom);
|
||||
trs.load();
|
||||
theAllPresets.addAll(trs.getPresets());
|
||||
LOGGER.println("\tTransitions loaded: " + trs.getPresets().size());
|
||||
}
|
||||
{
|
||||
LaunchLugLoader lls = new LaunchLugLoader(materialMap, theBasePathToLoadFrom);
|
||||
lls.load();
|
||||
theAllPresets.addAll(lls.getPresets());
|
||||
LOGGER.println("\tLaunch Lugs loaded: " + lls.getPresets().size());
|
||||
}
|
||||
{
|
||||
StreamerLoader sts = new StreamerLoader(materialMap, theBasePathToLoadFrom);
|
||||
sts.load();
|
||||
theAllPresets.addAll(sts.getPresets());
|
||||
LOGGER.println("\tStreamers loaded: " + sts.getPresets().size());
|
||||
}
|
||||
{
|
||||
ParachuteLoader pcs = new ParachuteLoader(materialMap, theBasePathToLoadFrom);
|
||||
pcs.load();
|
||||
theAllPresets.addAll(pcs.getPresets());
|
||||
LOGGER.println("Parachutes loaded: " + pcs.getPresets().size());
|
||||
}
|
||||
return materialMap;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,12 +5,14 @@ import net.sf.openrocket.preset.ComponentPreset;
|
||||
import net.sf.openrocket.preset.ComponentPreset.Type;
|
||||
import net.sf.openrocket.preset.TypedPropertyMap;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class StreamerLoader extends BaseComponentLoader {
|
||||
|
||||
private final MaterialHolder materials;
|
||||
|
||||
public StreamerLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
|
||||
public StreamerLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
this.materials = materials;
|
||||
fileColumns.add(new SurfaceMaterialColumnParser(materials,"Material",ComponentPreset.MATERIAL));
|
||||
fileColumns.add(new DoubleUnitColumnParser("Length","Units",ComponentPreset.LENGTH));
|
||||
@ -34,13 +36,13 @@ public class StreamerLoader extends BaseComponentLoader {
|
||||
@Override
|
||||
protected void postProcess(TypedPropertyMap props) {
|
||||
super.postProcess(props);
|
||||
|
||||
|
||||
// Fix the material since some files use bulk materials for streamers.
|
||||
Double thickness = props.get( ComponentPreset.THICKNESS );
|
||||
Material.Surface material = (Material.Surface) props.get( ComponentPreset.MATERIAL );
|
||||
|
||||
|
||||
material = materials.getSurfaceMaterial(material, thickness);
|
||||
|
||||
|
||||
props.put(ComponentPreset.MATERIAL, material);
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
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 java.io.File;
|
||||
|
||||
public class TransitionLoader extends NoseConeLoader {
|
||||
|
||||
public TransitionLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public TransitionLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
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));
|
||||
|
@ -1,15 +1,14 @@
|
||||
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 java.io.File;
|
||||
|
||||
public class TubeCouplerLoader extends BodyTubeLoader {
|
||||
|
||||
public TubeCouplerLoader(MaterialHolder materials) {
|
||||
super(materials);
|
||||
public TubeCouplerLoader(MaterialHolder materials, File theBasePath) {
|
||||
super(materials, theBasePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
x
Reference in New Issue
Block a user