De-localize Material and FlightDataType objects when persisting in ork files. Added...
[debian/openrocket] / core / src / net / sf / openrocket / preset / xml / BaseComponentDTO.java
index d107abf5735109bb325a202c07de20c2221e50ab..b39bc23ec4245a2cb3cb07e3e1d9be36d58a903e 100644 (file)
@@ -1,14 +1,6 @@
 
 package net.sf.openrocket.preset.xml;
 
-import java.util.List;
-
-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.XmlValue;
-
 import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.motor.Manufacturer;
@@ -17,6 +9,22 @@ import net.sf.openrocket.preset.InvalidComponentPresetException;
 import net.sf.openrocket.preset.TypedPropertyMap;
 import net.sf.openrocket.unit.UnitGroup;
 
+import javax.imageio.ImageIO;
+import javax.xml.bind.DatatypeConverter;
+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.XmlInlineBinaryData;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+
 /**
  * Base class for the external representation of all component presets.
  */
@@ -35,6 +43,10 @@ public abstract class BaseComponentDTO {
        private AnnotatedMassDTO mass;
        @XmlElement(name="Filled")
        private Boolean filled;
+    @XmlInlineBinaryData
+    @XmlJavaTypeAdapter(Base64Adapter.class)
+    @XmlElement(name = "Thumbnail")
+    private byte[] image;
 
        /**
         * Default constructor.
@@ -64,6 +76,9 @@ public abstract class BaseComponentDTO {
                if ( preset.has(ComponentPreset.FILLED) ) {
                        setFilled( preset.get(ComponentPreset.FILLED));
                }
+        if (preset.has(ComponentPreset.IMAGE) ) {
+            setImageData(preset.get(ComponentPreset.IMAGE));
+        }
        }
 
        public String getManufacturer() {
@@ -118,7 +133,30 @@ public abstract class BaseComponentDTO {
                this.filled = filled;
        }
 
-       public abstract ComponentPreset asComponentPreset(List<MaterialDTO> materials) throws InvalidComponentPresetException;
+    public byte[] getImageData() {
+        return image;
+    }
+
+    public void setImageData(final byte[] theImage) {
+        image = theImage;
+    }
+
+    public BufferedImage getImage() throws IOException {
+        if (image != null) {
+            return ImageIO.read(new ByteArrayInputStream(image));
+        }
+        return null;
+    }
+
+    public void setImage(BufferedImage theImage) throws IOException {
+        if (theImage != null) {
+            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+            ImageIO.write(theImage, "png", byteArrayOutputStream);
+            image = byteArrayOutputStream.toByteArray();
+        }
+    }
+
+    public abstract ComponentPreset asComponentPreset(List<MaterialDTO> materials) throws InvalidComponentPresetException;
 
        void addProps(TypedPropertyMap props, List<MaterialDTO> materialList) {
                props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(manufacturer));
@@ -136,17 +174,30 @@ public abstract class BaseComponentDTO {
                if ( filled != null ) {
                        props.put(ComponentPreset.FILLED, getFilled());
                }
+        if (image != null) {
+            props.put(ComponentPreset.IMAGE, image);
+        }
        }
 
-       private Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) {
+       protected Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) {
+               if ( dto == null ) {
+                       return null;
+               }
                for (int i = 0; i < materialList.size(); i++) {
                        MaterialDTO materialDTO =  materialList.get(i);
                        if (materialDTO.getType().name().equals(dto.type) && materialDTO.getName().equals(dto.material)) {
                                return materialDTO.asMaterial();
                        }
                }
-               //Otherwise fallback and look at factory default materials.
-               return Databases.findMaterial(Material.Type.valueOf(material.type), material.material);
+
+               // Don't have one, first check OR's database
+        Material m = Databases.findMaterial(dto.getORMaterialType(), dto.material);
+        if ( m != null ) {
+               return m;
+        }
+
+        return Material.newUserMaterial(dto.getORMaterialType(), dto.material, 0.0);
+
        }
 
        static class AnnotatedMaterialDTO {
@@ -161,16 +212,27 @@ public abstract class BaseComponentDTO {
                        type = theMaterial.getType().name();
                        material = theMaterial.getName();
                }
+               
+               public Material.Type getORMaterialType() {
+                       if ( "BULK".equals(type) ) {
+                               return Material.Type.BULK;
+                       } else if ( "SURFACE".equals(type) ) {
+                               return Material.Type.SURFACE;
+                       } else if ( "LINE".equals(type) ) {
+                               return Material.Type.LINE;
+                       }
+                       throw new IllegalArgumentException( "Inavlid material type " + type +" specified for Component" );
+               }
        }
-       
+
        static class AnnotatedLengthDTO {
                @XmlAttribute(name="Unit", required=false)
                private String unitName = "m";
                @XmlValue
                private double length;
-               
+
                AnnotatedLengthDTO() {}
-               
+
                AnnotatedLengthDTO( double length ) {
                        this.length = length;
                }
@@ -179,21 +241,39 @@ public abstract class BaseComponentDTO {
                        return UnitGroup.UNITS_LENGTH.getUnit(unitName).fromUnit(length);
                }
        }
-       
+
        static class AnnotatedMassDTO {
                @XmlAttribute(name="Unit", required=false)
                private String unitName = "kg";
                @XmlValue
                private double mass;
-               
+
                AnnotatedMassDTO() {}
-               
+
                AnnotatedMassDTO( double mass ) {
                        this.mass = mass;
                }
-               
+
                public double getValue() {
                        return UnitGroup.UNITS_MASS.getUnit(unitName).fromUnit(mass);
                }
        }
+
+    static class Base64Adapter extends XmlAdapter<String, byte[]> {
+       @Override
+        public byte[] unmarshal(String s) {
+            if (s == null) {
+                return null;
+            }
+            return DatatypeConverter.parseBase64Binary(s);
+        }
+
+       @Override
+        public String marshal(byte[] bytes) {
+            if (bytes == null) {
+                return null;
+            }
+            return DatatypeConverter.printBase64Binary(bytes);
+        }
+    }
 }