Refactored simple SAX ElementHandler to be an interface.
authorplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Sun, 19 Feb 2012 08:40:34 +0000 (08:40 +0000)
committerplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Sun, 19 Feb 2012 08:40:34 +0000 (08:40 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@428 180e2498-e6e9-4542-8430-84ac67f01cd8

12 files changed:
core/src/net/sf/openrocket/file/motor/RockSimMotorLoader.java
core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java
core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java
core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java
core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java
core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java
core/src/net/sf/openrocket/file/simplesax/AbstractElementHandler.java [new file with mode: 0644]
core/src/net/sf/openrocket/file/simplesax/DelegatorHandler.java
core/src/net/sf/openrocket/file/simplesax/ElementHandler.java
core/src/net/sf/openrocket/file/simplesax/NullElementHandler.java
core/src/net/sf/openrocket/file/simplesax/PlainTextHandler.java
core/src/net/sf/openrocket/file/simplesax/SimpleSAX.java

index 8627bf82f79ae3b74ade31cc15717fc8324eb021..5a79d9463b375f0bdbaa56aaaf8fc178303fc9bd 100644 (file)
@@ -8,6 +8,7 @@ import java.util.HashMap;
 import java.util.List;
 
 import net.sf.openrocket.aerodynamics.WarningSet;
+import net.sf.openrocket.file.simplesax.AbstractElementHandler;
 import net.sf.openrocket.file.simplesax.ElementHandler;
 import net.sf.openrocket.file.simplesax.NullElementHandler;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
@@ -77,7 +78,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
        /**
         * Initial handler for the RockSim engine files.
         */
-       private static class RSEHandler extends ElementHandler {
+       private static class RSEHandler extends AbstractElementHandler {
                private final List<Motor> motors = new ArrayList<Motor>();
                
                private RSEMotorHandler motorHandler;
@@ -124,7 +125,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
        /**
         * Handler for a RockSim engine file <motor> element.
         */
-       private static class RSEMotorHandler extends ElementHandler {
+       private static class RSEMotorHandler extends AbstractElementHandler {
                
                private final String manufacturer;
                private final String designation;
@@ -390,7 +391,7 @@ public class RockSimMotorLoader extends AbstractMotorLoader {
        /**
         * Handler for the <data> element in a RockSim engine file motor definition.
         */
-       private static class RSEMotorDataHandler extends ElementHandler {
+       private static class RSEMotorDataHandler extends AbstractElementHandler {
                
                private final List<Double> time = new ArrayList<Double>();
                private final List<Double> force = new ArrayList<Double>();
index 77f7185b2d70101a0fa8ca7fe3690468c50056fa..313fa981a158d96206c6f9d2aa410e85e706020f 100644 (file)
@@ -20,6 +20,7 @@ import net.sf.openrocket.document.StorageOptions;
 import net.sf.openrocket.file.AbstractRocketLoader;
 import net.sf.openrocket.file.MotorFinder;
 import net.sf.openrocket.file.RocketLoadException;
+import net.sf.openrocket.file.simplesax.AbstractElementHandler;
 import net.sf.openrocket.file.simplesax.ElementHandler;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.file.simplesax.SimpleSAX;
@@ -545,7 +546,7 @@ class DocumentConfig {
  * The starting point of the handlers.  Accepts a single <openrocket> element and hands
  * the contents to be read by a OpenRocketContentsHandler.
  */
-class OpenRocketHandler extends ElementHandler {
+class OpenRocketHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private OpenRocketContentHandler handler = null;
        
@@ -636,7 +637,7 @@ class OpenRocketHandler extends ElementHandler {
 /**
  * Handles the content of the <openrocket> tag.
  */
-class OpenRocketContentHandler extends ElementHandler {
+class OpenRocketContentHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private final OpenRocketDocument doc;
        private final Rocket rocket;
@@ -696,7 +697,7 @@ class OpenRocketContentHandler extends ElementHandler {
  * A handler that creates components from the corresponding elements.  The control of the
  * contents is passed on to ComponentParameterHandler.
  */
-class ComponentHandler extends ElementHandler {
+class ComponentHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private final RocketComponent parent;
        
@@ -740,7 +741,7 @@ class ComponentHandler extends ElementHandler {
  * This uses the setters, or delegates the handling to another handler for specific
  * elements.
  */
-class ComponentParameterHandler extends ElementHandler {
+class ComponentParameterHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private final RocketComponent component;
        
@@ -821,7 +822,7 @@ class ComponentParameterHandler extends ElementHandler {
  * A handler that reads the <point> specifications within the freeformfinset's
  * <finpoints> elements.
  */
-class FinSetPointHandler extends ElementHandler {
+class FinSetPointHandler extends AbstractElementHandler {
        @SuppressWarnings("unused")
        private final DocumentLoadingContext context;
        private final FreeformFinSet finset;
@@ -873,7 +874,7 @@ class FinSetPointHandler extends ElementHandler {
 }
 
 
-class MotorMountHandler extends ElementHandler {
+class MotorMountHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private final MotorMount mount;
        private MotorHandler motorHandler;
@@ -969,7 +970,7 @@ class MotorMountHandler extends ElementHandler {
 
 
 
-class MotorConfigurationHandler extends ElementHandler {
+class MotorConfigurationHandler extends AbstractElementHandler {
        @SuppressWarnings("unused")
        private final DocumentLoadingContext context;
        private final Rocket rocket;
@@ -1028,7 +1029,7 @@ class MotorConfigurationHandler extends ElementHandler {
 }
 
 
-class MotorHandler extends ElementHandler {
+class MotorHandler extends AbstractElementHandler {
        /** File version where latest digest format was introduced */
        private static final int MOTOR_DIGEST_VERSION = 104;
        
@@ -1162,7 +1163,7 @@ class MotorHandler extends ElementHandler {
 
 
 
-class SimulationsHandler extends ElementHandler {
+class SimulationsHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private final OpenRocketDocument doc;
        private SingleSimulationHandler handler;
@@ -1195,7 +1196,7 @@ class SimulationsHandler extends ElementHandler {
        
 }
 
-class SingleSimulationHandler extends ElementHandler {
+class SingleSimulationHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        
        private final OpenRocketDocument doc;
@@ -1290,7 +1291,7 @@ class SingleSimulationHandler extends ElementHandler {
 
 
 
-class SimulationConditionsHandler extends ElementHandler {
+class SimulationConditionsHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        private SimulationOptions conditions;
        private AtmosphereHandler atmosphereHandler;
@@ -1402,7 +1403,7 @@ class SimulationConditionsHandler extends ElementHandler {
 }
 
 
-class AtmosphereHandler extends ElementHandler {
+class AtmosphereHandler extends AbstractElementHandler {
        @SuppressWarnings("unused")
        private final DocumentLoadingContext context;
        private final String model;
@@ -1467,7 +1468,7 @@ class AtmosphereHandler extends ElementHandler {
 }
 
 
-class FlightDataHandler extends ElementHandler {
+class FlightDataHandler extends AbstractElementHandler {
        private final DocumentLoadingContext context;
        
        private FlightDataBranchHandler dataHandler;
@@ -1589,7 +1590,7 @@ class FlightDataHandler extends ElementHandler {
 }
 
 
-class FlightDataBranchHandler extends ElementHandler {
+class FlightDataBranchHandler extends AbstractElementHandler {
        @SuppressWarnings("unused")
        private final DocumentLoadingContext context;
        private final FlightDataType[] types;
index bfb7692ad31d2b3e1f9395d52c2536e390559278..cb019fa37c65439631f588580047984568551bda 100644 (file)
@@ -5,6 +5,7 @@ package net.sf.openrocket.file.rocksim.importt;
 
 import net.sf.openrocket.aerodynamics.WarningSet;
 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
+import net.sf.openrocket.file.simplesax.AbstractElementHandler;
 import net.sf.openrocket.file.simplesax.ElementHandler;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
 
@@ -13,7 +14,7 @@ import java.util.HashMap;
 /**
  * A SAX handler for the Rocksim AttachedParts XML type.  
  */
-class AttachedPartsHandler extends ElementHandler {
+class AttachedPartsHandler extends AbstractElementHandler {
     /** The parent component. */
     private final RocketComponent component;
 
index b825111a4e07b8720793151c980b0933e1969f3f..6302c62a3e19baa9a3ea917764c8f3ef9b37ba32 100644 (file)
@@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt;
 import net.sf.openrocket.aerodynamics.WarningSet;
 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
 import net.sf.openrocket.file.rocksim.RocksimDensityType;
-import net.sf.openrocket.file.simplesax.ElementHandler;
+import net.sf.openrocket.file.simplesax.AbstractElementHandler;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.RocketComponent;
 import org.xml.sax.SAXException;
@@ -20,7 +20,7 @@ import java.util.HashMap;
  *
  * @param <C>   the specific RocketComponent subtype for which the concrete handler can create
  */
-public abstract class BaseHandler<C extends RocketComponent> extends ElementHandler {
+public abstract class BaseHandler<C extends RocketComponent> extends AbstractElementHandler {
 
     /**
      * Prepend rocksim materials.
index 9b42617b0ffa2a09443aae64d3dd6d3ed01b02b4..048a2fd4f2a730b9cefd57fbded3ec34fa323acc 100644 (file)
@@ -7,6 +7,7 @@ import net.sf.openrocket.aerodynamics.WarningSet;
 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
 import net.sf.openrocket.file.rocksim.RocksimFinishCode;
 import net.sf.openrocket.file.rocksim.RocksimLocationMode;
+import net.sf.openrocket.file.simplesax.AbstractElementHandler;
 import net.sf.openrocket.file.simplesax.ElementHandler;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.material.Material;
@@ -31,7 +32,7 @@ import java.util.List;
  * characteristics are kept here until the closing FinSet tag. At that point, <code>asOpenRocket</code> method is called
  * to construct the corresponding OpenRocket FinSet.
  */
-class FinSetHandler extends ElementHandler {
+class FinSetHandler extends AbstractElementHandler {
     /**
      * The parent component.
      */
index 9228d6b102654fe7a37b9f295b8b0a0fea4ae81f..bf41c1687ec690bc9585b4fa3abf001ff89f8233 100644 (file)
@@ -8,6 +8,7 @@ import net.sf.openrocket.aerodynamics.Warning;
 import net.sf.openrocket.aerodynamics.WarningSet;
 import net.sf.openrocket.document.OpenRocketDocument;
 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
+import net.sf.openrocket.file.simplesax.AbstractElementHandler;
 import net.sf.openrocket.file.simplesax.ElementHandler;
 import net.sf.openrocket.file.simplesax.PlainTextHandler;
 import net.sf.openrocket.rocketcomponent.Rocket;
@@ -24,7 +25,7 @@ import java.util.HashMap;
  * <p/>
  * Limitations: Rocksim flight simulations are not imported; tube fins are not supported; Rocksim 'pods' are not supported.
  */
-public class RocksimHandler extends ElementHandler {
+public class RocksimHandler extends AbstractElementHandler {
 
     /**
      * The main content handler.
@@ -67,7 +68,7 @@ public class RocksimHandler extends ElementHandler {
 /**
  * Handles the content of the <DesignInformation> tag.
  */
-class RocksimContentHandler extends ElementHandler {
+class RocksimContentHandler extends AbstractElementHandler {
     /**
      * The OpenRocketDocument that is the container for the rocket.
      */
@@ -145,7 +146,7 @@ class RocksimContentHandler extends ElementHandler {
  * Correct functioning of this handler is predicated on the stage count element appearing before the actual stage parts
  * structures.  If that invariant is not true, then behavior will be unpredictable.
  */
-class RocketDesignHandler extends ElementHandler {
+class RocketDesignHandler extends AbstractElementHandler {
     /**
      * The parent component.
      */
@@ -309,7 +310,7 @@ class RocketDesignHandler extends ElementHandler {
 /**
  * A SAX handler for a Rocksim stage.
  */
-class StageHandler extends ElementHandler {
+class StageHandler extends AbstractElementHandler {
     /**
      * The parent OpenRocket component.
      */
diff --git a/core/src/net/sf/openrocket/file/simplesax/AbstractElementHandler.java b/core/src/net/sf/openrocket/file/simplesax/AbstractElementHandler.java
new file mode 100644 (file)
index 0000000..208f68c
--- /dev/null
@@ -0,0 +1,54 @@
+package net.sf.openrocket.file.simplesax;
+
+import java.util.HashMap;
+
+import net.sf.openrocket.aerodynamics.Warning;
+import net.sf.openrocket.aerodynamics.WarningSet;
+
+import org.xml.sax.SAXException;
+
+
+/**
+ * An abstract base class for creating an ElementHandler.  This implements the close
+ * methods so that warnings are generated for spurious content.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public abstract class AbstractElementHandler implements ElementHandler {
+       
+       @Override
+       public abstract ElementHandler openElement(String element,
+                       HashMap<String, String> attributes, WarningSet warnings) throws SAXException;
+       
+       /**
+        * {@inheritDoc}
+        * <p>
+        * The default implementation is to add warnings for any textual content or attributes.
+        * This is useful for generating warnings for unknown XML attributes.
+        */
+       @Override
+       public void closeElement(String element, HashMap<String, String> attributes,
+                       String content, WarningSet warnings) throws SAXException {
+               
+               if (!content.trim().equals("")) {
+                       warnings.add(Warning.fromString("Unknown text in element '" + element
+                                       + "', ignoring."));
+               }
+               if (!attributes.isEmpty()) {
+                       warnings.add(Warning.fromString("Unknown attributes in element '" + element
+                                       + "', ignoring."));
+               }
+       }
+       
+       /**
+        * {@inheritDoc}
+        * <p>
+        * The default implementation is a no-op.
+        */
+       @Override
+       public void endHandler(String element, HashMap<String, String> attributes,
+                       String content, WarningSet warnings) throws SAXException {
+               // No-op
+       }
+       
+}
index 3ec6bdc11d57a0295ae6edefd82a21aeea705947..0b88640ca683ad5a6611bc1fc4dd2f8174599f14 100644 (file)
@@ -13,7 +13,7 @@ import org.xml.sax.helpers.DefaultHandler;
 
 /**
  * The actual SAX handler class.  Contains the necessary methods for parsing the SAX source.
- * Delegates the actual content parsing to {@link ElementHandler} objects.
+ * Delegates the actual content parsing to {@link AbstractElementHandler} objects.
  */
 class DelegatorHandler extends DefaultHandler {
        private final WarningSet warnings;
@@ -22,12 +22,12 @@ class DelegatorHandler extends DefaultHandler {
        private final Deque<StringBuilder> elementData = new ArrayDeque<StringBuilder>();
        private final Deque<HashMap<String, String>> elementAttributes = new ArrayDeque<HashMap<String, String>>();
        
-
+       
        // Ignore all elements as long as ignore > 0
        private int ignore = 0;
        
        
-       public DelegatorHandler(ElementHandler initialHandler, WarningSet warnings) {
+       public DelegatorHandler(AbstractElementHandler initialHandler, WarningSet warnings) {
                this.warnings = warnings;
                handlerStack.add(initialHandler);
                elementData.add(new StringBuilder()); // Just in case
index ae678f80bb43915398ad72f377a9b8a649ee55f4..cdbbe1d6187dadef53638464274d6dd00e9d1e31 100644 (file)
@@ -2,7 +2,6 @@ package net.sf.openrocket.file.simplesax;
 
 import java.util.HashMap;
 
-import net.sf.openrocket.aerodynamics.Warning;
 import net.sf.openrocket.aerodynamics.WarningSet;
 
 import org.xml.sax.SAXException;
@@ -18,30 +17,23 @@ import org.xml.sax.SAXException;
  * 
  * and the initial handler is initHandler, then the following methods will be called:
  * 
- * 1. initHandler.{@link #openElement(String, HashMap, WarningSet)} is called for
- *       the opening element <bar>, which returns fooHandler
- * 2. fooHandler.{@link #openElement(String, HashMap, WarningSet)} is called for
- *       the opening element <bar>, which returns barHandler
- * 3. barHandler.{@link #endHandler(String, HashMap, String, WarningSet)} is called for
- *       the closing element </bar>
- * 4. fooHandler.{@link #closeElement(String, HashMap, String, WarningSet)} is called for
- *       the closing element </bar>
- * 5. fooHandler.{@link #endHandler(String, HashMap, String, WarningSet)} is called for
- *       the closing element </foo>
- * 6. initHandler.{@link #closeElement(String, HashMap, String, WarningSet)} is called for
- *       the closing element </foo>
+ * 1. initHandler.openElement(String, HashMap, WarningSet) is called for the opening element <foo>, which returns fooHandler
+ * 2. fooHandler.openElement(String, HashMap, WarningSet) is called for the opening element <bar>, which returns barHandler
+ * 3. barHandler.endHandler(String, HashMap, String, WarningSet) is called for the closing element </bar>
+ * 4. fooHandler.closeElement(String, HashMap, String, WarningSet) is called for the closing element </bar>
+ * 5. fooHandler.endHandler(String, HashMap, String, WarningSet) is called for the closing element </foo>
+ * 6. initHandler.closeElement(String, HashMap, String, WarningSet) is called for the closing element </foo>
  * 
- * Note that {@link #endHandler(String, HashMap, String, WarningSet)} is not called for
- * the initial handler.
+ * Note that endHandler(String, HashMap, String, WarningSet) is not called for the initial handler.
  * 
  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
  */
-public abstract class ElementHandler {
-
+public interface ElementHandler {
+       
        /**
-        * Called when an opening element is encountered.  Returns the handler that will handle
-        * the elements within that element, or <code>null</code> if the element and all of
-        * its contents is to be ignored.
+        * Called when an opening tag of a contained element is encountered.  Returns the handler
+        * that will handle the elements within that element, or <code>null</code> if the element
+        * and all of its contents is to be ignored.
         * <p>
         * Note that this method may also return <code>this</code>, in which case this
         * handler will also handle the subelement.
@@ -52,43 +44,29 @@ public abstract class ElementHandler {
         * @return                              the handler that handles elements encountered within this element,
         *                                              or <code>null</code> if the element is to be ignored.
         */
-       public abstract ElementHandler openElement(String element,
-                       HashMap<String, String> attributes, WarningSet warnings) throws SAXException;
-
+       public ElementHandler openElement(String element, HashMap<String, String> attributes,
+                       WarningSet warnings) throws SAXException;
+       
        /**
-        * Called when an element is closed.  The default implementation checks whether there is
-        * any non-space text within the element and if there exists any attributes, and adds
-        * a warning of both.  This can be used at the and of the method to check for 
-        * spurious data.
+        * Called when a closing tag of a contained element is encountered.
+        * <p>
+        * This method can be used to handle the textual content of the element for simple text
+        * elements, which is passed in as the "content" parameter.
         * 
         * @param element               the element name.
         * @param attributes    attributes of the element.
         * @param content               the textual content of the element.
         * @param warnings              the warning set to store warnings in.
         */
-       public void closeElement(String element, HashMap<String, String> attributes,
-                       String content, WarningSet warnings) throws SAXException {
-
-               if (!content.trim().equals("")) {
-                       warnings.add(Warning.fromString("Unknown text in element '" + element
-                                       + "', ignoring."));
-               }
-               if (!attributes.isEmpty()) {
-                       warnings.add(Warning.fromString("Unknown attributes in element '" + element
-                                       + "', ignoring."));
-               }
-       }
-       
+       public abstract void closeElement(String element, HashMap<String, String> attributes,
+                       String content, WarningSet warnings) throws SAXException;
        
        /**
-        * Called when the element block that this handler is handling ends.
-        * The default implementation is a no-op.
+        * Called when the current element that this handler is handling is closed.
         * 
         * @param warnings              the warning set to store warnings in.
         */
-       public void endHandler(String element, HashMap<String, String> attributes,
-                       String content, WarningSet warnings) throws SAXException {
-               // No-op
-       }
+       public abstract void endHandler(String element, HashMap<String, String> attributes,
+                       String content, WarningSet warnings) throws SAXException;
        
-}
+}
\ No newline at end of file
index e8dd2df8070ff05da9f240f17e03bef1d468b228..2cc86be3c8bdadfbb3cb3c0d504625aaf0f9441f 100644 (file)
@@ -16,7 +16,7 @@ import org.xml.sax.SAXException;
  * 
  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
  */
-public class NullElementHandler extends ElementHandler {
+public class NullElementHandler extends AbstractElementHandler {
        public static final NullElementHandler INSTANCE = new NullElementHandler();
 
        private static final HashMap<String, String> EMPTY_MAP = new HashMap<String,String>();
index 03be721a650a3da828097c8c1b3f108f374dc8a9..406a522c91986673db81e1151a3a21ef4ff4b2f7 100644 (file)
@@ -9,7 +9,7 @@ import net.sf.openrocket.aerodynamics.WarningSet;
  * An element handler that does not allow any sub-elements.  If any are encountered
  * a warning is generated and they are ignored.
  */
-public class PlainTextHandler extends ElementHandler {
+public class PlainTextHandler extends AbstractElementHandler {
        public static final PlainTextHandler INSTANCE = new PlainTextHandler();
 
        private PlainTextHandler() {
index 025c8886088094ae3edb128fee0120dec069ce35..62dc35a9b3f18f22d6f29a822f499bb2df4b7437 100644 (file)
@@ -16,8 +16,8 @@ import org.xml.sax.helpers.XMLReaderFactory;
  * both.  This holds true for both the OpenRocket and RockSim design formats and the
  * RockSim engine definition format.
  * <p>
- * The actual handling is performed by subclasses of {@link ElementHandler}.  The 
- * initial handler is provided to the {@link #readXML(InputSource, ElementHandler, WarningSet)}
+ * The actual handling is performed by subclasses of {@link AbstractElementHandler}.  The 
+ * initial handler is provided to the {@link #readXML(InputSource, AbstractElementHandler, WarningSet)}
  * method.
  * 
  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
@@ -33,7 +33,7 @@ public class SimpleSAX {
         * @throws IOException          if an I/O exception occurs while reading.
         * @throws SAXException         if e.g. malformed XML is encountered.
         */
-       public static void readXML(InputSource source, ElementHandler initialHandler,
+       public static void readXML(InputSource source, AbstractElementHandler initialHandler,
                        WarningSet warnings) throws IOException, SAXException {
 
                DelegatorHandler xmlhandler = new DelegatorHandler(initialHandler, warnings);