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