Initial XML generating code for .orc format.
authorrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Mon, 23 Apr 2012 14:26:05 +0000 (14:26 +0000)
committerrodinia814 <rodinia814@180e2498-e6e9-4542-8430-84ac67f01cd8>
Mon, 23 Apr 2012 14:26:05 +0000 (14:26 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@588 180e2498-e6e9-4542-8430-84ac67f01cd8

14 files changed:
core/src/net/sf/openrocket/preset/loader/RocksimComponentFileLoader.java
core/src/net/sf/openrocket/preset/xml/BaseComponentDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/BodyTubeDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/BulkHeadDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/CenteringRingDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/EngineBlockDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/MaterialDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/MaterialTypeDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/NoseConeDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/ShapeDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/TransitionDTO.java [new file with mode: 0644]
core/src/net/sf/openrocket/preset/xml/TubeCouplerDTO.java [new file with mode: 0644]

index 73075c46344169155988116e976684688f9506a9..b1e15649067b1013ddd848e72b087c04c49d4f72 100644 (file)
@@ -12,6 +12,7 @@ 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;
@@ -25,7 +26,6 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -50,7 +50,7 @@ public class RocksimComponentFileLoader {
      *         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("/performancerocketry/" + type.getDefaultFileName()));
+        return load(RocksimComponentFileLoader.class.getResourceAsStream("/giantleaprocketry/" + type.getDefaultFileName()));
     }
 
     /**
@@ -571,7 +571,7 @@ public class RocksimComponentFileLoader {
         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);
@@ -600,6 +600,18 @@ public class RocksimComponentFileLoader {
             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);
     }
 }
 
diff --git a/core/src/net/sf/openrocket/preset/xml/BaseComponentDTO.java b/core/src/net/sf/openrocket/preset/xml/BaseComponentDTO.java
new file mode 100644 (file)
index 0000000..c437ed4
--- /dev/null
@@ -0,0 +1,89 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Base class for the external representation of all component presets.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+public abstract class BaseComponentDTO {
+
+    @XmlElement(name = "Manufacturer")
+    private String manufacturer;
+    @XmlElement(name = "PartNumber")
+    private String partNo;
+    @XmlElement(name = "Description")
+    private String description;
+    @XmlElement(name = "Material")
+    private String material;
+    @XmlElement(name = "Mass")
+    private double mass;
+
+    /**
+     * Default constructor.
+     */
+    protected BaseComponentDTO() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param preset  the preset to use to pull data values out of
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset
+     */
+    protected BaseComponentDTO(final ComponentPreset preset) {
+        setManufacturer(preset.getManufacturer().getSimpleName());
+        setPartNo(preset.getPartNo());
+        setDescription(preset.get(ComponentPreset.DESCRIPTION));
+        setMaterial(preset.get(ComponentPreset.MATERIAL).getName());
+        if (preset.has(ComponentPreset.MASS)) {
+            setMass(preset.get(ComponentPreset.MASS));
+        }
+    }
+
+    public String getManufacturer() {
+        return manufacturer;
+    }
+
+    public void setManufacturer(final String theManufacturer) {
+        manufacturer = theManufacturer;
+    }
+
+    public String getPartNo() {
+        return partNo;
+    }
+
+    public void setPartNo(final String thePartNo) {
+        partNo = thePartNo;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(final String theDescription) {
+        description = theDescription;
+    }
+
+    public String getMaterial() {
+        return material;
+    }
+
+    public void setMaterial(final String theMaterial) {
+        material = theMaterial;
+    }
+
+    public double getMass() {
+        return mass;
+    }
+
+    public void setMass(final double theMass) {
+        mass = theMass;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/BodyTubeDTO.java b/core/src/net/sf/openrocket/preset/xml/BodyTubeDTO.java
new file mode 100644 (file)
index 0000000..5fb8992
--- /dev/null
@@ -0,0 +1,68 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Body tube preset XML handler.
+ */
+@XmlRootElement(name = "BodyTube")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class BodyTubeDTO extends BaseComponentDTO {
+
+    @XmlElement(name = "InsideDiameter")
+    private double insideDiameter;
+    @XmlElement(name = "OutsideDiameter")
+    private double outsideDiameter;
+    @XmlElement(name = "Length")
+    private double length;
+
+    /**
+     * Default constructor.
+     */
+    public BodyTubeDTO() {
+    }
+
+    /**
+     * Most-useful constructor that maps a BodyTube preset to a BodyTubeDTO.
+     *
+     * @param preset  the preset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset
+     */
+    public BodyTubeDTO(final ComponentPreset preset) {
+        super(preset);
+        setInsideDiameter(preset.get(ComponentPreset.INNER_DIAMETER));
+        setOutsideDiameter(preset.get(ComponentPreset.OUTER_DIAMETER));
+        setLength(preset.get(ComponentPreset.LENGTH));
+    }
+
+    public double getInsideDiameter() {
+        return insideDiameter;
+    }
+
+    public void setInsideDiameter(final double theId) {
+        insideDiameter = theId;
+    }
+
+    public double getOutsideDiameter() {
+        return outsideDiameter;
+    }
+
+    public void setOutsideDiameter(final double theOd) {
+        outsideDiameter = theOd;
+    }
+
+    public double getLength() {
+        return length;
+    }
+
+    public void setLength(final double theLength) {
+        length = theLength;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/BulkHeadDTO.java b/core/src/net/sf/openrocket/preset/xml/BulkHeadDTO.java
new file mode 100644 (file)
index 0000000..a378c74
--- /dev/null
@@ -0,0 +1,54 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Bulkhead preset XML handler.
+ */
+@XmlRootElement(name = "BulkHead")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class BulkHeadDTO extends BaseComponentDTO {
+
+    @XmlElement(name = "OutsideDiameter")
+    private double outsideDiameter;
+    @XmlElement(name = "Length")
+    private double length;
+
+    public BulkHeadDTO() {
+    }
+
+    /**
+     * Most-useful constructor that maps a BulkHead preset to a BulkHeadDTO.
+     *
+     * @param thePreset  the preset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected bulk head keys are not in the preset
+     */
+    public BulkHeadDTO(final ComponentPreset thePreset) {
+        super(thePreset);
+        setOutsideDiameter(thePreset.get(ComponentPreset.OUTER_DIAMETER));
+        setLength(thePreset.get(ComponentPreset.LENGTH));
+    }
+
+    public double getOutsideDiameter() {
+        return outsideDiameter;
+    }
+
+    public void setOutsideDiameter(final double theOutsideDiameter) {
+        outsideDiameter = theOutsideDiameter;
+    }
+
+    public double getLength() {
+        return length;
+    }
+
+    public void setLength(final double theLength) {
+        length = theLength;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/CenteringRingDTO.java b/core/src/net/sf/openrocket/preset/xml/CenteringRingDTO.java
new file mode 100644 (file)
index 0000000..3f217b5
--- /dev/null
@@ -0,0 +1,68 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Centering ring preset XML handler.
+ */
+@XmlRootElement(name = "CenteringRing")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CenteringRingDTO extends BaseComponentDTO {
+
+    @XmlElement(name = "InsideDiameter")
+    private double insideDiameter;
+    @XmlElement(name = "OutsideDiameter")
+    private double outsideDiameter;
+    @XmlElement(name = "Length")
+    private double length;
+
+    /**
+     * Default constructor.
+     */
+    public CenteringRingDTO() {
+    }
+
+    /**
+     * Most-useful constructor that maps a CenteringRing preset to a CenteringRingDTO.
+     *
+     * @param thePreset  the preset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected centering ring keys are not in the preset
+     */
+    public CenteringRingDTO(final ComponentPreset thePreset) {
+        super(thePreset);
+        setInsideDiameter(thePreset.get(ComponentPreset.INNER_DIAMETER));
+        setOutsideDiameter(thePreset.get(ComponentPreset.OUTER_DIAMETER));
+        setLength(thePreset.get(ComponentPreset.LENGTH));
+    }
+
+    public double getInsideDiameter() {
+        return insideDiameter;
+    }
+
+    public void setInsideDiameter(final double theInsideDiameter) {
+        insideDiameter = theInsideDiameter;
+    }
+
+    public double getOutsideDiameter() {
+        return outsideDiameter;
+    }
+
+    public void setOutsideDiameter(final double theOutsideDiameter) {
+        outsideDiameter = theOutsideDiameter;
+    }
+
+    public double getLength() {
+        return length;
+    }
+
+    public void setLength(final double theLength) {
+        length = theLength;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/EngineBlockDTO.java b/core/src/net/sf/openrocket/preset/xml/EngineBlockDTO.java
new file mode 100644 (file)
index 0000000..4736d31
--- /dev/null
@@ -0,0 +1,34 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Engine block preset XML handler.
+ */
+@XmlRootElement(name = "EngineBlock")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class EngineBlockDTO extends CenteringRingDTO {
+
+    /**
+     * Default constructor.
+     */
+    public EngineBlockDTO() {
+    }
+
+    /**
+     * Most-useful constructor that maps a EngineBlock preset to a EngineBlockDTO.
+     *
+     * @param thePreset  the preset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected engine block keys are not in the preset
+     */
+    public EngineBlockDTO(ComponentPreset thePreset) {
+        super(thePreset);
+    }
+
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/MaterialDTO.java b/core/src/net/sf/openrocket/preset/xml/MaterialDTO.java
new file mode 100644 (file)
index 0000000..9fe1781
--- /dev/null
@@ -0,0 +1,77 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.material.Material;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * XML handler for materials.
+ */
+@XmlRootElement(name = "Material")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class MaterialDTO {
+
+    @XmlElement(name = "Name")
+    private String name;
+    @XmlElement(name = "Density")
+    private double density;
+    @XmlElement(name = "Type")
+    private MaterialTypeDTO type;
+    @XmlAttribute(name = "UnitsOfMeasure")
+    private String uom;
+
+    /**
+     * Default constructor.
+     */
+    public MaterialDTO() {
+    }
+
+    public MaterialDTO(final Material theMaterial) {
+        this(theMaterial.getName(), theMaterial.getDensity(), MaterialTypeDTO.asDTO(theMaterial.getType()),
+                theMaterial.getType().getUnitGroup().getDefaultUnit().toString());
+    }
+
+    public MaterialDTO(final String theName, final double theDensity, final MaterialTypeDTO theType, final String theUom) {
+        name = theName;
+        density = theDensity;
+        type = theType;
+        uom = theUom;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String theName) {
+        name = theName;
+    }
+
+    public double getDensity() {
+        return density;
+    }
+
+    public void setDensity(final double theDensity) {
+        density = theDensity;
+    }
+
+    public MaterialTypeDTO getType() {
+        return type;
+    }
+
+    public void setType(final MaterialTypeDTO theType) {
+        type = theType;
+    }
+
+    public String getUom() {
+        return uom;
+    }
+
+    public void setUom(final String theUom) {
+        uom = theUom;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/MaterialTypeDTO.java b/core/src/net/sf/openrocket/preset/xml/MaterialTypeDTO.java
new file mode 100644 (file)
index 0000000..a75092b
--- /dev/null
@@ -0,0 +1,32 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.material.Material;
+
+/**
+ * A mirror enum of Material.Type, for the purposes of mapping to/from an XML representation.
+ */
+public enum MaterialTypeDTO {
+
+    LINE (Material.Type.LINE),
+    SURFACE (Material.Type.SURFACE),
+    BULK (Material.Type.BULK);
+
+    private Material.Type corollary;
+
+    private MaterialTypeDTO(final Material.Type theCorollary) {
+        corollary = theCorollary;
+    }
+
+    public static MaterialTypeDTO asDTO(Material.Type targetType) {
+        MaterialTypeDTO[] values = values();
+        for (int i = 0; i < values.length; i++) {
+            MaterialTypeDTO value = values[i];
+            if (value.corollary.equals(targetType)) {
+                return value;
+            }
+        }
+        return BULK; //default
+    }
+
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/NoseConeDTO.java b/core/src/net/sf/openrocket/preset/xml/NoseConeDTO.java
new file mode 100644 (file)
index 0000000..ab35222
--- /dev/null
@@ -0,0 +1,78 @@
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A NoseCone preset XML handler.
+ */
+@XmlRootElement(name = "NoseCone")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class NoseConeDTO extends BaseComponentDTO {
+
+    @XmlElement(name = "Shape")
+    private ShapeDTO shape;
+    @XmlElement(name = "OutsideDiameter")
+    private double outsideDiameter;
+    @XmlElement(name = "ShoulderDiameter")
+    private double shoulderDiameter;
+    @XmlElement(name = "Length")
+    private double length;
+
+    /**
+     * Default constructor.
+     */
+    public NoseConeDTO() {
+    }
+
+    /**
+     * Constructor that
+     *
+     * @param thePreset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset
+     */
+    public NoseConeDTO(final ComponentPreset thePreset) {
+        super(thePreset);
+        setShape(ShapeDTO.asDTO(thePreset.get(ComponentPreset.SHAPE)));
+        setOutsideDiameter(thePreset.get(ComponentPreset.AFT_OUTER_DIAMETER));
+        setShoulderDiameter(thePreset.get(ComponentPreset.AFT_SHOULDER_DIAMETER));
+        setLength(thePreset.get(ComponentPreset.LENGTH));
+    }
+
+    public ShapeDTO getShape() {
+        return shape;
+    }
+
+    public void setShape(final ShapeDTO theShape) {
+        shape = theShape;
+    }
+
+    public double getOutsideDiameter() {
+        return outsideDiameter;
+    }
+
+    public void setOutsideDiameter(final double theOutsideDiameter) {
+        outsideDiameter = theOutsideDiameter;
+    }
+
+    public double getShoulderDiameter() {
+        return shoulderDiameter;
+    }
+
+    public void setShoulderDiameter(final double theShoulderDiameter) {
+        shoulderDiameter = theShoulderDiameter;
+    }
+
+    public double getLength() {
+        return length;
+    }
+
+    public void setLength(final double theLength) {
+        length = theLength;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java b/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentDTO.java
new file mode 100644 (file)
index 0000000..6f097c5
--- /dev/null
@@ -0,0 +1,69 @@
+package net.sf.openrocket.preset.xml;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementRef;
+import javax.xml.bind.annotation.XmlElementRefs;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The real 'root' element in an XML document.
+ */
+@XmlRootElement(name = "OpenRocketComponent")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class OpenRocketComponentDTO {
+
+    @XmlElement(name = "Version")
+    private final String version = "0.1";
+
+    @XmlElementWrapper(name = "Materials")
+            @XmlElement(name = "Material")
+    List<MaterialDTO> materials = new ArrayList<MaterialDTO>();
+
+    @XmlElementWrapper(name = "Components")
+    @XmlElementRefs({
+            @XmlElementRef(name = "BodyTubes", type = BodyTubeDTO.class),
+            @XmlElementRef(name = "TubeCouplers", type = TubeCouplerDTO.class),
+            @XmlElementRef(name = "NoseCones", type = NoseConeDTO.class),
+            @XmlElementRef(name = "Transitions", type = TransitionDTO.class),
+            @XmlElementRef(name = "BulkHeads", type = BulkHeadDTO.class),
+            @XmlElementRef(name = "CenteringRings", type = CenteringRingDTO.class),
+            @XmlElementRef(name = "EngineBlocks", type = EngineBlockDTO.class)})
+    private List<BaseComponentDTO> components = new ArrayList<BaseComponentDTO>();
+
+    public OpenRocketComponentDTO() {
+    }
+
+    public OpenRocketComponentDTO(final List<MaterialDTO> theMaterials, final List<BaseComponentDTO> theComponents) {
+        materials = theMaterials;
+        components = theComponents;
+    }
+
+    public List<MaterialDTO> getMaterials() {
+        return materials;
+    }
+
+    public void addMaterial(final MaterialDTO theMaterial) {
+        materials.add(theMaterial);
+    }
+
+    public void setMaterials(final List<MaterialDTO> theMaterials) {
+        materials = theMaterials;
+    }
+
+    public List<BaseComponentDTO> getComponents() {
+        return components;
+    }
+
+    public void addComponent(final BaseComponentDTO theComponent) {
+        components.add(theComponent);
+    }
+
+    public void setComponents(final List<BaseComponentDTO> theComponents) {
+        components = theComponents;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java b/core/src/net/sf/openrocket/preset/xml/OpenRocketComponentSaver.java
new file mode 100644 (file)
index 0000000..bb35ce7
--- /dev/null
@@ -0,0 +1,121 @@
+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.startup.Application;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.util.List;
+
+/**
+ * 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) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/ShapeDTO.java b/core/src/net/sf/openrocket/preset/xml/ShapeDTO.java
new file mode 100644 (file)
index 0000000..7cdb1e3
--- /dev/null
@@ -0,0 +1,37 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.rocketcomponent.Transition;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+/**
+ * A mirror class to Transition.Shape to adapt that class to/from XML.
+ */
+@XmlEnum(String.class)
+public enum ShapeDTO {
+
+    CONICAL (Transition.Shape.CONICAL),
+    OGIVE   (Transition.Shape.OGIVE),
+    ELLIPSOID (Transition.Shape.ELLIPSOID),
+    POWER (Transition.Shape.POWER),
+    PARABOLIC (Transition.Shape.PARABOLIC),
+    HAACK (Transition.Shape.HAACK);
+
+    private Transition.Shape corollary;
+
+    private ShapeDTO(Transition.Shape theShape) {
+        corollary = theShape;
+    }
+
+    public static ShapeDTO asDTO(Transition.Shape targetShape) {
+        ShapeDTO[] values = values();
+        for (int i = 0; i < values.length; i++) {
+            ShapeDTO value = values[i];
+            if (value.corollary.equals(targetShape)) {
+                return value;
+            }
+        }
+        return ELLIPSOID; //default
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/TransitionDTO.java b/core/src/net/sf/openrocket/preset/xml/TransitionDTO.java
new file mode 100644 (file)
index 0000000..91c62ed
--- /dev/null
@@ -0,0 +1,127 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Transition preset XML handler.
+ */
+@XmlRootElement(name = "Transition")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class TransitionDTO extends BaseComponentDTO {
+
+    @XmlElement(name = "Shape")
+    private ShapeDTO shape;
+
+    @XmlElement(name = "ForeOutsideDiameter")
+    private double foreOutsideDiameter;
+    @XmlElement(name = "ForeShoulderDiameter")
+    private double foreShoulderDiameter;
+    @XmlElement(name = "ForeShoulderLength")
+    private double foreShoulderLength;
+
+    @XmlElement(name = "AftOutsideDiameter")
+    private double aftOutsideDiameter;
+    @XmlElement(name = "AftShoulderDiameter")
+    private double aftShoulderDiameter;
+    @XmlElement(name = "AftShoulderLength")
+    private double aftShoulderLength;
+
+    @XmlElement(name = "Length")
+    private double length;
+
+
+    /**
+     * Default constructor.
+     */
+    public TransitionDTO() {
+    }
+
+    /**
+     * Most-useful constructor that maps a Transition preset to a TransitionDTO.
+     *
+     * @param thePreset  the preset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected transition keys are not in the preset
+     */
+    public TransitionDTO(final ComponentPreset thePreset) {
+        super(thePreset);
+        setShape(ShapeDTO.asDTO(thePreset.get(ComponentPreset.SHAPE)));
+        setForeOutsideDiameter(thePreset.get(ComponentPreset.FORE_OUTER_DIAMETER));
+        setForeShoulderDiameter(thePreset.get(ComponentPreset.FORE_SHOULDER_DIAMETER));
+        setForeShoulderLength(thePreset.get(ComponentPreset.FORE_SHOULDER_LENGTH));
+        setAftOutsideDiameter(thePreset.get(ComponentPreset.AFT_OUTER_DIAMETER));
+        setAftShoulderDiameter(thePreset.get(ComponentPreset.AFT_SHOULDER_DIAMETER));
+        setAftShoulderLength(thePreset.get(ComponentPreset.AFT_SHOULDER_LENGTH));
+        setLength(thePreset.get(ComponentPreset.LENGTH));
+    }
+
+    public ShapeDTO getShape() {
+        return shape;
+    }
+
+    public void setShape(final ShapeDTO theShape) {
+        shape = theShape;
+    }
+
+    public double getForeOutsideDiameter() {
+        return foreOutsideDiameter;
+    }
+
+    public void setForeOutsideDiameter(final double theForeOutsideDiameter) {
+        foreOutsideDiameter = theForeOutsideDiameter;
+    }
+
+    public double getForeShoulderDiameter() {
+        return foreShoulderDiameter;
+    }
+
+    public void setForeShoulderDiameter(final double theForeShoulderDiameter) {
+        foreShoulderDiameter = theForeShoulderDiameter;
+    }
+
+    public double getForeShoulderLength() {
+        return foreShoulderLength;
+    }
+
+    public void setForeShoulderLength(final double theForeShoulderLength) {
+        foreShoulderLength = theForeShoulderLength;
+    }
+
+    public double getAftOutsideDiameter() {
+        return aftOutsideDiameter;
+    }
+
+    public void setAftOutsideDiameter(final double theAftOutsideDiameter) {
+        aftOutsideDiameter = theAftOutsideDiameter;
+    }
+
+    public double getAftShoulderDiameter() {
+        return aftShoulderDiameter;
+    }
+
+    public void setAftShoulderDiameter(final double theAftShoulderDiameter) {
+        aftShoulderDiameter = theAftShoulderDiameter;
+    }
+
+    public double getAftShoulderLength() {
+        return aftShoulderLength;
+    }
+
+    public void setAftShoulderLength(final double theAftShoulderLength) {
+        aftShoulderLength = theAftShoulderLength;
+    }
+
+    public double getLength() {
+        return length;
+    }
+
+    public void setLength(final double theLength) {
+        length = theLength;
+    }
+}
diff --git a/core/src/net/sf/openrocket/preset/xml/TubeCouplerDTO.java b/core/src/net/sf/openrocket/preset/xml/TubeCouplerDTO.java
new file mode 100644 (file)
index 0000000..1e87dc1
--- /dev/null
@@ -0,0 +1,33 @@
+
+package net.sf.openrocket.preset.xml;
+
+import net.sf.openrocket.preset.ComponentPreset;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Tube coupler preset XML handler.
+ */
+@XmlRootElement(name = "TubeCoupler")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class TubeCouplerDTO extends BodyTubeDTO {
+
+    /**
+     * Default constructor.
+     */
+    public TubeCouplerDTO() {
+    }
+
+    /**
+     * Most-useful constructor that maps a TubeCoupler preset to a TubeCouplerDTO.
+     *
+     * @param thePreset  the preset
+     *
+     * @throws net.sf.openrocket.util.BugException thrown if the expected tube coupler keys are not in the preset
+     */
+    public TubeCouplerDTO(ComponentPreset thePreset) {
+        super(thePreset);
+    }
+}