De-localize Material and FlightDataType objects when persisting in ork files. Added...
[debian/openrocket] / core / src / net / sf / openrocket / file / openrocket / importt / OpenRocketLoader.java
index 6a112f55d63df91dd353e7f7d99b83a1d9331e9e..7ef136b83eea70062ae19b467236a6530e1c85c0 100644 (file)
@@ -67,6 +67,7 @@ import net.sf.openrocket.rocketcomponent.ThicknessRingComponent;
 import net.sf.openrocket.rocketcomponent.Transition;
 import net.sf.openrocket.rocketcomponent.TrapezoidFinSet;
 import net.sf.openrocket.rocketcomponent.TubeCoupler;
+import net.sf.openrocket.simulation.CustomExpression;
 import net.sf.openrocket.simulation.FlightData;
 import net.sf.openrocket.simulation.FlightDataBranch;
 import net.sf.openrocket.simulation.FlightDataType;
@@ -1201,6 +1202,7 @@ class SimulationsHandler extends AbstractElementHandler {
 }
 
 class SingleSimulationHandler extends AbstractElementHandler {
+
        private final DocumentLoadingContext context;
 
        private final OpenRocketDocument doc;
@@ -1209,7 +1211,9 @@ class SingleSimulationHandler extends AbstractElementHandler {
 
        private SimulationConditionsHandler conditionHandler;
        private FlightDataHandler dataHandler;
+       private CustomExpressionsHandler customExpressionsHandler;
 
+       private ArrayList<CustomExpression> customExpressions = new ArrayList<CustomExpression>();
        private final List<String> listeners = new ArrayList<String>();
 
        public SingleSimulationHandler(OpenRocketDocument doc, DocumentLoadingContext context) {
@@ -1217,7 +1221,13 @@ class SingleSimulationHandler extends AbstractElementHandler {
                this.context = context;
        }
 
+       public void setCustomExpressions(ArrayList<CustomExpression> expressions){
+               this.customExpressions = expressions;
+       }
 
+       public ArrayList<CustomExpression> getCustomExpressions(){
+               return customExpressions;
+       }
 
        @Override
        public ElementHandler openElement(String element, HashMap<String, String> attributes,
@@ -1226,11 +1236,14 @@ class SingleSimulationHandler extends AbstractElementHandler {
                if (element.equals("name") || element.equals("simulator") ||
                                element.equals("calculator") || element.equals("listener")) {
                        return PlainTextHandler.INSTANCE;
+               } else if (element.equals("customexpressions")) {
+                       customExpressionsHandler = new CustomExpressionsHandler(this, context);
+                       return customExpressionsHandler;
                } else if (element.equals("conditions")) {
                        conditionHandler = new SimulationConditionsHandler(doc.getRocket(), context);
                        return conditionHandler;
                } else if (element.equals("flightdata")) {
-                       dataHandler = new FlightDataHandler(context);
+                       dataHandler = new FlightDataHandler(this, context);
                        return dataHandler;
                } else {
                        warnings.add("Unknown element '" + element + "', ignoring.");
@@ -1286,14 +1299,71 @@ class SingleSimulationHandler extends AbstractElementHandler {
                else
                        data = dataHandler.getFlightData();
 
-               Simulation simulation = new Simulation(doc.getRocket(), status, name,
+               Simulation simulation = new Simulation(doc, doc.getRocket(), status, name,
                                conditions, listeners, data);
 
+               // Note : arraylist implementation in simulation different from standard one
+               for (CustomExpression exp : customExpressions){
+                       exp.setSimulation(simulation);
+                       if (exp.checkAll())
+                               simulation.addCustomExpression(exp);
+               }
+
                doc.addSimulation(simulation);
        }
 }
 
+class CustomExpressionsHandler extends AbstractElementHandler {
+       private final DocumentLoadingContext context;
+       private final SingleSimulationHandler simHandler;
+       public CustomExpression currentExpression = new CustomExpression();
+       private final ArrayList<CustomExpression> customExpressions = new ArrayList<CustomExpression>();
+
+
+       public CustomExpressionsHandler(SingleSimulationHandler simHandler, DocumentLoadingContext context) {
+               this.context = context;
+               this.simHandler = simHandler;
+       }
+
+       @Override
+       public ElementHandler openElement(String element,
+                       HashMap<String, String> attributes, WarningSet warnings)
+                                       throws SAXException {
+
+               if (element.equals("expression")){
+                       currentExpression = new CustomExpression();
+               }
+
+               return this;
+       }
+
+       @Override
+       public void closeElement(String element, HashMap<String, String> attributes,
+                       String content, WarningSet warnings) {
+
+               if (element.equals("expression"))
+                       customExpressions.add(currentExpression);
+
+               if (element.equals("name"))
+                       currentExpression.setName(content);
+
+               else if (element.equals("symbol"))
+                       currentExpression.setSymbol(content);
+
+               else if (element.equals("unit"))
+                       currentExpression.setUnit(content);
+
+               else if (element.equals("expressionstring"))
+                       currentExpression.setExpression(content);
+
+       }
 
+       @Override
+       public void endHandler(String element, HashMap<String, String> attributes,
+                       String content, WarningSet warnings) {
+               simHandler.setCustomExpressions(customExpressions);
+       }
+}
 
 class SimulationConditionsHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
@@ -1479,11 +1549,13 @@ class FlightDataHandler extends AbstractElementHandler {
        private WarningSet warningSet = new WarningSet();
        private List<FlightDataBranch> branches = new ArrayList<FlightDataBranch>();
 
+       private SingleSimulationHandler simHandler;
        private FlightData data;
 
 
-       public FlightDataHandler(DocumentLoadingContext context) {
+       public FlightDataHandler(SingleSimulationHandler simHandler, DocumentLoadingContext context) {
                this.context = context;
+               this.simHandler = simHandler;
        }
 
        public FlightData getFlightData() {
@@ -1502,8 +1574,10 @@ class FlightDataHandler extends AbstractElementHandler {
                                warnings.add("Illegal flight data definition, ignoring.");
                                return null;
                        }
-                       dataHandler = new FlightDataBranchHandler(attributes.get("name"),
-                                       attributes.get("types"), context);
+                       dataHandler = new FlightDataBranchHandler(      attributes.get("name"),
+                                       attributes.get("typekeys"),
+                                       attributes.get("types"), 
+                                       simHandler, context);
                        return dataHandler;
                }
 
@@ -1600,18 +1674,74 @@ class FlightDataBranchHandler extends AbstractElementHandler {
        private final FlightDataType[] types;
        private final FlightDataBranch branch;
 
-       public FlightDataBranchHandler(String name, String typeList, DocumentLoadingContext context) {
+       private static final LogHelper log = Application.getLogger();
+       private final SingleSimulationHandler simHandler;
+
+       public FlightDataBranchHandler(String name, String typeKeyList, String typeList, SingleSimulationHandler simHandler, DocumentLoadingContext context) {
+               this.simHandler = simHandler;
                this.context = context;
-               String[] split = typeList.split(",");
-               types = new FlightDataType[split.length];
-               for (int i = 0; i < split.length; i++) {
-                       types[i] = FlightDataType.getType(split[i], UnitGroup.UNITS_NONE);
+               String[] typeNames = typeList.split(",");
+               String[] typeKeys = null;
+               if ( typeKeyList != null ) {
+                       typeKeys = typeKeyList.split(",");
+               }
+               types = new FlightDataType[typeNames.length];
+               for (int i = 0; i < typeNames.length; i++) {
+                       String typeName = typeNames[i];
+                       String typeKey = (typeKeys != null ) ? typeKeys[i] : null ;
+                       FlightDataType matching = findFlightDataType(typeKey, typeName);
+                       types[i] = matching;
+                       //types[i] = FlightDataType.getType(typeName, matching.getSymbol(), matching.getUnitGroup());
                }
 
                // TODO: LOW: May throw an IllegalArgumentException
                branch = new FlightDataBranch(name, types);
        }
 
+       // Find the full flight data type given name only
+       // Note: this way of doing it requires that custom expressions always come before flight data in the file,
+       // not the nicest but this is always the case anyway.
+       private FlightDataType findFlightDataType(String key, String name){
+
+               // Look in built in types by key.
+               if ( key != null ) {
+                       for (FlightDataType t : FlightDataType.ALL_TYPES){
+                               if (t.getKey().equals(key) ){
+                                       return t;
+                               }
+                       }
+               }
+               // Look in built in types by name.
+               for (FlightDataType t : FlightDataType.ALL_TYPES){
+                       if (t.getName().equals(name) ){
+                               return t;
+                       }
+               }
+
+               // Look in custom expressions
+               for (CustomExpression exp : simHandler.getCustomExpressions()){
+                       if (exp.getName().equals(name) ){
+                               return exp.getType();
+                       }
+               }
+
+               // Look in custom expressions, meanwhile set priority based on order in file
+               /*
+               int totalExpressions = simHandler.getCustomExpressions().size();
+               for (int i=0; i<totalExpressions; i++){
+                       CustomExpression exp = simHandler.getCustomExpressions().get(i);                        
+                       if (exp.getName().equals(name) ){
+                               FlightDataType t = exp.getType();
+                               t.setPriority(-1*(totalExpressions-i));
+                               return exp.getType();
+                       }
+               }
+                */
+
+               log.warn("Could not find the flight data type '"+name+"' used in the XML file. Substituted type with unknown symbol and units.");
+               return FlightDataType.getType(name, "Unknown", UnitGroup.UNITS_NONE);
+       }
+
        public FlightDataBranch getBranch() {
                branch.immute();
                return branch;
@@ -1948,7 +2078,7 @@ class ComponentPresetSetter implements Setter {
        @Override
        public void set(RocketComponent c, String name, HashMap<String, String> attributes,
                        WarningSet warnings) {
-// FIXME - probably need more data in the warning messages - like what component preset...
+               // FIXME - probably need more data in the warning messages - like what component preset...
                String manufacturerName = attributes.get("manufacturer");
                if ( manufacturerName == null ) {
                        warnings.add(Warning.fromString("Invalid ComponentPreset, no manufacturer specified.  Ignored"));
@@ -1989,10 +2119,10 @@ class ComponentPresetSetter implements Setter {
 
                // Was any found?
                if ( matchingPreset == null ) {
-                       warnings.add(Warning.fromString("No matching ComponentPreset found"));
+                       warnings.add(Warning.fromString("No matching ComponentPreset found " + manufacturerName + " " + productNo));
                        return;
                }
-               
+
                if ( digest != null && !matchingPreset.getDigest().equals(digest) ) {
                        warnings.add(Warning.fromString("ComponentPreset has wrong digest"));
                }
@@ -2058,7 +2188,9 @@ class MaterialSetter implements Setter {
                        return;
                }
 
-               mat = Databases.findMaterial(type, name, density, false);
+               String key = attributes.remove("key");
+
+               mat = Databases.findMaterial(type, key, name, density);
 
                setMethod.invoke(c, mat);
        }