create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / file / rocksim / importt / ParachuteHandler.java
1 /*
2  * ParachuteHandler.java
3  */
4 package net.sf.openrocket.file.rocksim.importt;
5
6 import net.sf.openrocket.aerodynamics.WarningSet;
7 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
8 import net.sf.openrocket.file.simplesax.ElementHandler;
9 import net.sf.openrocket.file.simplesax.PlainTextHandler;
10 import net.sf.openrocket.material.Material;
11 import net.sf.openrocket.rocketcomponent.BodyTube;
12 import net.sf.openrocket.rocketcomponent.InnerTube;
13 import net.sf.openrocket.rocketcomponent.Parachute;
14 import net.sf.openrocket.rocketcomponent.RocketComponent;
15 import org.xml.sax.SAXException;
16
17 import java.util.HashMap;
18
19 /**
20  * A SAX handler for Rocksim's Parachute XML type.
21  */
22 class ParachuteHandler extends RecoveryDeviceHandler<Parachute> {
23     /**
24      * The OpenRocket Parachute instance
25      */
26     private final Parachute chute;
27     /**
28      * The shroud line density.
29      */
30     private double shroudLineDensity = 0.0d;
31
32     /**
33      * Constructor.
34      *
35      * @param c the parent component
36      * @param warnings  the warning set
37      * 
38      * @throws IllegalArgumentException thrown if <code>c</code> is null
39      */
40     public ParachuteHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
41         if (c == null) {
42             throw new IllegalArgumentException("The parent of a parachute may not be null.");
43         }
44         chute = new Parachute();
45         if (isCompatible(c, Parachute.class, warnings)) {
46             c.addChild(chute);
47         }
48     }
49
50     /**
51      * {@inheritDoc}
52      */
53     @Override
54     public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings) {
55         return PlainTextHandler.INSTANCE;
56     }
57
58     /**
59      * {@inheritDoc}
60      */
61     @Override
62     public void closeElement(String element, HashMap<String, String> attributes, String content, WarningSet warnings)
63             throws SAXException {
64         super.closeElement(element, attributes, content, warnings);
65         try {
66             if (RocksimCommonConstants.DIAMETER.equals(element)) {
67                 chute.setDiameter(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
68                 /* Rocksim doesn't have a packed parachute radius, so we approximate it. */
69                 double packed;
70                 RocketComponent parent = chute.getParent();
71                 if (parent instanceof BodyTube) {
72                     packed = ((BodyTube) parent).getOuterRadius() * 0.9;
73                 }
74                 else if (parent instanceof InnerTube) {
75                     packed = ((InnerTube) parent).getInnerRadius() * 0.9;
76                 }
77                 else {
78                     packed = chute.getDiameter() * 0.025;
79                 }
80                 chute.setRadius(packed);
81             }
82             if (RocksimCommonConstants.SHROUD_LINE_COUNT.equals(element)) {
83                 chute.setLineCount(Math.max(0, Integer.parseInt(content)));
84             }
85             if (RocksimCommonConstants.SHROUD_LINE_LEN.equals(element)) {
86                 chute.setLineLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH));
87             }
88             if (RocksimCommonConstants.SPILL_HOLE_DIA.equals(element)) {
89                 //Not supported in OpenRocket
90                 double spillHoleRadius = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS;
91                 warnings.add("Parachute spill holes are not supported. Ignoring.");
92             }
93             if (RocksimCommonConstants.SHROUD_LINE_MASS_PER_MM.equals(element)) {
94                 shroudLineDensity = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LINE_DENSITY;
95             }
96             if (RocksimCommonConstants.SHROUD_LINE_MATERIAL.equals(element)) {
97                 chute.setLineMaterial(createCustomMaterial(Material.Type.LINE, content, shroudLineDensity));
98             }
99             if (RocksimCommonConstants.DRAG_COEFFICIENT.equals(element)) {
100                 chute.setCD(Double.parseDouble(content));
101             }
102             if (RocksimCommonConstants.MATERIAL.equals(element)) {
103                 setMaterialName(content);
104             }
105         }
106         catch (NumberFormatException nfe) {
107             warnings.add("Could not convert " + element + " value of " + content + ".  It is expected to be a number.");
108         }
109     }
110
111     /**
112      * Get the component this handler is working upon.
113      *
114      * @return a component
115      */
116     public Parachute getComponent() {
117         return chute;
118     }
119
120 }
121