4 package net.sf.openrocket.file.rocksim.importt;
6 import net.sf.openrocket.aerodynamics.WarningSet;
7 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
8 import net.sf.openrocket.file.rocksim.RocksimFinishCode;
9 import net.sf.openrocket.file.rocksim.RocksimNoseConeCode;
10 import net.sf.openrocket.file.simplesax.ElementHandler;
11 import net.sf.openrocket.file.simplesax.PlainTextHandler;
12 import net.sf.openrocket.material.Material;
13 import net.sf.openrocket.rocketcomponent.NoseCone;
14 import net.sf.openrocket.rocketcomponent.RocketComponent;
15 import net.sf.openrocket.rocketcomponent.Transition;
16 import org.xml.sax.SAXException;
18 import java.util.HashMap;
21 * The SAX nose cone handler for Rocksim NoseCones.
23 class NoseConeHandler extends BaseHandler<NoseCone> {
26 * The OpenRocket NoseCone.
28 private final NoseCone noseCone = new NoseCone();
31 * The wall thickness. Used for hollow nose cones.
33 private double thickness = 0d;
38 * @param c the parent component to the nosecone
39 * @param warnings the warning set
41 * @throws IllegalArgumentException thrown if <code>c</code> is null
43 public NoseConeHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException {
45 throw new IllegalArgumentException("The parent component of a nose cone may not be null.");
47 if (isCompatible(c, NoseCone.class, warnings)) {
49 noseCone.setAftRadiusAutomatic(false);
54 public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings) {
55 //Nose cones in Rocksim may have attached parts - namely Mass Objects - as children.
56 if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) {
57 return new AttachedPartsHandler(noseCone);
59 return PlainTextHandler.INSTANCE;
63 public void closeElement(String element, HashMap<String, String> attributes,
64 String content, WarningSet warnings) throws SAXException {
65 super.closeElement(element, attributes, content, warnings);
68 if (RocksimCommonConstants.SHAPE_CODE.equals(element)) {
69 noseCone.setType(RocksimNoseConeCode.fromCode(Integer.parseInt(content)).asOpenRocket());
71 if (RocksimCommonConstants.LEN.equals(element)) {
72 noseCone.setLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH));
74 if (RocksimCommonConstants.BASE_DIA.equals(element)) {
75 noseCone.setAftRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS));
77 if (RocksimCommonConstants.WALL_THICKNESS.equals(element)) {
78 thickness = Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
80 if (RocksimCommonConstants.SHOULDER_OD.equals(element)) {
81 noseCone.setAftShoulderRadius(Math.max(0, Double.parseDouble(
82 content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS));
84 if (RocksimCommonConstants.SHOULDER_LEN.equals(element)) {
85 noseCone.setAftShoulderLength(Math.max(0, Double.parseDouble(
86 content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH));
88 if (RocksimCommonConstants.SHAPE_PARAMETER.equals(element)) {
89 //The Rocksim ShapeParameter only applies to certain shapes, although it is included
90 //in the design file for all nose cones. Applying it when it should not be causes oddities so
91 //a check is made for the allowable shapes.
92 if (Transition.Shape.POWER.equals(noseCone.getType()) ||
93 Transition.Shape.HAACK.equals(noseCone.getType()) ||
94 Transition.Shape.PARABOLIC.equals(noseCone.getType())) {
95 noseCone.setShapeParameter(Double.parseDouble(content));
98 if (RocksimCommonConstants.CONSTRUCTION_TYPE.equals(element)) {
99 int typeCode = Integer.parseInt(content);
102 noseCone.setFilled(true);
104 else if (typeCode == 1) {
106 noseCone.setFilled(false);
109 if (RocksimCommonConstants.FINISH_CODE.equals(element)) {
110 noseCone.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket());
112 if (RocksimCommonConstants.MATERIAL.equals(element)) {
113 setMaterialName(content);
116 catch (NumberFormatException nfe) {
117 warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number.");
122 public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings)
123 throws SAXException {
124 super.endHandler(element, attributes, content, warnings);
126 if (noseCone.isFilled()) {
127 noseCone.setAftShoulderThickness(noseCone.getAftShoulderRadius());
130 noseCone.setThickness(thickness);
131 noseCone.setAftShoulderThickness(thickness);
136 * Get the nose cone component this handler is working upon.
138 * @return a nose cone component
141 public NoseCone getComponent() {
146 * Get the required type of material for this component.
150 public Material.Type getMaterialType() {
151 return Material.Type.BULK;