2 package net.sf.openrocket.preset.xml;
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;
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;
28 * Base class for the external representation of all component presets.
30 @XmlAccessorType(XmlAccessType.FIELD)
31 public abstract class BaseComponentDTO {
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;
46 @XmlJavaTypeAdapter(Base64Adapter.class)
47 @XmlElement(name = "Thumbnail")
51 * Default constructor.
53 protected BaseComponentDTO() {
59 * @param preset the preset to use to pull data values out of
61 * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset
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));
69 if ( preset.has(ComponentPreset.MATERIAL)) {
70 setMaterial(new AnnotatedMaterialDTO(preset.get(ComponentPreset.MATERIAL)));
72 if (preset.has(ComponentPreset.MASS)) {
73 setMass(preset.get(ComponentPreset.MASS));
75 if ( preset.has(ComponentPreset.FILLED) ) {
76 setFilled( preset.get(ComponentPreset.FILLED));
78 if (preset.has(ComponentPreset.IMAGE) ) {
79 setImageData(preset.get(ComponentPreset.IMAGE));
83 public String getManufacturer() {
87 public void setManufacturer(final String theManufacturer) {
88 manufacturer = theManufacturer;
91 public String getPartNo() {
95 public void setPartNo(final String thePartNo) {
99 public String getDescription() {
103 public void setDescription(final String theDescription) {
104 description = theDescription;
107 public AnnotatedMaterialDTO getMaterial() {
111 public void setMaterial(final AnnotatedMaterialDTO theMaterial) {
112 material = theMaterial;
115 public double getMass() {
116 return mass.getValue();
119 public void setMass(final AnnotatedMassDTO theMass) {
123 public void setMass(final double theMass) {
124 mass = new AnnotatedMassDTO(theMass);
127 public Boolean getFilled() {
131 public void setFilled(Boolean filled) {
132 this.filled = filled;
135 public byte[] getImageData() {
139 public void setImageData(final byte[] theImage) {
143 public BufferedImage getImage() throws IOException {
145 return ImageIO.read(new ByteArrayInputStream(image));
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();
158 public abstract ComponentPreset asComponentPreset(List<MaterialDTO> materials) throws InvalidComponentPresetException;
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);
166 Material m = find(materialList, material);
168 props.put(ComponentPreset.MATERIAL, find(materialList, material));
170 if ( mass != null ) {
171 props.put(ComponentPreset.MASS, getMass());
173 if ( filled != null ) {
174 props.put(ComponentPreset.FILLED, getFilled());
177 props.put(ComponentPreset.IMAGE, image);
181 protected Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) {
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();
192 // Don't have one, build one.
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);
206 static class AnnotatedMaterialDTO {
207 @XmlAttribute(name = "Type")
210 private String material;
212 AnnotatedMaterialDTO() {}
214 AnnotatedMaterialDTO(Material theMaterial) {
215 type = theMaterial.getType().name();
216 material = theMaterial.getName();
220 static class AnnotatedLengthDTO {
221 @XmlAttribute(name="Unit", required=false)
222 private String unitName = "m";
224 private double length;
226 AnnotatedLengthDTO() {}
228 AnnotatedLengthDTO( double length ) {
229 this.length = length;
232 public double getValue() {
233 return UnitGroup.UNITS_LENGTH.getUnit(unitName).fromUnit(length);
237 static class AnnotatedMassDTO {
238 @XmlAttribute(name="Unit", required=false)
239 private String unitName = "kg";
243 AnnotatedMassDTO() {}
245 AnnotatedMassDTO( double mass ) {
249 public double getValue() {
250 return UnitGroup.UNITS_MASS.getUnit(unitName).fromUnit(mass);
254 static class Base64Adapter extends XmlAdapter<String, byte[]> {
255 public byte[] unmarshal(String s) {
259 return DatatypeConverter.parseBase64Binary(s);
262 public String marshal(byte[] bytes) {
266 return DatatypeConverter.printBase64Binary(bytes);