Initial GUI for editing and saving component presets. See ComponentPresetPanel.main...
[debian/openrocket] / core / src / net / sf / openrocket / preset / xml / BaseComponentDTO.java
1
2 package net.sf.openrocket.preset.xml;
3
4 import net.sf.openrocket.material.Material;
5 import net.sf.openrocket.motor.Manufacturer;
6 import net.sf.openrocket.preset.ComponentPreset;
7 import net.sf.openrocket.preset.InvalidComponentPresetException;
8 import net.sf.openrocket.preset.TypedPropertyMap;
9 import net.sf.openrocket.unit.UnitGroup;
10
11 import javax.imageio.ImageIO;
12 import javax.xml.bind.DatatypeConverter;
13 import javax.xml.bind.annotation.XmlAccessType;
14 import javax.xml.bind.annotation.XmlAccessorType;
15 import javax.xml.bind.annotation.XmlAttribute;
16 import javax.xml.bind.annotation.XmlElement;
17 import javax.xml.bind.annotation.XmlInlineBinaryData;
18 import javax.xml.bind.annotation.XmlValue;
19 import javax.xml.bind.annotation.adapters.XmlAdapter;
20 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
21 import java.awt.image.BufferedImage;
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.util.List;
26
27 /**
28  * Base class for the external representation of all component presets.
29  */
30 @XmlAccessorType(XmlAccessType.FIELD)
31 public abstract class BaseComponentDTO {
32
33         @XmlElement(name = "Manufacturer")
34         private String manufacturer;
35         @XmlElement(name = "PartNumber")
36         private String partNo;
37         @XmlElement(name = "Description")
38         private String description;
39         @XmlElement(name = "Material")
40         private AnnotatedMaterialDTO material;
41         @XmlElement(name = "Mass")
42         private AnnotatedMassDTO mass;
43         @XmlElement(name="Filled")
44         private Boolean filled;
45     @XmlInlineBinaryData
46     @XmlJavaTypeAdapter(Base64Adapter.class)
47     @XmlElement(name = "Thumbnail")
48     private byte[] image;
49
50         /**
51          * Default constructor.
52          */
53         protected BaseComponentDTO() {
54         }
55
56         /**
57          * Constructor.
58          *
59          * @param preset  the preset to use to pull data values out of
60          *
61          * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset
62          */
63         protected BaseComponentDTO(final ComponentPreset preset) {
64                 setManufacturer(preset.getManufacturer().getSimpleName());
65                 setPartNo(preset.getPartNo());
66                 if ( preset.has(ComponentPreset.DESCRIPTION )) {
67                         setDescription(preset.get(ComponentPreset.DESCRIPTION));
68                 }
69                 if ( preset.has(ComponentPreset.MATERIAL)) {
70                         setMaterial(new AnnotatedMaterialDTO(preset.get(ComponentPreset.MATERIAL)));
71                 }
72                 if (preset.has(ComponentPreset.MASS)) {
73                         setMass(preset.get(ComponentPreset.MASS));
74                 }
75                 if ( preset.has(ComponentPreset.FILLED) ) {
76                         setFilled( preset.get(ComponentPreset.FILLED));
77                 }
78         if (preset.has(ComponentPreset.IMAGE) ) {
79             setImageData(preset.get(ComponentPreset.IMAGE));
80         }
81         }
82
83         public String getManufacturer() {
84                 return manufacturer;
85         }
86
87         public void setManufacturer(final String theManufacturer) {
88                 manufacturer = theManufacturer;
89         }
90
91         public String getPartNo() {
92                 return partNo;
93         }
94
95         public void setPartNo(final String thePartNo) {
96                 partNo = thePartNo;
97         }
98
99         public String getDescription() {
100                 return description;
101         }
102
103         public void setDescription(final String theDescription) {
104                 description = theDescription;
105         }
106
107         public AnnotatedMaterialDTO getMaterial() {
108                 return material;
109         }
110
111         public void setMaterial(final AnnotatedMaterialDTO theMaterial) {
112                 material = theMaterial;
113         }
114
115         public double getMass() {
116                 return mass.getValue();
117         }
118
119         public void setMass(final AnnotatedMassDTO theMass) {
120                 mass = theMass;
121         }
122
123         public void setMass(final double theMass) {
124                 mass = new AnnotatedMassDTO(theMass);
125         }
126
127         public Boolean getFilled() {
128                 return filled;
129         }
130
131         public void setFilled(Boolean filled) {
132                 this.filled = filled;
133         }
134
135     public byte[] getImageData() {
136         return image;
137     }
138
139     public void setImageData(final byte[] theImage) {
140         image = theImage;
141     }
142
143     public BufferedImage getImage() throws IOException {
144         if (image != null) {
145             return ImageIO.read(new ByteArrayInputStream(image));
146         }
147         return null;
148     }
149
150     public void setImage(BufferedImage theImage) throws IOException {
151         if (theImage != null) {
152             final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
153             ImageIO.write(theImage, "png", byteArrayOutputStream);
154             image = byteArrayOutputStream.toByteArray();
155         }
156     }
157
158     public abstract ComponentPreset asComponentPreset(List<MaterialDTO> materials) throws InvalidComponentPresetException;
159
160         void addProps(TypedPropertyMap props, List<MaterialDTO> materialList) {
161                 props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(manufacturer));
162                 props.put(ComponentPreset.PARTNO, partNo);
163                 if ( description != null ) {
164                         props.put(ComponentPreset.DESCRIPTION, description);
165                 }
166                 Material m = find(materialList, material);
167                 if ( m != null ) {
168                         props.put(ComponentPreset.MATERIAL, find(materialList, material));
169                 }
170                 if ( mass != null ) {
171                         props.put(ComponentPreset.MASS, getMass());
172                 }
173                 if ( filled != null ) {
174                         props.put(ComponentPreset.FILLED, getFilled());
175                 }
176         if (image != null) {
177             props.put(ComponentPreset.IMAGE, image);
178         }
179         }
180
181         protected Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) {
182                 if ( dto == null ) {
183                         return null;
184                 }
185                 for (int i = 0; i < materialList.size(); i++) {
186                         MaterialDTO materialDTO =  materialList.get(i);
187                         if (materialDTO.getType().name().equals(dto.type) && materialDTO.getName().equals(dto.material)) {
188                                 return materialDTO.asMaterial();
189                         }
190                 }
191
192                 // Don't have one, build one.
193
194                 if ( "BULK".equals( dto.type ) ) {
195                         return new Material.Bulk(dto.material, 0.0, true);
196                 } else if ( "SURFACE".equals( dto.type ) ) {
197                         return new Material.Surface(dto.material, 0.0, true);
198                 } else if ( "LINE".equals( dto.type ) ) {
199                         return new Material.Line(dto.material, 0.0, true);
200                 } else {
201                         return null;
202                 }
203
204         }
205
206         static class AnnotatedMaterialDTO {
207                 @XmlAttribute(name = "Type")
208                 private String type;
209                 @XmlValue
210                 private String material;
211
212                 AnnotatedMaterialDTO() {}
213
214                 AnnotatedMaterialDTO(Material theMaterial) {
215                         type = theMaterial.getType().name();
216                         material = theMaterial.getName();
217                 }
218         }
219
220         static class AnnotatedLengthDTO {
221                 @XmlAttribute(name="Unit", required=false)
222                 private String unitName = "m";
223                 @XmlValue
224                 private double length;
225
226                 AnnotatedLengthDTO() {}
227
228                 AnnotatedLengthDTO( double length ) {
229                         this.length = length;
230                 }
231
232                 public double getValue() {
233                         return UnitGroup.UNITS_LENGTH.getUnit(unitName).fromUnit(length);
234                 }
235         }
236
237         static class AnnotatedMassDTO {
238                 @XmlAttribute(name="Unit", required=false)
239                 private String unitName = "kg";
240                 @XmlValue
241                 private double mass;
242
243                 AnnotatedMassDTO() {}
244
245                 AnnotatedMassDTO( double mass ) {
246                         this.mass = mass;
247                 }
248
249                 public double getValue() {
250                         return UnitGroup.UNITS_MASS.getUnit(unitName).fromUnit(mass);
251                 }
252         }
253
254     static class Base64Adapter extends XmlAdapter<String, byte[]> {
255         public byte[] unmarshal(String s) {
256             if (s == null) {
257                 return null;
258             }
259             return DatatypeConverter.parseBase64Binary(s);
260         }
261
262         public String marshal(byte[] bytes) {
263             if (bytes == null) {
264                 return null;
265             }
266             return DatatypeConverter.printBase64Binary(bytes);
267         }
268     }
269 }