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;
/**
* 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;
/**
* 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;
/**
* 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>();
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;
* 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;
/**
* 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;
* 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;
* 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;
* 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;
}
-class MotorMountHandler extends ElementHandler {
+class MotorMountHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
private final MotorMount mount;
private MotorHandler motorHandler;
-class MotorConfigurationHandler extends ElementHandler {
+class MotorConfigurationHandler extends AbstractElementHandler {
@SuppressWarnings("unused")
private final DocumentLoadingContext context;
private final Rocket rocket;
}
-class MotorHandler extends ElementHandler {
+class MotorHandler extends AbstractElementHandler {
/** File version where latest digest format was introduced */
private static final int MOTOR_DIGEST_VERSION = 104;
-class SimulationsHandler extends ElementHandler {
+class SimulationsHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
private final OpenRocketDocument doc;
private SingleSimulationHandler handler;
}
-class SingleSimulationHandler extends ElementHandler {
+class SingleSimulationHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
private final OpenRocketDocument doc;
-class SimulationConditionsHandler extends ElementHandler {
+class SimulationConditionsHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
private SimulationOptions conditions;
private AtmosphereHandler atmosphereHandler;
}
-class AtmosphereHandler extends ElementHandler {
+class AtmosphereHandler extends AbstractElementHandler {
@SuppressWarnings("unused")
private final DocumentLoadingContext context;
private final String model;
}
-class FlightDataHandler extends ElementHandler {
+class FlightDataHandler extends AbstractElementHandler {
private final DocumentLoadingContext context;
private FlightDataBranchHandler dataHandler;
}
-class FlightDataBranchHandler extends ElementHandler {
+class FlightDataBranchHandler extends AbstractElementHandler {
@SuppressWarnings("unused")
private final DocumentLoadingContext context;
private final FlightDataType[] types;
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;
/**
* A SAX handler for the Rocksim AttachedParts XML type.
*/
-class AttachedPartsHandler extends ElementHandler {
+class AttachedPartsHandler extends AbstractElementHandler {
/** The parent component. */
private final RocketComponent component;
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;
*
* @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.
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;
* 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.
*/
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;
* <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.
/**
* Handles the content of the <DesignInformation> tag.
*/
-class RocksimContentHandler extends ElementHandler {
+class RocksimContentHandler extends AbstractElementHandler {
/**
* The OpenRocketDocument that is the container for the rocket.
*/
* 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.
*/
/**
* A SAX handler for a Rocksim stage.
*/
-class StageHandler extends ElementHandler {
+class StageHandler extends AbstractElementHandler {
/**
* The parent OpenRocket component.
*/
--- /dev/null
+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
+ }
+
+}
/**
* 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;
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
import java.util.HashMap;
-import net.sf.openrocket.aerodynamics.Warning;
import net.sf.openrocket.aerodynamics.WarningSet;
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.
* @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
*
* @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>();
* 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() {
* 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>
* @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);