2 package net.sf.openrocket.preset.xml;
4 import net.sf.openrocket.database.Databases;
5 import net.sf.openrocket.material.Material;
6 import net.sf.openrocket.motor.Manufacturer;
7 import net.sf.openrocket.preset.ComponentPreset;
8 import net.sf.openrocket.preset.InvalidComponentPresetException;
9 import net.sf.openrocket.preset.TypedPropertyMap;
10 import net.sf.openrocket.unit.UnitGroup;
12 import javax.imageio.ImageIO;
13 import javax.xml.bind.DatatypeConverter;
14 import javax.xml.bind.annotation.XmlAccessType;
15 import javax.xml.bind.annotation.XmlAccessorType;
16 import javax.xml.bind.annotation.XmlAttribute;
17 import javax.xml.bind.annotation.XmlElement;
18 import javax.xml.bind.annotation.XmlInlineBinaryData;
19 import javax.xml.bind.annotation.XmlValue;
20 import javax.xml.bind.annotation.adapters.XmlAdapter;
21 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
22 import java.awt.image.BufferedImage;
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.util.List;
29 * Base class for the external representation of all component presets.
31 @XmlAccessorType(XmlAccessType.FIELD)
32 public abstract class BaseComponentDTO {
34 @XmlElement(name = "Manufacturer")
35 private String manufacturer;
36 @XmlElement(name = "PartNumber")
37 private String partNo;
38 @XmlElement(name = "Description")
39 private String description;
40 @XmlElement(name = "Material")
41 private AnnotatedMaterialDTO material;
42 @XmlElement(name = "Mass")
43 private AnnotatedMassDTO mass;
44 @XmlElement(name="Filled")
45 private Boolean filled;
47 @XmlJavaTypeAdapter(Base64Adapter.class)
48 @XmlElement(name = "Thumbnail")
52 * Default constructor.
54 protected BaseComponentDTO() {
60 * @param preset the preset to use to pull data values out of
62 * @throws net.sf.openrocket.util.BugException thrown if the expected body tube keys are not in the preset
64 protected BaseComponentDTO(final ComponentPreset preset) {
65 setManufacturer(preset.getManufacturer().getSimpleName());
66 setPartNo(preset.getPartNo());
67 if ( preset.has(ComponentPreset.DESCRIPTION )) {
68 setDescription(preset.get(ComponentPreset.DESCRIPTION));
70 if ( preset.has(ComponentPreset.MATERIAL)) {
71 setMaterial(new AnnotatedMaterialDTO(preset.get(ComponentPreset.MATERIAL)));
73 if (preset.has(ComponentPreset.MASS)) {
74 setMass(preset.get(ComponentPreset.MASS));
76 if ( preset.has(ComponentPreset.FILLED) ) {
77 setFilled( preset.get(ComponentPreset.FILLED));
79 if (preset.has(ComponentPreset.IMAGE) ) {
80 setImageData(preset.get(ComponentPreset.IMAGE));
84 public String getManufacturer() {
88 public void setManufacturer(final String theManufacturer) {
89 manufacturer = theManufacturer;
92 public String getPartNo() {
96 public void setPartNo(final String thePartNo) {
100 public String getDescription() {
104 public void setDescription(final String theDescription) {
105 description = theDescription;
108 public AnnotatedMaterialDTO getMaterial() {
112 public void setMaterial(final AnnotatedMaterialDTO theMaterial) {
113 material = theMaterial;
116 public double getMass() {
117 return mass.getValue();
120 public void setMass(final AnnotatedMassDTO theMass) {
124 public void setMass(final double theMass) {
125 mass = new AnnotatedMassDTO(theMass);
128 public Boolean getFilled() {
132 public void setFilled(Boolean filled) {
133 this.filled = filled;
136 public byte[] getImageData() {
140 public void setImageData(final byte[] theImage) {
144 public BufferedImage getImage() throws IOException {
146 return ImageIO.read(new ByteArrayInputStream(image));
151 public void setImage(BufferedImage theImage) throws IOException {
152 if (theImage != null) {
153 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
154 ImageIO.write(theImage, "png", byteArrayOutputStream);
155 image = byteArrayOutputStream.toByteArray();
159 public abstract ComponentPreset asComponentPreset(List<MaterialDTO> materials) throws InvalidComponentPresetException;
161 void addProps(TypedPropertyMap props, List<MaterialDTO> materialList) {
162 props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(manufacturer));
163 props.put(ComponentPreset.PARTNO, partNo);
164 if ( description != null ) {
165 props.put(ComponentPreset.DESCRIPTION, description);
167 Material m = find(materialList, material);
169 props.put(ComponentPreset.MATERIAL, find(materialList, material));
171 if ( mass != null ) {
172 props.put(ComponentPreset.MASS, getMass());
174 if ( filled != null ) {
175 props.put(ComponentPreset.FILLED, getFilled());
178 props.put(ComponentPreset.IMAGE, image);
182 protected Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) {
186 for (int i = 0; i < materialList.size(); i++) {
187 MaterialDTO materialDTO = materialList.get(i);
188 if (materialDTO.getType().name().equals(dto.type) && materialDTO.getName().equals(dto.material)) {
189 return materialDTO.asMaterial();
193 // Don't have one, first check OR's database
194 Material m = Databases.findMaterial(dto.getORMaterialType(), dto.material);
199 switch( dto.getORMaterialType() ) {
201 return new Material.Bulk(dto.material, 0.0, true);
203 return new Material.Surface(dto.material, 0.0, true);
205 return new Material.Line(dto.material, 0.0, true);
212 static class AnnotatedMaterialDTO {
213 @XmlAttribute(name = "Type")
216 private String material;
218 AnnotatedMaterialDTO() {}
220 AnnotatedMaterialDTO(Material theMaterial) {
221 type = theMaterial.getType().name();
222 material = theMaterial.getName();
225 public Material.Type getORMaterialType() {
226 if ( "BULK".equals(type) ) {
227 return Material.Type.BULK;
228 } else if ( "SURFACE".equals(type) ) {
229 return Material.Type.SURFACE;
230 } else if ( "LINE".equals(type) ) {
231 return Material.Type.LINE;
233 throw new IllegalArgumentException( "Inavlid material type " + type +" specified for Component" );
237 static class AnnotatedLengthDTO {
238 @XmlAttribute(name="Unit", required=false)
239 private String unitName = "m";
241 private double length;
243 AnnotatedLengthDTO() {}
245 AnnotatedLengthDTO( double length ) {
246 this.length = length;
249 public double getValue() {
250 return UnitGroup.UNITS_LENGTH.getUnit(unitName).fromUnit(length);
254 static class AnnotatedMassDTO {
255 @XmlAttribute(name="Unit", required=false)
256 private String unitName = "kg";
260 AnnotatedMassDTO() {}
262 AnnotatedMassDTO( double mass ) {
266 public double getValue() {
267 return UnitGroup.UNITS_MASS.getUnit(unitName).fromUnit(mass);
271 static class Base64Adapter extends XmlAdapter<String, byte[]> {
272 public byte[] unmarshal(String s) {
276 return DatatypeConverter.parseBase64Binary(s);
279 public String marshal(byte[] bytes) {
283 return DatatypeConverter.printBase64Binary(bytes);