diff --git a/core/src/net/sf/openrocket/document/AttachmentFactory.java b/core/src/net/sf/openrocket/document/AttachmentFactory.java deleted file mode 100644 index c6cafb36f..000000000 --- a/core/src/net/sf/openrocket/document/AttachmentFactory.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.sf.openrocket.document; - -public interface AttachmentFactory { - - public T getAttachment(String name); - -} diff --git a/core/src/net/sf/openrocket/document/DecalRegistry.java b/core/src/net/sf/openrocket/document/DecalRegistry.java index 95f64798d..a604941c5 100644 --- a/core/src/net/sf/openrocket/document/DecalRegistry.java +++ b/core/src/net/sf/openrocket/document/DecalRegistry.java @@ -19,53 +19,51 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.openrocket.appearance.DecalImage; +import net.sf.openrocket.document.attachments.FileSystemAttachment; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.startup.Application; import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.FileUtils; -public class DecalRegistry implements AttachmentFactory { +public class DecalRegistry { private static LogHelper log = Application.getLogger(); - private final AttachmentFactory baseFactory; - - public DecalRegistry(AttachmentFactory baseFactory) { - this.baseFactory = baseFactory; + DecalRegistry() { + } private Map registeredDecals = new HashMap(); - public DecalImage getAttachment(String decalName) { - DecalImageImpl d = registeredDecals.get(decalName); - if (d == null) { - Attachment attachment = baseFactory.getAttachment(decalName); - d = new DecalImageImpl(attachment); + public DecalImage getDecalImage(Attachment attachment) { + String decalName = attachment.getName(); + DecalImageImpl d; + if (attachment instanceof FileSystemAttachment) { + File location = ((FileSystemAttachment) attachment).getLocation(); + d = findDecalForFile(location); + if (d != null) { + return d; + } + + // It's a new file, generate a name for it. + decalName = makeUniqueName(location.getName()); + + d = new DecalImageImpl(decalName, attachment); + d.setFileSystemLocation(location); + registeredDecals.put(decalName, d); + return d; + + } else { + d = registeredDecals.get(decalName); + if (d != null) { + return d; + } } + d = new DecalImageImpl(attachment); + registeredDecals.put(decalName, d); return d; } - public DecalImage getAttachment(File file) { - - // See if this file is being used already - DecalImageImpl decal = findDecalForFile(file); - - if (decal != null) { - return decal; - } - - // It's a new file, generate a name for it. - String decalName = makeUniqueName(file.getName()); - - Attachment attachment = baseFactory.getAttachment(decalName); - decal = new DecalImageImpl(attachment); - decal.setFileSystemLocation(file); - - registeredDecals.put(decalName, decal); - return decal; - - } - public Collection getDecalList() { Set decals = new TreeSet(); @@ -79,25 +77,31 @@ public class DecalRegistry implements AttachmentFactory { private final Attachment delegate; + private String name; private File fileSystemLocation; + private DecalImageImpl(String name, Attachment delegate) { + this.name = name; + this.delegate = delegate; + } + private DecalImageImpl(Attachment delegate) { this.delegate = delegate; } @Override public String getName() { - return delegate.getName(); + return name != null ? name : delegate.getName(); } @Override public InputStream getBytes() throws FileNotFoundException, IOException { - return DecalRegistry.this.getDecal(this); + return DecalRegistry.getDecal(this); } @Override public void exportImage(File file, boolean watchForChanges) throws IOException { - DecalRegistry.this.exportDecal(this, file); + DecalRegistry.exportDecal(this, file); this.fileSystemLocation = file; } @@ -111,7 +115,7 @@ public class DecalRegistry implements AttachmentFactory { @Override public String toString() { - return delegate.toString(); + return getName(); } @Override @@ -119,7 +123,7 @@ public class DecalRegistry implements AttachmentFactory { if (!(o instanceof DecalImageImpl)) { return -1; } - return delegate.compareTo(((DecalImageImpl) o).delegate); + return getName().compareTo(o.getName()); } } @@ -133,7 +137,7 @@ public class DecalRegistry implements AttachmentFactory { * @throws FileNotFoundException * @throws IOException */ - private InputStream getDecal(DecalImageImpl decal) throws FileNotFoundException, IOException { + private static InputStream getDecal(DecalImageImpl decal) throws FileNotFoundException, IOException { // First check if the decal is located on the file system File exportedFile = decal.getFileSystemLocation(); @@ -152,7 +156,7 @@ public class DecalRegistry implements AttachmentFactory { } - private void exportDecal(DecalImageImpl decal, File selectedFile) throws IOException { + private static void exportDecal(DecalImageImpl decal, File selectedFile) throws IOException { try { InputStream is = decal.getBytes(); diff --git a/core/src/net/sf/openrocket/document/OpenRocketDocument.java b/core/src/net/sf/openrocket/document/OpenRocketDocument.java index e1536d9c3..8af24ae50 100644 --- a/core/src/net/sf/openrocket/document/OpenRocketDocument.java +++ b/core/src/net/sf/openrocket/document/OpenRocketDocument.java @@ -1,14 +1,14 @@ package net.sf.openrocket.document; import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; +import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; +import net.sf.openrocket.appearance.DecalImage; import net.sf.openrocket.document.events.DocumentChangeEvent; import net.sf.openrocket.document.events.DocumentChangeListener; import net.sf.openrocket.document.events.SimulationChangeEvent; @@ -60,9 +60,6 @@ public class OpenRocketDocument implements ComponentChangeListener { private final ArrayList simulations = new ArrayList(); private ArrayList customExpressions = new ArrayList(); - private final AttachmentFactory attachmentFactory; - private final DecalRegistry decalRegistry; - /* * The undo/redo variables and mechanism are documented in doc/undo-redo-flow.* */ @@ -95,36 +92,13 @@ public class OpenRocketDocument implements ComponentChangeListener { private final StorageOptions storageOptions = new StorageOptions(); + private final DecalRegistry decalRegistry = new DecalRegistry(); private final List listeners = new ArrayList(); - OpenRocketDocument(Rocket rocket, File fileName, boolean isContainer) { + OpenRocketDocument(Rocket rocket) { this.configuration = rocket.getDefaultConfiguration(); this.rocket = rocket; - AttachmentFactory attachments; - if (isContainer) { - try { - attachments = new ZipFileAttachmentFactory(fileName.toURI().toURL()); - } catch (MalformedURLException mex) { - attachments = new FileSystemAttachmentFactory(null); - } - } else { - if (fileName == null) { - attachments = new FileSystemAttachmentFactory(null); - } else { - attachments = new FileSystemAttachmentFactory(fileName.getParentFile()); - } - } - this.attachmentFactory = attachments; - this.decalRegistry = new DecalRegistry(this.attachmentFactory); - init(); - } - - OpenRocketDocument(Rocket rocket, URL jarURL, boolean isContainer) { - this.configuration = rocket.getDefaultConfiguration(); - this.rocket = rocket; - this.attachmentFactory = isContainer ? new ZipFileAttachmentFactory(jarURL) : new FileSystemAttachmentFactory(null); - this.decalRegistry = new DecalRegistry(this.attachmentFactory); init(); } @@ -197,10 +171,6 @@ public class OpenRocketDocument implements ComponentChangeListener { return configuration; } - public DecalRegistry getDecalRegistry() { - return decalRegistry; - } - public File getFile() { return file; } @@ -209,7 +179,6 @@ public class OpenRocketDocument implements ComponentChangeListener { this.file = file; } - public boolean isSaved() { return rocket.getModID() == savedID; } @@ -231,8 +200,15 @@ public class OpenRocketDocument implements ComponentChangeListener { } + public Collection getDecalList() { + + return decalRegistry.getDecalList(); + + } - + public DecalImage getDecalImage(Attachment a) { + return decalRegistry.getDecalImage(a); + } public List getSimulations() { return simulations.clone(); diff --git a/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java b/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java index bb7c1376f..e649a06d0 100644 --- a/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java +++ b/core/src/net/sf/openrocket/document/OpenRocketDocumentFactory.java @@ -1,8 +1,5 @@ package net.sf.openrocket.document; -import java.io.File; -import java.net.URL; - import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Stage; @@ -18,25 +15,19 @@ public class OpenRocketDocumentFactory { //// Sustainer stage.setName(trans.get("BasicFrame.StageName.Sustainer")); rocket.addChild(stage); - OpenRocketDocument doc = new OpenRocketDocument(rocket, (File) null, false); + OpenRocketDocument doc = new OpenRocketDocument(rocket); doc.setSaved(true); return doc; } public static OpenRocketDocument createDocumentFromRocket(Rocket r) { - OpenRocketDocument doc = new OpenRocketDocument(r, (File) null, false); + OpenRocketDocument doc = new OpenRocketDocument(r); return doc; } - public static OpenRocketDocument createDocumentForFile(File filename, boolean isContainer) { + public static OpenRocketDocument createEmptyRocket() { Rocket rocket = new Rocket(); - OpenRocketDocument doc = new OpenRocketDocument(rocket, filename, isContainer); - return doc; - } - - public static OpenRocketDocument createDocumentForUrl(URL filename, boolean isContainer) { - Rocket rocket = new Rocket(); - OpenRocketDocument doc = new OpenRocketDocument(rocket, filename, isContainer); + OpenRocketDocument doc = new OpenRocketDocument(rocket); return doc; } diff --git a/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java b/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java index 50fdae583..33fca97bf 100644 --- a/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java +++ b/core/src/net/sf/openrocket/document/attachments/FileSystemAttachment.java @@ -17,6 +17,10 @@ public class FileSystemAttachment extends BaseAttachment implements Attachment { this.location = location; } + public File getLocation() { + return location; + } + @Override public InputStream getBytes() throws FileNotFoundException, IOException { return new FileInputStream(location); diff --git a/core/src/net/sf/openrocket/file/AbstractRocketLoader.java b/core/src/net/sf/openrocket/file/AbstractRocketLoader.java index 599e3f62b..0c0a0a222 100644 --- a/core/src/net/sf/openrocket/file/AbstractRocketLoader.java +++ b/core/src/net/sf/openrocket/file/AbstractRocketLoader.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.io.InputStream; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; public abstract class AbstractRocketLoader implements RocketLoader { @@ -15,11 +14,11 @@ public abstract class AbstractRocketLoader implements RocketLoader { * Loads a rocket from the specified InputStream. */ @Override - public final void load(OpenRocketDocument doc, InputStream source, MotorFinder motorFinder) throws RocketLoadException { + public final void load(DocumentLoadingContext context, InputStream source) throws RocketLoadException { warnings.clear(); try { - loadFromStream(doc, source, motorFinder); + loadFromStream(context, source); } catch (RocketLoadException e) { throw e; } catch (IOException e) { @@ -35,8 +34,7 @@ public abstract class AbstractRocketLoader implements RocketLoader { * * @throws RocketLoadException if an error occurs during loading. */ - protected abstract void loadFromStream(OpenRocketDocument doc, InputStream source, MotorFinder motorFinder) throws IOException, - RocketLoadException; + protected abstract void loadFromStream(DocumentLoadingContext context, InputStream source) throws IOException, RocketLoadException; diff --git a/core/src/net/sf/openrocket/file/AttachmentFactory.java b/core/src/net/sf/openrocket/file/AttachmentFactory.java new file mode 100644 index 000000000..74377f30f --- /dev/null +++ b/core/src/net/sf/openrocket/file/AttachmentFactory.java @@ -0,0 +1,9 @@ +package net.sf.openrocket.file; + +import net.sf.openrocket.document.Attachment; + +public interface AttachmentFactory { + + public Attachment getAttachment(String name); + +} diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentLoadingContext.java b/core/src/net/sf/openrocket/file/DocumentLoadingContext.java similarity index 67% rename from core/src/net/sf/openrocket/file/openrocket/importt/DocumentLoadingContext.java rename to core/src/net/sf/openrocket/file/DocumentLoadingContext.java index 2db581ca6..cd1812805 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentLoadingContext.java +++ b/core/src/net/sf/openrocket/file/DocumentLoadingContext.java @@ -1,12 +1,12 @@ -package net.sf.openrocket.file.openrocket.importt; +package net.sf.openrocket.file; import net.sf.openrocket.document.OpenRocketDocument; -import net.sf.openrocket.file.MotorFinder; public class DocumentLoadingContext { private int fileVersion; private MotorFinder motorFinder; + private AttachmentFactory attachmentFactory = new FileSystemAttachmentFactory(); private OpenRocketDocument document; public int getFileVersion() { @@ -24,13 +24,21 @@ public class DocumentLoadingContext { public void setMotorFinder(MotorFinder motorFinder) { this.motorFinder = motorFinder; } - + public OpenRocketDocument getOpenRocketDocument() { return document; } - + public void setOpenRocketDocument(OpenRocketDocument document) { this.document = document; } + public AttachmentFactory getAttachmentFactory() { + return attachmentFactory; + } + + public void setAttachmentFactory(AttachmentFactory attachmentFactory) { + this.attachmentFactory = attachmentFactory; + } + } diff --git a/core/src/net/sf/openrocket/document/FileSystemAttachmentFactory.java b/core/src/net/sf/openrocket/file/FileSystemAttachmentFactory.java similarity index 77% rename from core/src/net/sf/openrocket/document/FileSystemAttachmentFactory.java rename to core/src/net/sf/openrocket/file/FileSystemAttachmentFactory.java index c68c4be26..27e85868d 100644 --- a/core/src/net/sf/openrocket/document/FileSystemAttachmentFactory.java +++ b/core/src/net/sf/openrocket/file/FileSystemAttachmentFactory.java @@ -1,11 +1,11 @@ -package net.sf.openrocket.document; +package net.sf.openrocket.file; import java.io.File; -import net.sf.openrocket.document.attachments.BaseAttachment; +import net.sf.openrocket.document.Attachment; import net.sf.openrocket.document.attachments.FileSystemAttachment; -public class FileSystemAttachmentFactory implements AttachmentFactory { +public class FileSystemAttachmentFactory implements AttachmentFactory { private final File baseDirectory; @@ -22,8 +22,12 @@ public class FileSystemAttachmentFactory implements AttachmentFactory { +public class ZipFileAttachmentFactory implements AttachmentFactory { private final URL zipFile; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java index 8d5f2859c..11b52f2ba 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/AppearanceHandler.java @@ -5,6 +5,8 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.appearance.AppearanceBuilder; import net.sf.openrocket.appearance.Decal.EdgeMode; +import net.sf.openrocket.document.Attachment; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; @@ -14,7 +16,6 @@ import net.sf.openrocket.util.Color; import org.xml.sax.SAXException; class AppearanceHandler extends AbstractElementHandler { - @SuppressWarnings("unused") private final DocumentLoadingContext context; private final RocketComponent component; @@ -31,7 +32,8 @@ class AppearanceHandler extends AbstractElementHandler { throws SAXException { if ("decal".equals(element)) { String name = attributes.remove("name"); - builder.setImage(context.getOpenRocketDocument().getDecalRegistry().getAttachment(name)); + Attachment a = context.getAttachmentFactory().getAttachment(name); + builder.setImage(context.getOpenRocketDocument().getDecalImage(a)); double rotation = Double.parseDouble(attributes.remove("rotation")); builder.setRotation(rotation); String edgeModeName = attributes.remove("edgemode"); diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/AtmosphereHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/AtmosphereHandler.java index 91f1f252b..b109c1c24 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/AtmosphereHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/AtmosphereHandler.java @@ -3,6 +3,7 @@ package net.sf.openrocket.file.openrocket.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentHandler.java index b26e081e3..85d782bb0 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentHandler.java @@ -6,6 +6,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.rocketcomponent.RocketComponent; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java index 5614b2b60..01e2bb3c7 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/ComponentParameterHandler.java @@ -4,6 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/CustomExpressionHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/CustomExpressionHandler.java index 66b6ac030..187f2ffff 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/CustomExpressionHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/CustomExpressionHandler.java @@ -3,6 +3,7 @@ package net.sf.openrocket.file.openrocket.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.simulation.customexpression.CustomExpression; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DatatypeHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/DatatypeHandler.java index ece9463a2..c3fef5140 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DatatypeHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DatatypeHandler.java @@ -4,6 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java index c3cf2726e..3c5863bef 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DeploymentConfigurationHandler.java @@ -4,6 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java index fd92dbf4c..9d9941270 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/FinSetPointHandler.java @@ -5,6 +5,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataBranchHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataBranchHandler.java index 6bb8a2d07..4adc42546 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataBranchHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataBranchHandler.java @@ -3,6 +3,7 @@ package net.sf.openrocket.file.openrocket.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataHandler.java index 4251807a8..bb2a78976 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/FlightDataHandler.java @@ -6,6 +6,7 @@ import java.util.List; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java index b20d3a865..43d08626d 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorConfigurationHandler.java @@ -4,6 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java index 14468a35f..5619dec24 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorHandler.java @@ -5,6 +5,7 @@ import java.util.Locale; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java index f53ae9ca0..c04a3e34c 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/MotorMountHandler.java @@ -5,6 +5,7 @@ import java.util.Locale; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java index 3ab9380f3..13b88bd5a 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java @@ -5,6 +5,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java index 2518c3b94..ccc6329c9 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketHandler.java @@ -7,6 +7,7 @@ import java.util.regex.Pattern; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java index 0f634d983..b607df8e0 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketLoader.java @@ -8,7 +8,7 @@ import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.StorageOptions; import net.sf.openrocket.file.AbstractRocketLoader; -import net.sf.openrocket.file.MotorFinder; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.simplesax.SimpleSAX; import net.sf.openrocket.logging.LogHelper; @@ -35,16 +35,14 @@ public class OpenRocketLoader extends AbstractRocketLoader { @Override - public void loadFromStream(OpenRocketDocument doc, InputStream source, MotorFinder motorFinder) throws RocketLoadException, + public void loadFromStream(DocumentLoadingContext context, InputStream source) throws RocketLoadException, IOException { log.info("Loading .ork file"); - DocumentLoadingContext context = new DocumentLoadingContext(); - context.setMotorFinder(motorFinder); - context.setOpenRocketDocument(doc); InputSource xmlSource = new InputSource(source); OpenRocketHandler handler = new OpenRocketHandler(context); + OpenRocketDocument doc = context.getOpenRocketDocument(); try { SimpleSAX.readXML(xmlSource, handler, warnings); diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java index 4dbb34c12..f0cde3a4c 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationConditionsHandler.java @@ -3,6 +3,7 @@ package net.sf.openrocket.file.openrocket.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationsHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationsHandler.java index a083af58e..c5b0f705b 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/SimulationsHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/SimulationsHandler.java @@ -4,6 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.simulation.customexpression.CustomExpression; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java index dfb7fccc4..e0e09e24a 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/SingleSimulationHandler.java @@ -8,6 +8,7 @@ import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.Simulation; import net.sf.openrocket.document.Simulation.Status; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java index 24728f64d..0b3c42393 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/StageSeparationConfigurationHandler.java @@ -4,6 +4,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java index 9b6fe83da..7a909a4c5 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/AttachedPartsHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; @@ -16,65 +16,64 @@ import net.sf.openrocket.rocketcomponent.RocketComponent; * A SAX handler for the Rocksim AttachedParts XML type. */ class AttachedPartsHandler extends AbstractElementHandler { - private final OpenRocketDocument document; + private final DocumentLoadingContext context; - /** The parent component. */ - private final RocketComponent component; - - /** - * Constructor. - * - * @param c the parent - * - * @throws IllegalArgumentException thrown if c is null - */ - public AttachedPartsHandler(OpenRocketDocument document, RocketComponent c) throws IllegalArgumentException { - if (c == null) { - throw new IllegalArgumentException("The parent component of any attached part may not be null."); - } - this.document = document; - component = c; - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - if (RocksimCommonConstants.FIN_SET.equals(element)) { - return new FinSetHandler(document, component); - } - if (RocksimCommonConstants.CUSTOM_FIN_SET.equals(element)) { - return new FinSetHandler(document, component); - } - if (RocksimCommonConstants.LAUNCH_LUG.equals(element)) { - return new LaunchLugHandler(document, component, warnings); - } - if (RocksimCommonConstants.PARACHUTE.equals(element)) { - return new ParachuteHandler(document, component, warnings); - } - if (RocksimCommonConstants.STREAMER.equals(element)) { - return new StreamerHandler(document, component, warnings); - } - if (RocksimCommonConstants.MASS_OBJECT.equals(element)) { - return new MassObjectHandler(document, component, warnings); - } - if (RocksimCommonConstants.RING.equals(element)) { - return new RingHandler(document, component, warnings); - } - if (RocksimCommonConstants.BODY_TUBE.equals(element)) { - return new InnerBodyTubeHandler(document, component, warnings); - } - if (RocksimCommonConstants.TRANSITION.equals(element)) { - return new TransitionHandler(document, component, warnings); - } - if (RocksimCommonConstants.TUBE_FIN_SET.equals(element)) { - warnings.add("Tube fins are not currently supported. Ignoring."); - } - if (RocksimCommonConstants.RING_TAIL.equals(element)) { - warnings.add("Ring tails are not currently supported. Ignoring."); - } - if (RocksimCommonConstants.EXTERNAL_POD.equals(element)) { - warnings.add("Pods are not currently supported. Ignoring."); - } - return null; - } + /** The parent component. */ + private final RocketComponent component; + + /** + * Constructor. + * + * @param c the parent + * + * @throws IllegalArgumentException thrown if c is null + */ + public AttachedPartsHandler(DocumentLoadingContext context, RocketComponent c) throws IllegalArgumentException { + if (c == null) { + throw new IllegalArgumentException("The parent component of any attached part may not be null."); + } + this.context = context; + component = c; + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + if (RocksimCommonConstants.FIN_SET.equals(element)) { + return new FinSetHandler(context, component); + } + if (RocksimCommonConstants.CUSTOM_FIN_SET.equals(element)) { + return new FinSetHandler(context, component); + } + if (RocksimCommonConstants.LAUNCH_LUG.equals(element)) { + return new LaunchLugHandler(context, component, warnings); + } + if (RocksimCommonConstants.PARACHUTE.equals(element)) { + return new ParachuteHandler(context, component, warnings); + } + if (RocksimCommonConstants.STREAMER.equals(element)) { + return new StreamerHandler(context, component, warnings); + } + if (RocksimCommonConstants.MASS_OBJECT.equals(element)) { + return new MassObjectHandler(context, component, warnings); + } + if (RocksimCommonConstants.RING.equals(element)) { + return new RingHandler(context, component, warnings); + } + if (RocksimCommonConstants.BODY_TUBE.equals(element)) { + return new InnerBodyTubeHandler(context, component, warnings); + } + if (RocksimCommonConstants.TRANSITION.equals(element)) { + return new TransitionHandler(context, component, warnings); + } + if (RocksimCommonConstants.TUBE_FIN_SET.equals(element)) { + warnings.add("Tube fins are not currently supported. Ignoring."); + } + if (RocksimCommonConstants.RING_TAIL.equals(element)) { + warnings.add("Ring tails are not currently supported. Ignoring."); + } + if (RocksimCommonConstants.EXTERNAL_POD.equals(element)) { + warnings.add("Pods are not currently supported. Ignoring."); + } + return null; + } } - diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java index a48885085..5bf50a513 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/BaseHandler.java @@ -9,7 +9,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.database.Databases; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimDensityType; import net.sf.openrocket.file.simplesax.AbstractElementHandler; @@ -53,14 +53,14 @@ public abstract class BaseHandler extends AbstractEle */ private String materialName = ""; - protected final OpenRocketDocument document; - private final RockSimAppearanceBuilder appearanceBuilder; - - public BaseHandler( OpenRocketDocument document ) { - this.document = document; - appearanceBuilder = new RockSimAppearanceBuilder( document ); - } - + protected final DocumentLoadingContext context; + private final RockSimAppearanceBuilder appearanceBuilder; + + public BaseHandler(DocumentLoadingContext context) { + this.context = context; + appearanceBuilder = new RockSimAppearanceBuilder(context); + } + /** * The SAX method called when the closing element tag is reached. * @@ -114,17 +114,17 @@ public abstract class BaseHandler extends AbstractEle */ density = computeDensity(densityType, density); RocketComponent component = getComponent(); - - //TODO - What RockSim components can have Appearances? - if ( component instanceof ExternalComponent ){ - //If a symmetric component is set to PreventSeam then it is repeated - //twice as many times around the rocket. - if ( component instanceof SymmetricComponent && appearanceBuilder.isPreventSeam() ){ - appearanceBuilder.setScaleU(appearanceBuilder.getScaleU()*2); + + //TODO - What RockSim components can have Appearances? + if (component instanceof ExternalComponent) { + //If a symmetric component is set to PreventSeam then it is repeated + //twice as many times around the rocket. + if (component instanceof SymmetricComponent && appearanceBuilder.isPreventSeam()) { + appearanceBuilder.setScaleU(appearanceBuilder.getScaleU() * 2); } - component.setAppearance(appearanceBuilder.getAppearance()); - } - + component.setAppearance(appearanceBuilder.getAppearance()); + } + updateComponentMaterial(component, materialName, getMaterialType(), density); } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java index 873252e75..9d2eb3899 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/BodyTubeHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimFinishCode; import net.sf.openrocket.file.simplesax.ElementHandler; @@ -21,88 +21,86 @@ import org.xml.sax.SAXException; * A SAX handler for Rocksim Body Tubes. */ class BodyTubeHandler extends BaseHandler { - /** - * The OpenRocket BodyTube. - */ - private final BodyTube bodyTube; - - /** - * Constructor. - * - * @param c parent component - * @param warnings the warning set - * @throws IllegalArgumentException thrown if c is null - */ - public BodyTubeHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent component of a body tube may not be null."); - } - bodyTube = new BodyTube(); - if (isCompatible(c, BodyTube.class, warnings)) { - c.addChild(bodyTube); - } - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { - return new AttachedPartsHandler(document, bodyTube); - } - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.OD.equals(element)) { - bodyTube.setOuterRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - } - if (RocksimCommonConstants.ID.equals(element)) { - final double r = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS; - bodyTube.setInnerRadius(r); - } - if (RocksimCommonConstants.LEN.equals(element)) { - bodyTube.setLength(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if (RocksimCommonConstants.FINISH_CODE.equals(element)) { - bodyTube.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); - } - if (RocksimCommonConstants.IS_MOTOR_MOUNT.equals(element)) { - bodyTube.setMotorMount("1".equals(content)); - } - if (RocksimCommonConstants.ENGINE_OVERHANG.equals(element)) { - bodyTube.setMotorOverhang(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - /** - * Get the component this handler is working upon. - * - * @return a component - */ - @Override - public BodyTube getComponent() { - return bodyTube; - } - - /** - * Get the required type of material for this component. - * - * @return BULK - */ - public Material.Type getMaterialType() { - return Material.Type.BULK; - } + /** + * The OpenRocket BodyTube. + */ + private final BodyTube bodyTube; + + /** + * Constructor. + * + * @param c parent component + * @param warnings the warning set + * @throws IllegalArgumentException thrown if c is null + */ + public BodyTubeHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent component of a body tube may not be null."); + } + bodyTube = new BodyTube(); + if (isCompatible(c, BodyTube.class, warnings)) { + c.addChild(bodyTube); + } + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { + return new AttachedPartsHandler(context, bodyTube); + } + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.OD.equals(element)) { + bodyTube.setOuterRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + } + if (RocksimCommonConstants.ID.equals(element)) { + final double r = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS; + bodyTube.setInnerRadius(r); + } + if (RocksimCommonConstants.LEN.equals(element)) { + bodyTube.setLength(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if (RocksimCommonConstants.FINISH_CODE.equals(element)) { + bodyTube.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); + } + if (RocksimCommonConstants.IS_MOTOR_MOUNT.equals(element)) { + bodyTube.setMotorMount("1".equals(content)); + } + if (RocksimCommonConstants.ENGINE_OVERHANG.equals(element)) { + bodyTube.setMotorOverhang(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + /** + * Get the component this handler is working upon. + * + * @return a component + */ + @Override + public BodyTube getComponent() { + return bodyTube; + } + + /** + * Get the required type of material for this component. + * + * @return BULK + */ + public Material.Type getMaterialType() { + return Material.Type.BULK; + } } - diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java index 51d0863cc..04ead9a45 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/FinSetHandler.java @@ -9,7 +9,7 @@ import java.util.HashMap; import java.util.List; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimFinishCode; import net.sf.openrocket.file.rocksim.RocksimLocationMode; @@ -35,372 +35,368 @@ import org.xml.sax.SAXException; * to construct the corresponding OpenRocket FinSet. */ class FinSetHandler extends AbstractElementHandler { - /** - * The parent component. - */ - private final RocketComponent component; - - /** - * The name of the fin. - */ - private String name; - /** - * The Rocksim fin shape code. - */ - private int shapeCode; - /** - * The location of the fin on its parent. - */ - private double location = 0.0d; - /** - * The OpenRocket Position which gives the absolute/relative positioning for location. - */ - private RocketComponent.Position position; - /** - * The number of fins in this fin set. - */ - private int finCount; - /** - * The length of the root chord. - */ - private double rootChord = 0.0d; - /** - * The length of the tip chord. - */ - private double tipChord = 0.0d; - /** - * The length of the mid-chord (aka height). - */ - private double midChordLen = 0.0d; - /** - * The distance of the leading edge from root to top. - */ - private double sweepDistance = 0.0d; - /** - * The angle the fins have been rotated from the y-axis, if looking down the tube, in radians. - */ - private double radialAngle = 0.0d; - /** - * The thickness of the fins. - */ - private double thickness; - /** - * The finish of the fins. - */ - private ExternalComponent.Finish finish; - /** - * The shape of the tip. - */ - private int tipShapeCode; - /** - * The length of the TTW tab. - */ - private double tabLength = 0.0d; - /** - * The depth of the TTW tab. - */ - private double tabDepth = 0.0d; - /** - * The offset of the tab, from the front of the fin. - */ - private double taboffset = 0.0d; - /** - * The elliptical semi-span (height). - */ - private double semiSpan; - /** - * The list of custom points. - */ - private String pointList; - /** - * Override the Cg and mass. - */ - private boolean override = false; - /** - * The overridden mass. - */ - private Double mass = 0d; - /** - * The overridden Cg. - */ - private Double cg = 0d; - /** - * The density of the material in the component. - */ - private Double density = 0d; - /** - * The material name. - */ - private String materialName = ""; - /** - * The Rocksim calculated mass. - */ - private Double calcMass = 0d; - /** - * The Rocksim calculated cg. - */ - private Double calcCg = 0d; - - private final RockSimAppearanceBuilder appearanceBuilder; - - /** - * Constructor. - * - * @param c the parent - * - * @throws IllegalArgumentException thrown if c is null - */ - public FinSetHandler (OpenRocketDocument document, RocketComponent c) throws IllegalArgumentException { - if (c == null) { - throw new IllegalArgumentException("The parent component of a fin set may not be null."); - } - appearanceBuilder = new RockSimAppearanceBuilder( document ); - component = c; - } - - @Override - public ElementHandler openElement (String element, HashMap attributes, WarningSet warnings) { - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement (String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - try { - if (RocksimCommonConstants.NAME.equals(element)) { - name = content; - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - materialName = content; - } - if (RocksimCommonConstants.FINISH_CODE.equals(element)) { - finish = RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket(); - } - if (RocksimCommonConstants.XB.equals(element)) { - location = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.LOCATION_MODE.equals(element)) { - position = RocksimLocationMode.fromCode(Integer.parseInt(content)).asOpenRocket(); - } - if (RocksimCommonConstants.FIN_COUNT.equals(element)) { - finCount = Integer.parseInt(content); - } - if (RocksimCommonConstants.ROOT_CHORD.equals(element)) { - rootChord = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.TIP_CHORD.equals(element)) { - tipChord = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.SEMI_SPAN.equals(element)) { - semiSpan = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if ("MidChordLen".equals(element)) { - midChordLen = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.SWEEP_DISTANCE.equals(element)) { - sweepDistance = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.THICKNESS.equals(element)) { - thickness = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.TIP_SHAPE_CODE.equals(element)) { - tipShapeCode = Integer.parseInt(content); - } - if (RocksimCommonConstants.TAB_LENGTH.equals(element)) { - tabLength = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.TAB_DEPTH.equals(element)) { - tabDepth = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.TAB_OFFSET.equals(element)) { - taboffset = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) { - radialAngle = Double.parseDouble(content); - } - if (RocksimCommonConstants.SHAPE_CODE.equals(element)) { - shapeCode = Integer.parseInt(content); - } - if (RocksimCommonConstants.POINT_LIST.equals(element)) { - pointList = content; - } - if (RocksimCommonConstants.KNOWN_MASS.equals(element)) { - mass = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); - } - if (RocksimCommonConstants.DENSITY.equals(element)) { - density = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_BULK_DENSITY); - } - if (RocksimCommonConstants.KNOWN_CG.equals(element)) { - cg = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); - } - if (RocksimCommonConstants.USE_KNOWN_CG.equals(element)) { - override = "1".equals(content); - } - if (RocksimCommonConstants.CALC_MASS.equals(element)) { - calcMass = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS; - } - if (RocksimCommonConstants.CALC_CG.equals(element)) { - calcCg = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - - appearanceBuilder.processElement(element, content, warnings); - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - @Override - public void endHandler (String element, HashMap attributes, - String content, WarningSet warnings) throws SAXException { - //Create the fin set and correct for overrides and actual material densities - final FinSet finSet = asOpenRocket(warnings); - - finSet.setAppearance(appearanceBuilder.getAppearance()); - - if (component.isCompatible(finSet)) { - BaseHandler.setOverride(finSet, override, mass, cg); - if (!override && finSet.getCrossSection().equals(FinSet.CrossSection.AIRFOIL)) { - //Override mass anyway. This is done only for AIRFOIL because Rocksim does not compute different - //mass/cg for different cross sections, but OpenRocket does. This can lead to drastic differences - //in mass. To counteract that, the cross section value is retained but the mass/cg is overridden - //with the calculated values from Rocksim. This will best approximate the Rocksim design in OpenRocket. - BaseHandler.setOverride(finSet, true, calcMass, calcCg); - } - BaseHandler.updateComponentMaterial(finSet, materialName, Material.Type.BULK, density); - component.addChild(finSet); - } - else { - warnings.add(finSet.getComponentName() + " can not be attached to " - + component.getComponentName() + ", ignoring component."); - } - } - - - /** - * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's FinSet. - * - * @param warnings the warning set to convey incompatibilities to the user - * - * @return a FinSet instance - */ - public FinSet asOpenRocket (WarningSet warnings) { - FinSet result; - - if (shapeCode == 0) { - //Trapezoidal - result = new TrapezoidFinSet(); - ((TrapezoidFinSet) result).setFinShape(rootChord, tipChord, sweepDistance, semiSpan, thickness); - } - else if (shapeCode == 1) { - //Elliptical - result = new EllipticalFinSet(); - ((EllipticalFinSet) result).setHeight(semiSpan); - ((EllipticalFinSet) result).setLength(rootChord); - } - else if (shapeCode == 2) { - - result = new FreeformFinSet(); - try { - ((FreeformFinSet) result).setPoints(toCoordinates(pointList, warnings)); - } - catch (IllegalFinPointException e) { - warnings.add("Illegal fin point set. " + e.getMessage() + " Ignoring."); - } - } - else { - return null; - } - result.setThickness(thickness); - result.setName(name); - result.setFinCount(finCount); - result.setFinish(finish); - //All TTW tabs in Rocksim are relative to the front of the fin. - result.setTabRelativePosition(FinSet.TabRelativePosition.FRONT); - result.setTabHeight(tabDepth); - result.setTabLength(tabLength); - result.setTabShift(taboffset); - result.setBaseRotation(radialAngle); - result.setCrossSection(convertTipShapeCode(tipShapeCode)); - result.setRelativePosition(position); - PositionDependentHandler.setLocation(result, position, location); - return result; - - } - - /** - * Convert a Rocksim string that represents fin plan points into an array of OpenRocket coordinates. - * - * @param pointList a comma and pipe delimited string of X,Y coordinates from Rocksim. This is of the format: - *
x0,y0|x1,y1|x2,y2|... 
- * @param warnings the warning set to convey incompatibilities to the user - * - * @return an array of OpenRocket Coordinates - */ - private Coordinate[] toCoordinates (String pointList, WarningSet warnings) { - List result = new ArrayList(); - if (pointList != null && pointList.length() > 0) { - String[] points = pointList.split("\\Q|\\E"); - for (String point : points) { - String[] aPoint = point.split(","); - try { - if (aPoint.length > 1) { - Coordinate c = new Coordinate( - Double.parseDouble(aPoint[0]) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH, - Double.parseDouble(aPoint[1]) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - result.add(c); - } - else { - warnings.add("Invalid fin point pair."); - } - } - catch (NumberFormatException nfe) { - warnings.add("Fin point not in numeric format."); - } - } - if (!result.isEmpty()) { - //OpenRocket requires fin plan points be ordered from leading root chord to trailing root chord in the - //Coordinate array. - Coordinate last = result.get(result.size() - 1); - if (last.x == 0 && last.y == 0) { - Collections.reverse(result); - } - } - } - final Coordinate[] coords = new Coordinate[result.size()]; - return result.toArray(coords); - } - - - /** - * Convert a Rocksim tip shape to an OpenRocket CrossSection. - * - * @param tipShape the tip shape code from Rocksim - * - * @return a CrossSection instance - */ - public static FinSet.CrossSection convertTipShapeCode (int tipShape) { - switch (tipShape) { - case 0: - return FinSet.CrossSection.SQUARE; - case 1: - return FinSet.CrossSection.ROUNDED; - case 2: - return FinSet.CrossSection.AIRFOIL; - default: - return FinSet.CrossSection.SQUARE; - } - } - - public static int convertTipShapeCode (FinSet.CrossSection cs) { - if (FinSet.CrossSection.ROUNDED.equals(cs)) { - return 1; - } - if (FinSet.CrossSection.AIRFOIL.equals(cs)) { - return 2; - } - return 0; - } - + /** + * The parent component. + */ + private final RocketComponent component; + + /** + * The name of the fin. + */ + private String name; + /** + * The Rocksim fin shape code. + */ + private int shapeCode; + /** + * The location of the fin on its parent. + */ + private double location = 0.0d; + /** + * The OpenRocket Position which gives the absolute/relative positioning for location. + */ + private RocketComponent.Position position; + /** + * The number of fins in this fin set. + */ + private int finCount; + /** + * The length of the root chord. + */ + private double rootChord = 0.0d; + /** + * The length of the tip chord. + */ + private double tipChord = 0.0d; + /** + * The length of the mid-chord (aka height). + */ + private double midChordLen = 0.0d; + /** + * The distance of the leading edge from root to top. + */ + private double sweepDistance = 0.0d; + /** + * The angle the fins have been rotated from the y-axis, if looking down the tube, in radians. + */ + private double radialAngle = 0.0d; + /** + * The thickness of the fins. + */ + private double thickness; + /** + * The finish of the fins. + */ + private ExternalComponent.Finish finish; + /** + * The shape of the tip. + */ + private int tipShapeCode; + /** + * The length of the TTW tab. + */ + private double tabLength = 0.0d; + /** + * The depth of the TTW tab. + */ + private double tabDepth = 0.0d; + /** + * The offset of the tab, from the front of the fin. + */ + private double taboffset = 0.0d; + /** + * The elliptical semi-span (height). + */ + private double semiSpan; + /** + * The list of custom points. + */ + private String pointList; + /** + * Override the Cg and mass. + */ + private boolean override = false; + /** + * The overridden mass. + */ + private Double mass = 0d; + /** + * The overridden Cg. + */ + private Double cg = 0d; + /** + * The density of the material in the component. + */ + private Double density = 0d; + /** + * The material name. + */ + private String materialName = ""; + /** + * The Rocksim calculated mass. + */ + private Double calcMass = 0d; + /** + * The Rocksim calculated cg. + */ + private Double calcCg = 0d; + + private final RockSimAppearanceBuilder appearanceBuilder; + + /** + * Constructor. + * + * @param c the parent + * + * @throws IllegalArgumentException thrown if c is null + */ + public FinSetHandler(DocumentLoadingContext context, RocketComponent c) throws IllegalArgumentException { + if (c == null) { + throw new IllegalArgumentException("The parent component of a fin set may not be null."); + } + appearanceBuilder = new RockSimAppearanceBuilder(context); + component = c; + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + try { + if (RocksimCommonConstants.NAME.equals(element)) { + name = content; + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + materialName = content; + } + if (RocksimCommonConstants.FINISH_CODE.equals(element)) { + finish = RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket(); + } + if (RocksimCommonConstants.XB.equals(element)) { + location = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.LOCATION_MODE.equals(element)) { + position = RocksimLocationMode.fromCode(Integer.parseInt(content)).asOpenRocket(); + } + if (RocksimCommonConstants.FIN_COUNT.equals(element)) { + finCount = Integer.parseInt(content); + } + if (RocksimCommonConstants.ROOT_CHORD.equals(element)) { + rootChord = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.TIP_CHORD.equals(element)) { + tipChord = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.SEMI_SPAN.equals(element)) { + semiSpan = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if ("MidChordLen".equals(element)) { + midChordLen = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.SWEEP_DISTANCE.equals(element)) { + sweepDistance = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.THICKNESS.equals(element)) { + thickness = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.TIP_SHAPE_CODE.equals(element)) { + tipShapeCode = Integer.parseInt(content); + } + if (RocksimCommonConstants.TAB_LENGTH.equals(element)) { + tabLength = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.TAB_DEPTH.equals(element)) { + tabDepth = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.TAB_OFFSET.equals(element)) { + taboffset = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) { + radialAngle = Double.parseDouble(content); + } + if (RocksimCommonConstants.SHAPE_CODE.equals(element)) { + shapeCode = Integer.parseInt(content); + } + if (RocksimCommonConstants.POINT_LIST.equals(element)) { + pointList = content; + } + if (RocksimCommonConstants.KNOWN_MASS.equals(element)) { + mass = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); + } + if (RocksimCommonConstants.DENSITY.equals(element)) { + density = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_BULK_DENSITY); + } + if (RocksimCommonConstants.KNOWN_CG.equals(element)) { + cg = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); + } + if (RocksimCommonConstants.USE_KNOWN_CG.equals(element)) { + override = "1".equals(content); + } + if (RocksimCommonConstants.CALC_MASS.equals(element)) { + calcMass = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS; + } + if (RocksimCommonConstants.CALC_CG.equals(element)) { + calcCg = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + + appearanceBuilder.processElement(element, content, warnings); + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + @Override + public void endHandler(String element, HashMap attributes, + String content, WarningSet warnings) throws SAXException { + //Create the fin set and correct for overrides and actual material densities + final FinSet finSet = asOpenRocket(warnings); + + finSet.setAppearance(appearanceBuilder.getAppearance()); + + if (component.isCompatible(finSet)) { + BaseHandler.setOverride(finSet, override, mass, cg); + if (!override && finSet.getCrossSection().equals(FinSet.CrossSection.AIRFOIL)) { + //Override mass anyway. This is done only for AIRFOIL because Rocksim does not compute different + //mass/cg for different cross sections, but OpenRocket does. This can lead to drastic differences + //in mass. To counteract that, the cross section value is retained but the mass/cg is overridden + //with the calculated values from Rocksim. This will best approximate the Rocksim design in OpenRocket. + BaseHandler.setOverride(finSet, true, calcMass, calcCg); + } + BaseHandler.updateComponentMaterial(finSet, materialName, Material.Type.BULK, density); + component.addChild(finSet); + } + else { + warnings.add(finSet.getComponentName() + " can not be attached to " + + component.getComponentName() + ", ignoring component."); + } + } + + + /** + * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's FinSet. + * + * @param warnings the warning set to convey incompatibilities to the user + * + * @return a FinSet instance + */ + public FinSet asOpenRocket(WarningSet warnings) { + FinSet result; + + if (shapeCode == 0) { + //Trapezoidal + result = new TrapezoidFinSet(); + ((TrapezoidFinSet) result).setFinShape(rootChord, tipChord, sweepDistance, semiSpan, thickness); + } + else if (shapeCode == 1) { + //Elliptical + result = new EllipticalFinSet(); + ((EllipticalFinSet) result).setHeight(semiSpan); + ((EllipticalFinSet) result).setLength(rootChord); + } + else if (shapeCode == 2) { + + result = new FreeformFinSet(); + try { + ((FreeformFinSet) result).setPoints(toCoordinates(pointList, warnings)); + } catch (IllegalFinPointException e) { + warnings.add("Illegal fin point set. " + e.getMessage() + " Ignoring."); + } + } + else { + return null; + } + result.setThickness(thickness); + result.setName(name); + result.setFinCount(finCount); + result.setFinish(finish); + //All TTW tabs in Rocksim are relative to the front of the fin. + result.setTabRelativePosition(FinSet.TabRelativePosition.FRONT); + result.setTabHeight(tabDepth); + result.setTabLength(tabLength); + result.setTabShift(taboffset); + result.setBaseRotation(radialAngle); + result.setCrossSection(convertTipShapeCode(tipShapeCode)); + result.setRelativePosition(position); + PositionDependentHandler.setLocation(result, position, location); + return result; + + } + + /** + * Convert a Rocksim string that represents fin plan points into an array of OpenRocket coordinates. + * + * @param pointList a comma and pipe delimited string of X,Y coordinates from Rocksim. This is of the format: + *
x0,y0|x1,y1|x2,y2|... 
+ * @param warnings the warning set to convey incompatibilities to the user + * + * @return an array of OpenRocket Coordinates + */ + private Coordinate[] toCoordinates(String pointList, WarningSet warnings) { + List result = new ArrayList(); + if (pointList != null && pointList.length() > 0) { + String[] points = pointList.split("\\Q|\\E"); + for (String point : points) { + String[] aPoint = point.split(","); + try { + if (aPoint.length > 1) { + Coordinate c = new Coordinate( + Double.parseDouble(aPoint[0]) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH, + Double.parseDouble(aPoint[1]) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + result.add(c); + } + else { + warnings.add("Invalid fin point pair."); + } + } catch (NumberFormatException nfe) { + warnings.add("Fin point not in numeric format."); + } + } + if (!result.isEmpty()) { + //OpenRocket requires fin plan points be ordered from leading root chord to trailing root chord in the + //Coordinate array. + Coordinate last = result.get(result.size() - 1); + if (last.x == 0 && last.y == 0) { + Collections.reverse(result); + } + } + } + final Coordinate[] coords = new Coordinate[result.size()]; + return result.toArray(coords); + } + + + /** + * Convert a Rocksim tip shape to an OpenRocket CrossSection. + * + * @param tipShape the tip shape code from Rocksim + * + * @return a CrossSection instance + */ + public static FinSet.CrossSection convertTipShapeCode(int tipShape) { + switch (tipShape) { + case 0: + return FinSet.CrossSection.SQUARE; + case 1: + return FinSet.CrossSection.ROUNDED; + case 2: + return FinSet.CrossSection.AIRFOIL; + default: + return FinSet.CrossSection.SQUARE; + } + } + + public static int convertTipShapeCode(FinSet.CrossSection cs) { + if (FinSet.CrossSection.ROUNDED.equals(cs)) { + return 1; + } + if (FinSet.CrossSection.AIRFOIL.equals(cs)) { + return 2; + } + return 0; + } + } - diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/InnerBodyTubeHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/InnerBodyTubeHandler.java index dd8bc4fd3..d6e0f2e98 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/InnerBodyTubeHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/InnerBodyTubeHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; @@ -20,104 +20,103 @@ import org.xml.sax.SAXException; * A SAX handler for Rocksim inside tubes. */ class InnerBodyTubeHandler extends PositionDependentHandler { - - /** - * The OpenRocket InnerTube instance. - */ - private final InnerTube bodyTube; - - /** - * Constructor. - * - * @param c the parent component - * @param warnings the warning set - * @throws IllegalArgumentException thrown if c is null - */ - public InnerBodyTubeHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent component of an inner tube may not be null."); - } - bodyTube = new InnerTube(); - if (isCompatible(c, InnerTube.class, warnings)) { - c.addChild(bodyTube); - } - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { - return new AttachedPartsHandler(document, bodyTube); - } - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.OD.equals(element)) { - bodyTube.setOuterRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - } - if (RocksimCommonConstants.ID.equals(element)) { - final double r = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS; - bodyTube.setInnerRadius(r); - } - if (RocksimCommonConstants.LEN.equals(element)) { - bodyTube.setLength(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if (RocksimCommonConstants.IS_MOTOR_MOUNT.equals(element)) { - bodyTube.setMotorMount("1".equals(content)); - } - if (RocksimCommonConstants.ENGINE_OVERHANG.equals(element)) { - bodyTube.setMotorOverhang(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) { - bodyTube.setRadialDirection(Double.parseDouble(content)); - } - if (RocksimCommonConstants.RADIAL_LOC.equals(element)) { - bodyTube.setRadialPosition(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - /** - * Get the InnerTube component this handler is working upon. - * - * @return an InnerTube component - */ - @Override - public InnerTube getComponent() { - return bodyTube; - } - - /** - * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not - * public in all components. - * - * @param position the OpenRocket position - */ - @Override - public void setRelativePosition(RocketComponent.Position position) { - bodyTube.setRelativePosition(position); - } - - /** - * Get the required type of material for this component. - * - * @return BULK - */ - @Override - public Material.Type getMaterialType() { - return Material.Type.BULK; - } - + + /** + * The OpenRocket InnerTube instance. + */ + private final InnerTube bodyTube; + + /** + * Constructor. + * + * @param c the parent component + * @param warnings the warning set + * @throws IllegalArgumentException thrown if c is null + */ + public InnerBodyTubeHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent component of an inner tube may not be null."); + } + bodyTube = new InnerTube(); + if (isCompatible(c, InnerTube.class, warnings)) { + c.addChild(bodyTube); + } + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { + return new AttachedPartsHandler(context, bodyTube); + } + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.OD.equals(element)) { + bodyTube.setOuterRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + } + if (RocksimCommonConstants.ID.equals(element)) { + final double r = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS; + bodyTube.setInnerRadius(r); + } + if (RocksimCommonConstants.LEN.equals(element)) { + bodyTube.setLength(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if (RocksimCommonConstants.IS_MOTOR_MOUNT.equals(element)) { + bodyTube.setMotorMount("1".equals(content)); + } + if (RocksimCommonConstants.ENGINE_OVERHANG.equals(element)) { + bodyTube.setMotorOverhang(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) { + bodyTube.setRadialDirection(Double.parseDouble(content)); + } + if (RocksimCommonConstants.RADIAL_LOC.equals(element)) { + bodyTube.setRadialPosition(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + /** + * Get the InnerTube component this handler is working upon. + * + * @return an InnerTube component + */ + @Override + public InnerTube getComponent() { + return bodyTube; + } + + /** + * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not + * public in all components. + * + * @param position the OpenRocket position + */ + @Override + public void setRelativePosition(RocketComponent.Position position) { + bodyTube.setRelativePosition(position); + } + + /** + * Get the required type of material for this component. + * + * @return BULK + */ + @Override + public Material.Type getMaterialType() { + return Material.Type.BULK; + } + } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/LaunchLugHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/LaunchLugHandler.java index 4b9361e49..1573d69d8 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/LaunchLugHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/LaunchLugHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimFinishCode; import net.sf.openrocket.file.simplesax.ElementHandler; @@ -21,95 +21,93 @@ import org.xml.sax.SAXException; * The SAX handler for Rocksim Launch Lugs. */ class LaunchLugHandler extends PositionDependentHandler { - - /** - * The OpenRocket LaunchLug instance. - */ - private final LaunchLug lug; - - /** - * Constructor. - * - * @param c the parent - * @param warnings the warning set - * - * @throws IllegalArgumentException thrown if c is null - */ - public LaunchLugHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent component of a launch lug may not be null."); - } - lug = new LaunchLug(); - if (isCompatible(c, LaunchLug.class, warnings)) { - c.addChild(lug); - } - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.OD.equals(element)) { - lug.setOuterRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if (RocksimCommonConstants.ID.equals(element)) { - lug.setInnerRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if (RocksimCommonConstants.LEN.equals(element)) { - lug.setLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) { - lug.setRadialDirection(Double.parseDouble(content)); - } - if (RocksimCommonConstants.FINISH_CODE.equals(element)) { - lug.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - /** - * Get the LaunchLug component this handler is working upon. - * - * @return a LaunchLug component - */ - @Override - public LaunchLug getComponent() { - return lug; - } - - /** - * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not - * public in all components. - * - * @param position the OpenRocket position - */ - @Override - public void setRelativePosition(RocketComponent.Position position) { - lug.setRelativePosition(position); - } - - /** - * Get the required type of material for this component. - * - * @return BULK - */ - @Override - public Material.Type getMaterialType() { - return Material.Type.BULK; - } + + /** + * The OpenRocket LaunchLug instance. + */ + private final LaunchLug lug; + + /** + * Constructor. + * + * @param c the parent + * @param warnings the warning set + * + * @throws IllegalArgumentException thrown if c is null + */ + public LaunchLugHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent component of a launch lug may not be null."); + } + lug = new LaunchLug(); + if (isCompatible(c, LaunchLug.class, warnings)) { + c.addChild(lug); + } + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.OD.equals(element)) { + lug.setOuterRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if (RocksimCommonConstants.ID.equals(element)) { + lug.setInnerRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if (RocksimCommonConstants.LEN.equals(element)) { + lug.setLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + if (RocksimCommonConstants.RADIAL_ANGLE.equals(element)) { + lug.setRadialDirection(Double.parseDouble(content)); + } + if (RocksimCommonConstants.FINISH_CODE.equals(element)) { + lug.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + /** + * Get the LaunchLug component this handler is working upon. + * + * @return a LaunchLug component + */ + @Override + public LaunchLug getComponent() { + return lug; + } + + /** + * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not + * public in all components. + * + * @param position the OpenRocket position + */ + @Override + public void setRelativePosition(RocketComponent.Position position) { + lug.setRelativePosition(position); + } + + /** + * Get the required type of material for this component. + * + * @return BULK + */ + @Override + public Material.Type getMaterialType() { + return Material.Type.BULK; + } } - diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java index 90e680dd6..33890dce3 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimDensityType; import net.sf.openrocket.file.simplesax.ElementHandler; @@ -24,185 +24,184 @@ import org.xml.sax.SAXException; * A SAX handler for Rocksim's MassObject XML type. */ class MassObjectHandler extends PositionDependentHandler { - - /** - * The Rocksim Mass length fudge factor. Rocksim completely exaggerates the length of a mass object to the point - * that it looks ridiculous in OpenRocket. This fudge factor is here merely to get the typical mass object to - * render in the OpenRocket UI with it's bounds mostly inside it's parent. The odd thing about it is that Rocksim - * does not expose the length of a mass object in the UI and actually treats mass objects as point objects - not 3 - * or even 2 dimensional. - */ - public static final int MASS_LEN_FUDGE_FACTOR = 100; - - /** - * The OpenRocket MassComponent - counterpart to the RS MassObject. - */ - private final MassComponent mass; - - /** - * Reference to answer for getComponent(). - */ - private MassObject current; - - /** - * Parent. - */ - private RocketComponent parent; - - /** - * 0 == General, 1 == Shock Cord - */ - private int typeCode = 0; - - /** - * Constructor. l - * - * @param c the parent component - * @param warnings the warning set - * - * @throws IllegalArgumentException thrown if c is null - */ - public MassObjectHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent component of a mass component may not be null."); - } - mass = new MassComponent(); - current = mass; - parent = c; - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - try { - if (RocksimCommonConstants.LEN.equals(element)) { - mass.setLength(Double.parseDouble(content) / (RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.KNOWN_MASS.equals(element)) { - mass.setComponentMass(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); - } - if (RocksimCommonConstants.KNOWN_CG.equals(element)) { - //Setting the CG of the Mass Object to 0 is important because of the different ways that Rocksim and - //OpenRocket treat mass objects. Rocksim treats them as points (even though the data file contains a - //length) and because Rocksim sets the CG of the mass object to really be relative to the front of - //the parent. But that value is already assumed in the position and position value for the component. - //Thus it needs to be set to 0 to say that the mass object's CG is at the point of the mass object. - super.setCG(0); - } - if (RocksimCommonConstants.TYPE_CODE.equals(element)) { - typeCode = Integer.parseInt(content); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - @Override - public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws - SAXException { - if (inferAsShockCord(typeCode, warnings)) { //Shock Cord - mapMassObjectAsShockCord(element, attributes, content, warnings); - } - else { // typeCode == 0 General Mass Object - if (isCompatible(parent, MassComponent.class, warnings)) { - parent.addChild(mass); - } - super.endHandler(element, attributes, content, warnings); - } - } - - /** - * Rocksim does not have a separate entity for Shock Cords. It has to be inferred. Sometimes the typeCode - * indicates it's a shock cord, but most times it does not. This is due to bugs in the Rocksim Component and - * Material databases. Try to infer a shock cord based on it's length and it's material type. It's somewhat - * arbitrary, but if the mass object's length is more than twice the length of it's parent component and it's a LINE - * material, then assume a shock cord. - * - * @param theTypeCode the code from the RKT XML file - * - * @return true if we think it's a shock cord - */ - private boolean inferAsShockCord(int theTypeCode, WarningSet warnings) { - return (theTypeCode == 1 || (mass.getLength() >= 2 * parent.getLength() && RocksimDensityType.ROCKSIM_LINE - .equals(getDensityType()))) && isCompatible(parent, ShockCord.class, warnings, true); - } - - /** - * If it appears that the mass object is a shock cord, then create an OR shock cord instance. - * - * @param element the element name - * @param attributes the attributes - * @param content the content of the element - * @param warnings the warning set to store warnings in. - * - * @throws org.xml.sax.SAXException not thrown - */ - private void mapMassObjectAsShockCord(final String element, final HashMap attributes, - final String content, final WarningSet warnings) throws SAXException { - ShockCord cord = new ShockCord(); - current = cord; - if (isCompatible(parent, ShockCord.class, warnings)) { - parent.addChild(cord); - } - super.endHandler(element, attributes, content, warnings); - cord.setName(mass.getName()); - - setOverride(cord, mass.isMassOverridden(), mass.getOverrideMass(), mass.getOverrideCGX()); - - cord.setRadialDirection(mass.getRadialDirection()); - cord.setRadialPosition(mass.getRadialPosition()); - cord.setRadius(mass.getRadius()); - - //Rocksim does not distinguish between total length of the cord and the packed length. Fudge the - //packed length and set the real length. - cord.setCordLength(mass.getLength()); - cord.setLength(cord.getCordLength() / MASS_LEN_FUDGE_FACTOR); - if (parent instanceof Coaxial) { - Coaxial parentCoaxial = (Coaxial) parent; - cord.setRadius(parentCoaxial.getInnerRadius()); - } - } - - /** - * Get the component this handler is working upon. This changes depending upon the type of mass object. - * - * @return a component - */ - @Override - public MassObject getComponent() { - return current; - } - - /** - * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not - * public in all components. - * - * @param position the OpenRocket position - */ - public void setRelativePosition(RocketComponent.Position position) { - current.setRelativePosition(position); - } - - /** - * Get the required type of material for this component. Does not apply to MassComponents, but does apply to Shock - * Cords. - * - * @return LINE - */ - @Override - public Material.Type getMaterialType() { - return Material.Type.LINE; - } - + + /** + * The Rocksim Mass length fudge factor. Rocksim completely exaggerates the length of a mass object to the point + * that it looks ridiculous in OpenRocket. This fudge factor is here merely to get the typical mass object to + * render in the OpenRocket UI with it's bounds mostly inside it's parent. The odd thing about it is that Rocksim + * does not expose the length of a mass object in the UI and actually treats mass objects as point objects - not 3 + * or even 2 dimensional. + */ + public static final int MASS_LEN_FUDGE_FACTOR = 100; + + /** + * The OpenRocket MassComponent - counterpart to the RS MassObject. + */ + private final MassComponent mass; + + /** + * Reference to answer for getComponent(). + */ + private MassObject current; + + /** + * Parent. + */ + private RocketComponent parent; + + /** + * 0 == General, 1 == Shock Cord + */ + private int typeCode = 0; + + /** + * Constructor. l + * + * @param c the parent component + * @param warnings the warning set + * + * @throws IllegalArgumentException thrown if c is null + */ + public MassObjectHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent component of a mass component may not be null."); + } + mass = new MassComponent(); + current = mass; + parent = c; + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + try { + if (RocksimCommonConstants.LEN.equals(element)) { + mass.setLength(Double.parseDouble(content) / (RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.KNOWN_MASS.equals(element)) { + mass.setComponentMass(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); + } + if (RocksimCommonConstants.KNOWN_CG.equals(element)) { + //Setting the CG of the Mass Object to 0 is important because of the different ways that Rocksim and + //OpenRocket treat mass objects. Rocksim treats them as points (even though the data file contains a + //length) and because Rocksim sets the CG of the mass object to really be relative to the front of + //the parent. But that value is already assumed in the position and position value for the component. + //Thus it needs to be set to 0 to say that the mass object's CG is at the point of the mass object. + super.setCG(0); + } + if (RocksimCommonConstants.TYPE_CODE.equals(element)) { + typeCode = Integer.parseInt(content); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + @Override + public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws + SAXException { + if (inferAsShockCord(typeCode, warnings)) { //Shock Cord + mapMassObjectAsShockCord(element, attributes, content, warnings); + } + else { // typeCode == 0 General Mass Object + if (isCompatible(parent, MassComponent.class, warnings)) { + parent.addChild(mass); + } + super.endHandler(element, attributes, content, warnings); + } + } + + /** + * Rocksim does not have a separate entity for Shock Cords. It has to be inferred. Sometimes the typeCode + * indicates it's a shock cord, but most times it does not. This is due to bugs in the Rocksim Component and + * Material databases. Try to infer a shock cord based on it's length and it's material type. It's somewhat + * arbitrary, but if the mass object's length is more than twice the length of it's parent component and it's a LINE + * material, then assume a shock cord. + * + * @param theTypeCode the code from the RKT XML file + * + * @return true if we think it's a shock cord + */ + private boolean inferAsShockCord(int theTypeCode, WarningSet warnings) { + return (theTypeCode == 1 || (mass.getLength() >= 2 * parent.getLength() && RocksimDensityType.ROCKSIM_LINE + .equals(getDensityType()))) && isCompatible(parent, ShockCord.class, warnings, true); + } + + /** + * If it appears that the mass object is a shock cord, then create an OR shock cord instance. + * + * @param element the element name + * @param attributes the attributes + * @param content the content of the element + * @param warnings the warning set to store warnings in. + * + * @throws org.xml.sax.SAXException not thrown + */ + private void mapMassObjectAsShockCord(final String element, final HashMap attributes, + final String content, final WarningSet warnings) throws SAXException { + ShockCord cord = new ShockCord(); + current = cord; + if (isCompatible(parent, ShockCord.class, warnings)) { + parent.addChild(cord); + } + super.endHandler(element, attributes, content, warnings); + cord.setName(mass.getName()); + + setOverride(cord, mass.isMassOverridden(), mass.getOverrideMass(), mass.getOverrideCGX()); + + cord.setRadialDirection(mass.getRadialDirection()); + cord.setRadialPosition(mass.getRadialPosition()); + cord.setRadius(mass.getRadius()); + + //Rocksim does not distinguish between total length of the cord and the packed length. Fudge the + //packed length and set the real length. + cord.setCordLength(mass.getLength()); + cord.setLength(cord.getCordLength() / MASS_LEN_FUDGE_FACTOR); + if (parent instanceof Coaxial) { + Coaxial parentCoaxial = (Coaxial) parent; + cord.setRadius(parentCoaxial.getInnerRadius()); + } + } + + /** + * Get the component this handler is working upon. This changes depending upon the type of mass object. + * + * @return a component + */ + @Override + public MassObject getComponent() { + return current; + } + + /** + * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not + * public in all components. + * + * @param position the OpenRocket position + */ + public void setRelativePosition(RocketComponent.Position position) { + current.setRelativePosition(position); + } + + /** + * Get the required type of material for this component. Does not apply to MassComponents, but does apply to Shock + * Cords. + * + * @return LINE + */ + @Override + public Material.Type getMaterialType() { + return Material.Type.LINE; + } + } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/NoseConeHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/NoseConeHandler.java index f6a4fc05a..a43e1c66a 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/NoseConeHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/NoseConeHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimFinishCode; import net.sf.openrocket.file.rocksim.RocksimNoseConeCode; @@ -23,135 +23,134 @@ import org.xml.sax.SAXException; * The SAX nose cone handler for Rocksim NoseCones. */ class NoseConeHandler extends BaseHandler { - - /** - * The OpenRocket NoseCone. - */ - private final NoseCone noseCone = new NoseCone(); - - /** - * The wall thickness. Used for hollow nose cones. - */ - private double thickness = 0d; - - /** - * Constructor. - * - * @param c the parent component to the nosecone - * @param warnings the warning set - * - * @throws IllegalArgumentException thrown if c is null - */ - public NoseConeHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent component of a nose cone may not be null."); - } - if (isCompatible(c, NoseCone.class, warnings)) { - c.addChild(noseCone); - noseCone.setAftRadiusAutomatic(false); - } - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - //Nose cones in Rocksim may have attached parts - namely Mass Objects - as children. - if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { - return new AttachedPartsHandler(document, noseCone); - } - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, - String content, WarningSet warnings) throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.SHAPE_CODE.equals(element)) { - noseCone.setType(RocksimNoseConeCode.fromCode(Integer.parseInt(content)).asOpenRocket()); - } - if (RocksimCommonConstants.LEN.equals(element)) { - noseCone.setLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.BASE_DIA.equals(element)) { - noseCone.setAftRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if (RocksimCommonConstants.WALL_THICKNESS.equals(element)) { - thickness = Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if (RocksimCommonConstants.SHOULDER_OD.equals(element)) { - noseCone.setAftShoulderRadius(Math.max(0, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if (RocksimCommonConstants.SHOULDER_LEN.equals(element)) { - noseCone.setAftShoulderLength(Math.max(0, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.SHAPE_PARAMETER.equals(element)) { - //The Rocksim ShapeParameter only applies to certain shapes, although it is included - //in the design file for all nose cones. Applying it when it should not be causes oddities so - //a check is made for the allowable shapes. - if (Transition.Shape.POWER.equals(noseCone.getType()) || - Transition.Shape.HAACK.equals(noseCone.getType()) || - Transition.Shape.PARABOLIC.equals(noseCone.getType())) { - noseCone.setShapeParameter(Double.parseDouble(content)); - } - } - if (RocksimCommonConstants.CONSTRUCTION_TYPE.equals(element)) { - int typeCode = Integer.parseInt(content); - if (typeCode == 0) { - //SOLID - noseCone.setFilled(true); - } - else if (typeCode == 1) { - //HOLLOW - noseCone.setFilled(false); - } - } - if (RocksimCommonConstants.FINISH_CODE.equals(element)) { - noseCone.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - @Override - public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.endHandler(element, attributes, content, warnings); - - if (noseCone.isFilled()) { - noseCone.setAftShoulderThickness(noseCone.getAftShoulderRadius()); - } - else { - noseCone.setThickness(thickness); - noseCone.setAftShoulderThickness(thickness); - } - } - - /** - * Get the nose cone component this handler is working upon. - * - * @return a nose cone component - */ - @Override - public NoseCone getComponent() { - return noseCone; - } - - /** - * Get the required type of material for this component. - * - * @return BULK - */ - public Material.Type getMaterialType() { - return Material.Type.BULK; - } - + + /** + * The OpenRocket NoseCone. + */ + private final NoseCone noseCone = new NoseCone(); + + /** + * The wall thickness. Used for hollow nose cones. + */ + private double thickness = 0d; + + /** + * Constructor. + * + * @param c the parent component to the nosecone + * @param warnings the warning set + * + * @throws IllegalArgumentException thrown if c is null + */ + public NoseConeHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent component of a nose cone may not be null."); + } + if (isCompatible(c, NoseCone.class, warnings)) { + c.addChild(noseCone); + noseCone.setAftRadiusAutomatic(false); + } + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + //Nose cones in Rocksim may have attached parts - namely Mass Objects - as children. + if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { + return new AttachedPartsHandler(context, noseCone); + } + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, + String content, WarningSet warnings) throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.SHAPE_CODE.equals(element)) { + noseCone.setType(RocksimNoseConeCode.fromCode(Integer.parseInt(content)).asOpenRocket()); + } + if (RocksimCommonConstants.LEN.equals(element)) { + noseCone.setLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.BASE_DIA.equals(element)) { + noseCone.setAftRadius(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if (RocksimCommonConstants.WALL_THICKNESS.equals(element)) { + thickness = Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if (RocksimCommonConstants.SHOULDER_OD.equals(element)) { + noseCone.setAftShoulderRadius(Math.max(0, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if (RocksimCommonConstants.SHOULDER_LEN.equals(element)) { + noseCone.setAftShoulderLength(Math.max(0, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.SHAPE_PARAMETER.equals(element)) { + //The Rocksim ShapeParameter only applies to certain shapes, although it is included + //in the design file for all nose cones. Applying it when it should not be causes oddities so + //a check is made for the allowable shapes. + if (Transition.Shape.POWER.equals(noseCone.getType()) || + Transition.Shape.HAACK.equals(noseCone.getType()) || + Transition.Shape.PARABOLIC.equals(noseCone.getType())) { + noseCone.setShapeParameter(Double.parseDouble(content)); + } + } + if (RocksimCommonConstants.CONSTRUCTION_TYPE.equals(element)) { + int typeCode = Integer.parseInt(content); + if (typeCode == 0) { + //SOLID + noseCone.setFilled(true); + } + else if (typeCode == 1) { + //HOLLOW + noseCone.setFilled(false); + } + } + if (RocksimCommonConstants.FINISH_CODE.equals(element)) { + noseCone.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + @Override + public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.endHandler(element, attributes, content, warnings); + + if (noseCone.isFilled()) { + noseCone.setAftShoulderThickness(noseCone.getAftShoulderRadius()); + } + else { + noseCone.setThickness(thickness); + noseCone.setAftShoulderThickness(thickness); + } + } + + /** + * Get the nose cone component this handler is working upon. + * + * @return a nose cone component + */ + @Override + public NoseCone getComponent() { + return noseCone; + } + + /** + * Get the required type of material for this component. + * + * @return BULK + */ + public Material.Type getMaterialType() { + return Material.Type.BULK; + } + } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/ParachuteHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/ParachuteHandler.java index 5bef1efab..3c8693cbb 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/ParachuteHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/ParachuteHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; @@ -22,103 +22,101 @@ import org.xml.sax.SAXException; * A SAX handler for Rocksim's Parachute XML type. */ class ParachuteHandler extends RecoveryDeviceHandler { - /** - * The OpenRocket Parachute instance - */ - private final Parachute chute; - /** - * The shroud line density. - */ - private double shroudLineDensity = 0.0d; - - /** - * Constructor. - * - * @param c the parent component - * @param warnings the warning set - * - * @throws IllegalArgumentException thrown if c is null - */ - public ParachuteHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent of a parachute may not be null."); - } - chute = new Parachute(); - if (isCompatible(c, Parachute.class, warnings)) { - c.addChild(chute); - } - } - - /** - * {@inheritDoc} - */ - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - return PlainTextHandler.INSTANCE; - } - - /** - * {@inheritDoc} - */ - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - try { - if (RocksimCommonConstants.DIAMETER.equals(element)) { - chute.setDiameter(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - /* Rocksim doesn't have a packed parachute radius, so we approximate it. */ - double packed; - RocketComponent parent = chute.getParent(); - if (parent instanceof BodyTube) { - packed = ((BodyTube) parent).getOuterRadius() * 0.9; - } - else if (parent instanceof InnerTube) { - packed = ((InnerTube) parent).getInnerRadius() * 0.9; - } - else { - packed = chute.getDiameter() * 0.025; - } - chute.setRadius(packed); - } - if (RocksimCommonConstants.SHROUD_LINE_COUNT.equals(element)) { - chute.setLineCount(Math.max(0, Integer.parseInt(content))); - } - if (RocksimCommonConstants.SHROUD_LINE_LEN.equals(element)) { - chute.setLineLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.SPILL_HOLE_DIA.equals(element)) { - //Not supported in OpenRocket - double spillHoleRadius = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS; - warnings.add("Parachute spill holes are not supported. Ignoring."); - } - if (RocksimCommonConstants.SHROUD_LINE_MASS_PER_MM.equals(element)) { - shroudLineDensity = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LINE_DENSITY; - } - if (RocksimCommonConstants.SHROUD_LINE_MATERIAL.equals(element)) { - chute.setLineMaterial(createCustomMaterial(Material.Type.LINE, content, shroudLineDensity)); - } - if (RocksimCommonConstants.DRAG_COEFFICIENT.equals(element)) { - chute.setCD(Double.parseDouble(content)); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - /** - * Get the component this handler is working upon. - * - * @return a component - */ - public Parachute getComponent() { - return chute; - } - + /** + * The OpenRocket Parachute instance + */ + private final Parachute chute; + /** + * The shroud line density. + */ + private double shroudLineDensity = 0.0d; + + /** + * Constructor. + * + * @param c the parent component + * @param warnings the warning set + * + * @throws IllegalArgumentException thrown if c is null + */ + public ParachuteHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent of a parachute may not be null."); + } + chute = new Parachute(); + if (isCompatible(c, Parachute.class, warnings)) { + c.addChild(chute); + } + } + + /** + * {@inheritDoc} + */ + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + return PlainTextHandler.INSTANCE; + } + + /** + * {@inheritDoc} + */ + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + try { + if (RocksimCommonConstants.DIAMETER.equals(element)) { + chute.setDiameter(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + /* Rocksim doesn't have a packed parachute radius, so we approximate it. */ + double packed; + RocketComponent parent = chute.getParent(); + if (parent instanceof BodyTube) { + packed = ((BodyTube) parent).getOuterRadius() * 0.9; + } + else if (parent instanceof InnerTube) { + packed = ((InnerTube) parent).getInnerRadius() * 0.9; + } + else { + packed = chute.getDiameter() * 0.025; + } + chute.setRadius(packed); + } + if (RocksimCommonConstants.SHROUD_LINE_COUNT.equals(element)) { + chute.setLineCount(Math.max(0, Integer.parseInt(content))); + } + if (RocksimCommonConstants.SHROUD_LINE_LEN.equals(element)) { + chute.setLineLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.SPILL_HOLE_DIA.equals(element)) { + //Not supported in OpenRocket + double spillHoleRadius = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS; + warnings.add("Parachute spill holes are not supported. Ignoring."); + } + if (RocksimCommonConstants.SHROUD_LINE_MASS_PER_MM.equals(element)) { + shroudLineDensity = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LINE_DENSITY; + } + if (RocksimCommonConstants.SHROUD_LINE_MATERIAL.equals(element)) { + chute.setLineMaterial(createCustomMaterial(Material.Type.LINE, content, shroudLineDensity)); + } + if (RocksimCommonConstants.DRAG_COEFFICIENT.equals(element)) { + chute.setCD(Double.parseDouble(content)); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + /** + * Get the component this handler is working upon. + * + * @return a component + */ + public Parachute getComponent() { + return chute; + } + } - diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java index 8ecc829eb..2cf4a6130 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/PositionDependentHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimLocationMode; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -20,73 +20,74 @@ import org.xml.sax.SAXException; * @param the specific position dependent RocketComponent subtype for which the concrete handler can create */ public abstract class PositionDependentHandler extends BaseHandler { - - /** Temporary position value. */ - private Double positionValue = 0d; - - /** Temporary position. */ - private RocketComponent.Position position = RocketComponent.Position.TOP; - - public PositionDependentHandler( OpenRocketDocument document ) { - super(document); - } - /** - * {@inheritDoc} - */ - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - if (RocksimCommonConstants.XB.equals(element)) { - positionValue = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.LOCATION_MODE.equals(element)) { - position = RocksimLocationMode.fromCode(Integer.parseInt( - content)).asOpenRocket(); - } - } - - /** - * This method sets the position information onto the component. Rocksim splits the location/position - * information into two disparate data elements. Both pieces of data are necessary to map into OpenRocket's - * position model. - * - * @param element the element name - * @param attributes the attributes - * @param content the content of the element - * @param warnings the warning set to store warnings in. - * @throws org.xml.sax.SAXException not thrown - */ - @Override - public void endHandler(String element, HashMap attributes, - String content, WarningSet warnings) throws SAXException { - super.endHandler(element, attributes, content, warnings); - setRelativePosition(position); - setLocation(getComponent(), position, positionValue); - } - - /** - * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not - * public in all components. - * - * @param position the OpenRocket position - */ - protected abstract void setRelativePosition(RocketComponent.Position position); - - /** - * Set the position of a component. - * - * @param component the component - * @param position the relative position - * @param location the actual position value - */ - public static void setLocation(RocketComponent component, RocketComponent.Position position, double location) { - if (position.equals(RocketComponent.Position.BOTTOM)) { - component.setPositionValue(-1d * location); - } - else { - component.setPositionValue(location); - } - } - + + /** Temporary position value. */ + private Double positionValue = 0d; + + /** Temporary position. */ + private RocketComponent.Position position = RocketComponent.Position.TOP; + + public PositionDependentHandler(DocumentLoadingContext context) { + super(context); + } + + /** + * {@inheritDoc} + */ + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + if (RocksimCommonConstants.XB.equals(element)) { + positionValue = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.LOCATION_MODE.equals(element)) { + position = RocksimLocationMode.fromCode(Integer.parseInt( + content)).asOpenRocket(); + } + } + + /** + * This method sets the position information onto the component. Rocksim splits the location/position + * information into two disparate data elements. Both pieces of data are necessary to map into OpenRocket's + * position model. + * + * @param element the element name + * @param attributes the attributes + * @param content the content of the element + * @param warnings the warning set to store warnings in. + * @throws org.xml.sax.SAXException not thrown + */ + @Override + public void endHandler(String element, HashMap attributes, + String content, WarningSet warnings) throws SAXException { + super.endHandler(element, attributes, content, warnings); + setRelativePosition(position); + setLocation(getComponent(), position, positionValue); + } + + /** + * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not + * public in all components. + * + * @param position the OpenRocket position + */ + protected abstract void setRelativePosition(RocketComponent.Position position); + + /** + * Set the position of a component. + * + * @param component the component + * @param position the relative position + * @param location the actual position value + */ + public static void setLocation(RocketComponent component, RocketComponent.Position position, double location) { + if (position.equals(RocketComponent.Position.BOTTOM)) { + component.setPositionValue(-1d * location); + } + else { + component.setPositionValue(location); + } + } + } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RecoveryDeviceHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/RecoveryDeviceHandler.java index c7a765b10..b175cc4c7 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RecoveryDeviceHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RecoveryDeviceHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimDensityType; import net.sf.openrocket.material.Material; @@ -23,100 +23,99 @@ import org.xml.sax.SAXException; * @param either a Streamer or Parachute */ public abstract class RecoveryDeviceHandler extends PositionDependentHandler { - - /** - * The thickness. Not used by every component, and some component handlers may parse it for their own purposes. - */ - private double thickness = 0d; - /** - * The Rocksim calculated mass. Used only when not overridden and when Rocksim says density == 0 (Rocksim bug). - */ - private Double calcMass = 0d; - - public RecoveryDeviceHandler( OpenRocketDocument document ) { - super(document); - } - - /** - * {@inheritDoc} - */ - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.THICKNESS.equals(element)) { - thickness = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; - } - if (RocksimCommonConstants.CALC_MASS.equals(element)) { - calcMass = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - - /** - * Compute the density. Rocksim does strange things with densities. For some streamer material it's in cubic, - * rather than square, units. In those cases it needs to be converted to an appropriate SURFACE material density. - * - * @param type the rocksim density - * @param rawDensity the density as specified in the Rocksim design file - * @return a value in OpenRocket SURFACE density units - */ - protected double computeDensity(RocksimDensityType type, double rawDensity) { - - double result; - - if (rawDensity > 0d) { - //ROCKSIM_SURFACE is a square area density; compute normally - //ROCKSIM_LINE is a single length dimension (kg/m) but Rocksim ignores thickness for this type and treats - //it like a SURFACE. - if (RocksimDensityType.ROCKSIM_SURFACE.equals(type) || RocksimDensityType.ROCKSIM_LINE.equals(type)) { - result = rawDensity / RocksimDensityType.ROCKSIM_SURFACE.asOpenRocket(); - } - //ROCKSIM_BULK is a cubic area density; multiple by thickness to make per square area; the result, when - //multiplied by the area will then equal Rocksim's computed mass. - else { - result = (rawDensity / type.asOpenRocket()) * thickness; - } - } - else { - result = calcMass / getComponent().getArea(); - //A Rocksim bug on streamers/parachutes results in a 0 density at times. When that is detected, try - //to compute an approximate density from Rocksim's computed mass. - if (RocksimDensityType.ROCKSIM_BULK.equals(type)) { - //ROCKSIM_BULK is a cubic area density; multiple by thickness to make per square area - result *= thickness; - } - } - return result; - } - - /** - * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not - * public in all components. - * - * @param position the OpenRocket position - */ - @Override - public void setRelativePosition(RocketComponent.Position position) { - getComponent().setRelativePosition(position); - } - - /** - * Get the required type of material for this component. This is the OpenRocket type, which does NOT always - * correspond to Rocksim. Some streamer material is defined as BULK in the Rocksim file. In those cases - * it is adjusted in this handler. - * - * @return SURFACE - */ - @Override - public Material.Type getMaterialType() { - return Material.Type.SURFACE; - } - + + /** + * The thickness. Not used by every component, and some component handlers may parse it for their own purposes. + */ + private double thickness = 0d; + /** + * The Rocksim calculated mass. Used only when not overridden and when Rocksim says density == 0 (Rocksim bug). + */ + private Double calcMass = 0d; + + public RecoveryDeviceHandler(DocumentLoadingContext context) { + super(context); + } + + /** + * {@inheritDoc} + */ + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.THICKNESS.equals(element)) { + thickness = Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH; + } + if (RocksimCommonConstants.CALC_MASS.equals(element)) { + calcMass = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_MASS); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + + /** + * Compute the density. Rocksim does strange things with densities. For some streamer material it's in cubic, + * rather than square, units. In those cases it needs to be converted to an appropriate SURFACE material density. + * + * @param type the rocksim density + * @param rawDensity the density as specified in the Rocksim design file + * @return a value in OpenRocket SURFACE density units + */ + protected double computeDensity(RocksimDensityType type, double rawDensity) { + + double result; + + if (rawDensity > 0d) { + //ROCKSIM_SURFACE is a square area density; compute normally + //ROCKSIM_LINE is a single length dimension (kg/m) but Rocksim ignores thickness for this type and treats + //it like a SURFACE. + if (RocksimDensityType.ROCKSIM_SURFACE.equals(type) || RocksimDensityType.ROCKSIM_LINE.equals(type)) { + result = rawDensity / RocksimDensityType.ROCKSIM_SURFACE.asOpenRocket(); + } + //ROCKSIM_BULK is a cubic area density; multiple by thickness to make per square area; the result, when + //multiplied by the area will then equal Rocksim's computed mass. + else { + result = (rawDensity / type.asOpenRocket()) * thickness; + } + } + else { + result = calcMass / getComponent().getArea(); + //A Rocksim bug on streamers/parachutes results in a 0 density at times. When that is detected, try + //to compute an approximate density from Rocksim's computed mass. + if (RocksimDensityType.ROCKSIM_BULK.equals(type)) { + //ROCKSIM_BULK is a cubic area density; multiple by thickness to make per square area + result *= thickness; + } + } + return result; + } + + /** + * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not + * public in all components. + * + * @param position the OpenRocket position + */ + @Override + public void setRelativePosition(RocketComponent.Position position) { + getComponent().setRelativePosition(position); + } + + /** + * Get the required type of material for this component. This is the OpenRocket type, which does NOT always + * correspond to Rocksim. Some streamer material is defined as BULK in the Rocksim file. In those cases + * it is adjusted in this handler. + * + * @return SURFACE + */ + @Override + public Material.Type getMaterialType() { + return Material.Type.SURFACE; + } + } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RingHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/RingHandler.java index 890aaa039..51d43789e 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RingHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RingHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; @@ -24,214 +24,214 @@ import org.xml.sax.SAXException; * A SAX handler for centering rings, tube couplers, and bulkheads. */ class RingHandler extends PositionDependentHandler { - - /** - * The OpenRocket Ring. - */ - private final CenteringRing ring = new CenteringRing(); - - /** - * The parent component. - */ - private final RocketComponent parent; - - /** - * The parsed Rocksim UsageCode. - */ - private int usageCode = 0; - - /** - * Constructor. - * - * @param theParent the parent component - * @param warnings the warning set - * @throws IllegalArgumentException thrown if c is null - */ - public RingHandler(OpenRocketDocument document, RocketComponent theParent, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (theParent == null) { - throw new IllegalArgumentException("The parent of a ring may not be null."); - } - parent = theParent; - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.OD.equals(element)) { - ring.setOuterRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - } - if (RocksimCommonConstants.ID.equals(element)) { - ring.setInnerRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); - } - if (RocksimCommonConstants.LEN.equals(element)) { - ring.setLength(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - if (RocksimCommonConstants.USAGE_CODE.equals(element)) { - usageCode = Integer.parseInt(content); - } - } catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - /** - * Get the ring component this handler is working upon. - * - * @return a component - */ - @Override - public CenteringRing getComponent() { - return ring; - } - - /** - * This method adds the CenteringRing as a child of the parent rocket component. - * - * @param warnings the warning set - */ - public void asCenteringRing(WarningSet warnings) { - - if (isCompatible(parent, CenteringRing.class, warnings)) { - parent.addChild(ring); - } - } - - /** - * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's Bulkhead. - *

- * Side Effect Warning: This method adds the resulting Bulkhead as a child of the parent rocket component! - * - * @param warnings the warning set - */ - public void asBulkhead(WarningSet warnings) { - - Bulkhead result = new Bulkhead(); - - copyValues(result); - - if (isCompatible(parent, Bulkhead.class, warnings)) { - parent.addChild(result); - } - } - - /** - * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's TubeCoupler. - *

- * Side Effect Warning: This method adds the resulting TubeCoupler as a child of the parent rocket component! - * - * @param warnings the warning set - */ - public void asTubeCoupler(WarningSet warnings) { - - TubeCoupler result = new TubeCoupler(); - - copyValues(result); - - if (isCompatible(parent, TubeCoupler.class, warnings)) { - parent.addChild(result); - } - } - - /** - * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's Engine Block. - *

- * Side Effect Warning: This method adds the resulting EngineBlock as a child of the parent rocket component! - * - * @param warnings the warning set - */ - public void asEngineBlock(WarningSet warnings) { - - EngineBlock result = new EngineBlock(); - - copyValues(result); - - if (isCompatible(parent, EngineBlock.class, warnings)) { - parent.addChild(result); - } - } - - /** - * Copy values from the base ring to the specific component. - * - * @param result the target to which ring values will be copied - */ - private void copyValues(RingComponent result) { - result.setOuterRadius(ring.getOuterRadius()); - result.setInnerRadius(ring.getInnerRadius()); - result.setLength(ring.getLength()); - result.setName(ring.getName()); - setOverride(result, ring.isOverrideSubcomponentsEnabled(), ring.getOverrideMass(), ring.getOverrideCGX()); - result.setRelativePosition(ring.getRelativePosition()); - result.setPositionValue(ring.getPositionValue()); - result.setMaterial(ring.getMaterial()); - result.setThickness(result.getThickness()); - } - - /** - * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not - * public in all components. - * - * @param position the OpenRocket position - */ - @Override - public void setRelativePosition(RocketComponent.Position position) { - ring.setRelativePosition(position); - } - - @Override - public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { - super.endHandler(element, attributes, content, warnings); - - // The XML element in Rocksim design file is used for many types of components, unfortunately. - // Additional subelements are used to indicate the type of the rocket component. When parsing using SAX - // this poses a problem because we can't "look ahead" to see what type is being represented at the start - // of parsing - something that would be nice to do so that we can instantiate the correct OR component - // at the start, then just call setters for the appropriate data. - - // To overcome that, a CenteringRing is instantiated at the start of parsing, it's mutators are called, - // and then at the end (this method) converts the CenteringRing to a more appropriate type. CenteringRing - // is generic enough to support the representation of all similar types without loss of data. - - //UsageCode - // 0 == Centering Ring - // 1 == Bulkhead - // 2 == Engine Block - // 3 == Sleeve - // 4 == Tube Coupler - - if (usageCode == 1) { - //Bulkhead - asBulkhead(warnings); - } else if (usageCode == 2) { - asEngineBlock(warnings); - } else if (usageCode == 4) { - //TubeCoupler - asTubeCoupler(warnings); - } else { - //Default - asCenteringRing(warnings); - } - } - - /** - * Get the required type of material for this component. - * - * @return BULK - */ - @Override - public Material.Type getMaterialType() { - return Material.Type.BULK; - } + + /** + * The OpenRocket Ring. + */ + private final CenteringRing ring = new CenteringRing(); + + /** + * The parent component. + */ + private final RocketComponent parent; + + /** + * The parsed Rocksim UsageCode. + */ + private int usageCode = 0; + + /** + * Constructor. + * + * @param theParent the parent component + * @param warnings the warning set + * @throws IllegalArgumentException thrown if c is null + */ + public RingHandler(DocumentLoadingContext context, RocketComponent theParent, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (theParent == null) { + throw new IllegalArgumentException("The parent of a ring may not be null."); + } + parent = theParent; + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.OD.equals(element)) { + ring.setOuterRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + } + if (RocksimCommonConstants.ID.equals(element)) { + ring.setInnerRadius(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS); + } + if (RocksimCommonConstants.LEN.equals(element)) { + ring.setLength(Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + if (RocksimCommonConstants.USAGE_CODE.equals(element)) { + usageCode = Integer.parseInt(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + /** + * Get the ring component this handler is working upon. + * + * @return a component + */ + @Override + public CenteringRing getComponent() { + return ring; + } + + /** + * This method adds the CenteringRing as a child of the parent rocket component. + * + * @param warnings the warning set + */ + public void asCenteringRing(WarningSet warnings) { + + if (isCompatible(parent, CenteringRing.class, warnings)) { + parent.addChild(ring); + } + } + + /** + * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's Bulkhead. + *

+ * Side Effect Warning: This method adds the resulting Bulkhead as a child of the parent rocket component! + * + * @param warnings the warning set + */ + public void asBulkhead(WarningSet warnings) { + + Bulkhead result = new Bulkhead(); + + copyValues(result); + + if (isCompatible(parent, Bulkhead.class, warnings)) { + parent.addChild(result); + } + } + + /** + * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's TubeCoupler. + *

+ * Side Effect Warning: This method adds the resulting TubeCoupler as a child of the parent rocket component! + * + * @param warnings the warning set + */ + public void asTubeCoupler(WarningSet warnings) { + + TubeCoupler result = new TubeCoupler(); + + copyValues(result); + + if (isCompatible(parent, TubeCoupler.class, warnings)) { + parent.addChild(result); + } + } + + /** + * Convert the parsed Rocksim data values in this object to an instance of OpenRocket's Engine Block. + *

+ * Side Effect Warning: This method adds the resulting EngineBlock as a child of the parent rocket component! + * + * @param warnings the warning set + */ + public void asEngineBlock(WarningSet warnings) { + + EngineBlock result = new EngineBlock(); + + copyValues(result); + + if (isCompatible(parent, EngineBlock.class, warnings)) { + parent.addChild(result); + } + } + + /** + * Copy values from the base ring to the specific component. + * + * @param result the target to which ring values will be copied + */ + private void copyValues(RingComponent result) { + result.setOuterRadius(ring.getOuterRadius()); + result.setInnerRadius(ring.getInnerRadius()); + result.setLength(ring.getLength()); + result.setName(ring.getName()); + setOverride(result, ring.isOverrideSubcomponentsEnabled(), ring.getOverrideMass(), ring.getOverrideCGX()); + result.setRelativePosition(ring.getRelativePosition()); + result.setPositionValue(ring.getPositionValue()); + result.setMaterial(ring.getMaterial()); + result.setThickness(result.getThickness()); + } + + /** + * Set the relative position onto the component. This cannot be done directly because setRelativePosition is not + * public in all components. + * + * @param position the OpenRocket position + */ + @Override + public void setRelativePosition(RocketComponent.Position position) { + ring.setRelativePosition(position); + } + + @Override + public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { + super.endHandler(element, attributes, content, warnings); + + // The XML element in Rocksim design file is used for many types of components, unfortunately. + // Additional subelements are used to indicate the type of the rocket component. When parsing using SAX + // this poses a problem because we can't "look ahead" to see what type is being represented at the start + // of parsing - something that would be nice to do so that we can instantiate the correct OR component + // at the start, then just call setters for the appropriate data. + + // To overcome that, a CenteringRing is instantiated at the start of parsing, it's mutators are called, + // and then at the end (this method) converts the CenteringRing to a more appropriate type. CenteringRing + // is generic enough to support the representation of all similar types without loss of data. + + //UsageCode + // 0 == Centering Ring + // 1 == Bulkhead + // 2 == Engine Block + // 3 == Sleeve + // 4 == Tube Coupler + + if (usageCode == 1) { + //Bulkhead + asBulkhead(warnings); + } else if (usageCode == 2) { + asEngineBlock(warnings); + } else if (usageCode == 4) { + //TubeCoupler + asTubeCoupler(warnings); + } else { + //Default + asCenteringRing(warnings); + } + } + + /** + * Get the required type of material for this component. + * + * @return BULK + */ + @Override + public Material.Type getMaterialType() { + return Material.Type.BULK; + } } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RockSimAppearanceBuilder.java b/core/src/net/sf/openrocket/file/rocksim/importt/RockSimAppearanceBuilder.java index 44724a845..9940207f0 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RockSimAppearanceBuilder.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RockSimAppearanceBuilder.java @@ -7,7 +7,8 @@ import java.net.MalformedURLException; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.appearance.AppearanceBuilder; import net.sf.openrocket.appearance.Decal.EdgeMode; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.document.Attachment; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.util.Color; @@ -16,10 +17,10 @@ public class RockSimAppearanceBuilder extends AppearanceBuilder { boolean preventSeam = false; boolean repeat = false; - private final OpenRocketDocument document; + private final DocumentLoadingContext context; - public RockSimAppearanceBuilder(OpenRocketDocument document) { - this.document = document; + public RockSimAppearanceBuilder(DocumentLoadingContext context) { + this.context = context; } public void processElement(String element, String content, WarningSet warnings) { @@ -68,7 +69,8 @@ public class RockSimAppearanceBuilder extends AppearanceBuilder { //Find out how to get path of current rocksim file //so I can look in it's directory } - setImage(document.getDecalRegistry().getAttachment(value)); + Attachment a = context.getAttachmentFactory().getAttachment(name); + setImage(context.getOpenRocketDocument().getDecalImage(a)); } } else if ("repeat".equals(name)) { repeat = "1".equals(value); diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java index cd5229453..0178df8dc 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimHandler.java @@ -9,6 +9,7 @@ import java.util.HashMap; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.simplesax.AbstractElementHandler; import net.sf.openrocket.file.simplesax.ElementHandler; @@ -33,11 +34,11 @@ public class RocksimHandler extends AbstractElementHandler { */ private RocksimContentHandler handler = null; - private final OpenRocketDocument document; + private final DocumentLoadingContext context; - public RocksimHandler(OpenRocketDocument document) { + public RocksimHandler(DocumentLoadingContext context) { super(); - this.document = document; + this.context = context; } /** @@ -47,7 +48,7 @@ public class RocksimHandler extends AbstractElementHandler { * @return the document read, or null. */ public OpenRocketDocument getDocument() { - return document; + return context.getOpenRocketDocument(); } @Override @@ -67,7 +68,7 @@ public class RocksimHandler extends AbstractElementHandler { return null; } - handler = new RocksimContentHandler(document); + handler = new RocksimContentHandler(context); return handler; } @@ -78,9 +79,9 @@ public class RocksimHandler extends AbstractElementHandler { */ class RocksimContentHandler extends AbstractElementHandler { /** - * The OpenRocketDocument that is the container for the rocket. + * The DocumentLoadingContext */ - private final OpenRocketDocument doc; + private final DocumentLoadingContext context; /** * The top-level component, from which all child components are added. @@ -92,10 +93,10 @@ class RocksimContentHandler extends AbstractElementHandler { */ private String version; - public RocksimContentHandler(OpenRocketDocument doc) { + public RocksimContentHandler(DocumentLoadingContext context) { super(); - this.doc = doc; - this.rocket = doc.getRocket(); + this.context = context; + this.rocket = context.getOpenRocketDocument().getRocket(); } /** @@ -104,7 +105,7 @@ class RocksimContentHandler extends AbstractElementHandler { * @return the instantiated OpenRocketDocument */ public OpenRocketDocument getDocument() { - return doc; + return context.getOpenRocketDocument(); } @Override @@ -119,7 +120,7 @@ class RocksimContentHandler extends AbstractElementHandler { return PlainTextHandler.INSTANCE; } if (RocksimCommonConstants.ROCKET_DESIGN.equals(element)) { - return new RocketDesignHandler(doc, rocket); + return new RocketDesignHandler(context, rocket); } return null; } @@ -153,7 +154,7 @@ class RocksimContentHandler extends AbstractElementHandler { * structures. If that invariant is not true, then behavior will be unpredictable. */ class RocketDesignHandler extends AbstractElementHandler { - private final OpenRocketDocument document; + private final DocumentLoadingContext context; /** * The parent component. */ @@ -192,8 +193,8 @@ class RocketDesignHandler extends AbstractElementHandler { * * @param c the parent component */ - public RocketDesignHandler(OpenRocketDocument document, RocketComponent c) { - this.document = document; + public RocketDesignHandler(DocumentLoadingContext context, RocketComponent c) { + this.context = context; component = c; } @@ -216,7 +217,7 @@ class RocketDesignHandler extends AbstractElementHandler { stage.setOverrideCGX(stage3CG); } component.addChild(stage); - return new StageHandler(document, stage); + return new StageHandler(context, stage); } if ("Stage2Parts".equals(element)) { if (stageCount >= 2) { @@ -232,7 +233,7 @@ class RocketDesignHandler extends AbstractElementHandler { stage.setOverrideCGX(stage2CG); } component.addChild(stage); - return new StageHandler(document, stage); + return new StageHandler(context, stage); } } if ("Stage1Parts".equals(element)) { @@ -249,7 +250,7 @@ class RocketDesignHandler extends AbstractElementHandler { stage.setOverrideCGX(stage1CG); } component.addChild(stage); - return new StageHandler(document, stage); + return new StageHandler(context, stage); } } if (RocksimCommonConstants.NAME.equals(element)) { @@ -318,7 +319,7 @@ class RocketDesignHandler extends AbstractElementHandler { * A SAX handler for a Rocksim stage. */ class StageHandler extends AbstractElementHandler { - private final OpenRocketDocument document; + private final DocumentLoadingContext context; /** * The parent OpenRocket component. */ @@ -330,24 +331,24 @@ class StageHandler extends AbstractElementHandler { * @param c the parent component * @throws IllegalArgumentException thrown if c is null */ - public StageHandler(OpenRocketDocument document, RocketComponent c) throws IllegalArgumentException { + public StageHandler(DocumentLoadingContext context, RocketComponent c) throws IllegalArgumentException { if (c == null) { throw new IllegalArgumentException("The stage component may not be null."); } - this.document = document; + this.context = context; component = c; } @Override public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { if (RocksimCommonConstants.NOSE_CONE.equals(element)) { - return new NoseConeHandler(document, component, warnings); + return new NoseConeHandler(context, component, warnings); } if (RocksimCommonConstants.BODY_TUBE.equals(element)) { - return new BodyTubeHandler(document, component, warnings); + return new BodyTubeHandler(context, component, warnings); } if (RocksimCommonConstants.TRANSITION.equals(element)) { - return new TransitionHandler(document, component, warnings); + return new TransitionHandler(context, component, warnings); } return null; } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimLoader.java b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimLoader.java index 46f4cbee4..60bea006a 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/RocksimLoader.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/RocksimLoader.java @@ -6,9 +6,8 @@ package net.sf.openrocket.file.rocksim.importt; import java.io.IOException; import java.io.InputStream; -import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.file.AbstractRocketLoader; -import net.sf.openrocket.file.MotorFinder; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.file.simplesax.SimpleSAX; @@ -39,11 +38,11 @@ public class RocksimLoader extends AbstractRocketLoader { * if an error occurs during loading. */ @Override - protected void loadFromStream(OpenRocketDocument doc, InputStream source, MotorFinder motorFinder) throws IOException, RocketLoadException { + protected void loadFromStream(DocumentLoadingContext context, InputStream source) throws IOException, RocketLoadException { InputSource xmlSource = new InputSource(source); - RocksimHandler handler = new RocksimHandler(doc); + RocksimHandler handler = new RocksimHandler(context); try { SimpleSAX.readXML(xmlSource, handler, warnings); @@ -51,7 +50,7 @@ public class RocksimLoader extends AbstractRocketLoader { throw new RocketLoadException("Malformed XML in input.", e); } - doc.setFile(null); - doc.clearUndo(); + context.getOpenRocketDocument().setFile(null); + context.getOpenRocketDocument().clearUndo(); } } diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/StreamerHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/StreamerHandler.java index 3a7a4b79b..4cf787d58 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/StreamerHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/StreamerHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; @@ -19,72 +19,71 @@ import org.xml.sax.SAXException; * A SAX handler for Streamer components. */ class StreamerHandler extends RecoveryDeviceHandler { - - /** - * The OpenRocket Streamer. - */ - private final Streamer streamer; - - /** - * Constructor. - * - * @param c the parent component - * @param warnings the warning set - * - * @throws IllegalArgumentException thrown if c is null - */ - public StreamerHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent of a streamer may not be null."); - } - streamer = new Streamer(); - if (isCompatible(c, Streamer.class, warnings)) { - c.addChild(streamer); - } - } - - /** - * {@inheritDoc} - */ - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - return PlainTextHandler.INSTANCE; - } - - /** - * {@inheritDoc} - */ - @Override - public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if (RocksimCommonConstants.WIDTH.equals(element)) { - streamer.setStripWidth(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.LEN.equals(element)) { - streamer.setStripLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if (RocksimCommonConstants.DRAG_COEFFICIENT.equals(element)) { - streamer.setCD(Double.parseDouble(content)); - } - if (RocksimCommonConstants.MATERIAL.equals(element)) { - setMaterialName(content); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - /** - * {@inheritDoc} - */ - @Override - public Streamer getComponent() { - return streamer; - } - + + /** + * The OpenRocket Streamer. + */ + private final Streamer streamer; + + /** + * Constructor. + * + * @param c the parent component + * @param warnings the warning set + * + * @throws IllegalArgumentException thrown if c is null + */ + public StreamerHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent of a streamer may not be null."); + } + streamer = new Streamer(); + if (isCompatible(c, Streamer.class, warnings)) { + c.addChild(streamer); + } + } + + /** + * {@inheritDoc} + */ + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + return PlainTextHandler.INSTANCE; + } + + /** + * {@inheritDoc} + */ + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if (RocksimCommonConstants.WIDTH.equals(element)) { + streamer.setStripWidth(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.LEN.equals(element)) { + streamer.setStripLength(Math.max(0, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if (RocksimCommonConstants.DRAG_COEFFICIENT.equals(element)) { + streamer.setCD(Double.parseDouble(content)); + } + if (RocksimCommonConstants.MATERIAL.equals(element)) { + setMaterialName(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + /** + * {@inheritDoc} + */ + @Override + public Streamer getComponent() { + return streamer; + } + } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/TransitionHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/TransitionHandler.java index 0d1c5ed85..e02353e7f 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/TransitionHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/TransitionHandler.java @@ -6,7 +6,7 @@ package net.sf.openrocket.file.rocksim.importt; import java.util.HashMap; import net.sf.openrocket.aerodynamics.WarningSet; -import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; import net.sf.openrocket.file.rocksim.RocksimFinishCode; import net.sf.openrocket.file.rocksim.RocksimNoseConeCode; @@ -22,142 +22,140 @@ import org.xml.sax.SAXException; * The SAX handler for Transition components. */ class TransitionHandler extends BaseHandler { - /** - * The OpenRocket Transition. - */ - private final Transition transition = new Transition(); - - /** - * The wall thickness. Used for hollow nose cones. - */ - private double thickness = 0d; - - /** - * Constructor. - * - * @param c the parent component - * @param warnings the warning set - * @throws IllegalArgumentException thrown if c is null - */ - public TransitionHandler(OpenRocketDocument document, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { - super(document); - if (c == null) { - throw new IllegalArgumentException("The parent of a transition may not be null."); - } - if (isCompatible(c, Transition.class, warnings)) { - c.addChild(transition); - } - } - - @Override - public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { - if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { - return new AttachedPartsHandler(document, transition); - } - return PlainTextHandler.INSTANCE; - } - - @Override - public void closeElement(String element, HashMap attributes, - String content, WarningSet warnings) throws SAXException { - super.closeElement(element, attributes, content, warnings); - - try { - if ("ShapeCode".equals(element)) { - transition.setType(RocksimNoseConeCode.fromCode(Integer.parseInt(content)).asOpenRocket()); - } - if ("Len".equals(element)) { - transition.setLength(Math.max(0, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if ("FrontDia".equals(element)) { - transition.setForeRadius(Math.max(0, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if ("RearDia".equals(element)) { - transition.setAftRadius(Math.max(0, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if ("WallThickness".equals(element)) { - thickness = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); - } - if ("FrontShoulderDia".equals(element)) { - transition.setForeShoulderRadius(Math.max(0d, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if ("RearShoulderDia".equals(element)) { - transition.setAftShoulderRadius(Math.max(0d, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); - } - if ("FrontShoulderLen".equals(element)) { - transition.setForeShoulderLength(Math.max(0d, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if ("RearShoulderLen".equals(element)) { - transition.setAftShoulderLength(Math.max(0d, Double.parseDouble( - content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); - } - if ("ShapeParameter".equals(element)) { - if (Transition.Shape.POWER.equals(transition.getType()) || - Transition.Shape.HAACK.equals(transition.getType()) || - Transition.Shape.PARABOLIC.equals(transition.getType())) { - transition.setShapeParameter(Double.parseDouble(content)); - } - } - if ("ConstructionType".equals(element)) { - int typeCode = Integer.parseInt(content); - if (typeCode == 0) { - //SOLID - transition.setFilled(true); - } - else if (typeCode == 1) { - //HOLLOW - transition.setFilled(false); - } - } - if ("FinishCode".equals(element)) { - transition.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); - } - if ("Material".equals(element)) { - setMaterialName(content); - } - } - catch (NumberFormatException nfe) { - warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); - } - } - - @Override - public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) - throws SAXException { - super.endHandler(element, attributes, content, warnings); - - if (transition.isFilled()) { - transition.setAftShoulderThickness(transition.getAftShoulderRadius()); - transition.setForeShoulderThickness(transition.getForeShoulderRadius()); - } - else { - transition.setThickness(thickness); - transition.setAftShoulderThickness(thickness); - transition.setForeShoulderThickness(thickness); - } - } - - - @Override - public Transition getComponent() { - return transition; - } - - /** - * Get the required type of material for this component. - * - * @return BULK - */ - public Material.Type getMaterialType() { - return Material.Type.BULK; - } - - + /** + * The OpenRocket Transition. + */ + private final Transition transition = new Transition(); + + /** + * The wall thickness. Used for hollow nose cones. + */ + private double thickness = 0d; + + /** + * Constructor. + * + * @param c the parent component + * @param warnings the warning set + * @throws IllegalArgumentException thrown if c is null + */ + public TransitionHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) throws IllegalArgumentException { + super(context); + if (c == null) { + throw new IllegalArgumentException("The parent of a transition may not be null."); + } + if (isCompatible(c, Transition.class, warnings)) { + c.addChild(transition); + } + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) { + if (RocksimCommonConstants.ATTACHED_PARTS.equals(element)) { + return new AttachedPartsHandler(context, transition); + } + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, + String content, WarningSet warnings) throws SAXException { + super.closeElement(element, attributes, content, warnings); + + try { + if ("ShapeCode".equals(element)) { + transition.setType(RocksimNoseConeCode.fromCode(Integer.parseInt(content)).asOpenRocket()); + } + if ("Len".equals(element)) { + transition.setLength(Math.max(0, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if ("FrontDia".equals(element)) { + transition.setForeRadius(Math.max(0, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if ("RearDia".equals(element)) { + transition.setAftRadius(Math.max(0, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if ("WallThickness".equals(element)) { + thickness = Math.max(0d, Double.parseDouble(content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH); + } + if ("FrontShoulderDia".equals(element)) { + transition.setForeShoulderRadius(Math.max(0d, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if ("RearShoulderDia".equals(element)) { + transition.setAftShoulderRadius(Math.max(0d, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS)); + } + if ("FrontShoulderLen".equals(element)) { + transition.setForeShoulderLength(Math.max(0d, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if ("RearShoulderLen".equals(element)) { + transition.setAftShoulderLength(Math.max(0d, Double.parseDouble( + content) / RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH)); + } + if ("ShapeParameter".equals(element)) { + if (Transition.Shape.POWER.equals(transition.getType()) || + Transition.Shape.HAACK.equals(transition.getType()) || + Transition.Shape.PARABOLIC.equals(transition.getType())) { + transition.setShapeParameter(Double.parseDouble(content)); + } + } + if ("ConstructionType".equals(element)) { + int typeCode = Integer.parseInt(content); + if (typeCode == 0) { + //SOLID + transition.setFilled(true); + } + else if (typeCode == 1) { + //HOLLOW + transition.setFilled(false); + } + } + if ("FinishCode".equals(element)) { + transition.setFinish(RocksimFinishCode.fromCode(Integer.parseInt(content)).asOpenRocket()); + } + if ("Material".equals(element)) { + setMaterialName(content); + } + } catch (NumberFormatException nfe) { + warnings.add("Could not convert " + element + " value of " + content + ". It is expected to be a number."); + } + } + + @Override + public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) + throws SAXException { + super.endHandler(element, attributes, content, warnings); + + if (transition.isFilled()) { + transition.setAftShoulderThickness(transition.getAftShoulderRadius()); + transition.setForeShoulderThickness(transition.getForeShoulderRadius()); + } + else { + transition.setThickness(thickness); + transition.setAftShoulderThickness(thickness); + transition.setForeShoulderThickness(thickness); + } + } + + + @Override + public Transition getComponent() { + return transition; + } + + /** + * Get the required type of material for this component. + * + * @return BULK + */ + public Material.Type getMaterialType() { + return Material.Type.BULK; + } + + } - diff --git a/core/src/net/sf/openrocket/gui/ExportDecalDialog.java b/core/src/net/sf/openrocket/gui/ExportDecalDialog.java index 638e6a466..3357c2af7 100644 --- a/core/src/net/sf/openrocket/gui/ExportDecalDialog.java +++ b/core/src/net/sf/openrocket/gui/ExportDecalDialog.java @@ -40,7 +40,7 @@ public class ExportDecalDialog extends JDialog { JLabel label = new JLabel(trans.get("ExportDecalDialog.decalList.lbl")); panel.add(label); - Collection exportableDecals = document.getDecalRegistry().getDecalList(); + Collection exportableDecals = document.getDecalList(); decalComboBox = new JComboBox(exportableDecals.toArray(new DecalImage[0])); decalComboBox.setEditable(false); diff --git a/core/src/net/sf/openrocket/gui/adaptors/DecalModel.java b/core/src/net/sf/openrocket/gui/adaptors/DecalModel.java index e1730f001..9fd3dab7f 100644 --- a/core/src/net/sf/openrocket/gui/adaptors/DecalModel.java +++ b/core/src/net/sf/openrocket/gui/adaptors/DecalModel.java @@ -10,7 +10,9 @@ import javax.swing.SwingUtilities; import net.sf.openrocket.appearance.AppearanceBuilder; import net.sf.openrocket.appearance.DecalImage; +import net.sf.openrocket.document.Attachment; import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.file.FileSystemAttachmentFactory; import net.sf.openrocket.gui.util.SwingPreferences; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.startup.Application; @@ -34,7 +36,7 @@ public class DecalModel extends AbstractListModel implements ComboBoxModel { this.document = document; this.parent = parent; this.ab = ab; - decals = document.getDecalRegistry().getDecalList().toArray(new DecalImage[0]); + decals = document.getDecalList().toArray(new DecalImage[0]); } @Override @@ -71,7 +73,8 @@ public class DecalModel extends AbstractListModel implements ComboBoxModel { if (action == JFileChooser.APPROVE_OPTION) { ((SwingPreferences) Application.getPreferences()).setDefaultDirectory(fc.getCurrentDirectory()); File file = fc.getSelectedFile(); - setSelectedItem(document.getDecalRegistry().getAttachment(file)); + Attachment a = (new FileSystemAttachmentFactory().getAttachment(file)); + setSelectedItem(document.getDecalImage(a)); } } }); diff --git a/core/test/net/sf/openrocket/file/rocksim/importt/RocksimLoaderTest.java b/core/test/net/sf/openrocket/file/rocksim/importt/RocksimLoaderTest.java index eb123c0b5..64c358cca 100644 --- a/core/test/net/sf/openrocket/file/rocksim/importt/RocksimLoaderTest.java +++ b/core/test/net/sf/openrocket/file/rocksim/importt/RocksimLoaderTest.java @@ -11,6 +11,7 @@ import java.io.InputStream; import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocumentFactory; import net.sf.openrocket.file.DatabaseMotorFinder; +import net.sf.openrocket.file.DocumentLoadingContext; import net.sf.openrocket.file.RocketLoadException; import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.LaunchLug; @@ -35,9 +36,11 @@ public class RocksimLoaderTest { InputStream stream = this.getClass().getResourceAsStream("PodFins.rkt"); Assert.assertNotNull("Could not open PodFins.rkt", stream); try { - OpenRocketDocument doc = OpenRocketDocumentFactory.createDocumentForFile(null, false); - loader.loadFromStream(doc, new BufferedInputStream(stream), new DatabaseMotorFinder()); - Assert.assertNotNull(doc); + OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); + DocumentLoadingContext context = new DocumentLoadingContext(); + context.setOpenRocketDocument(doc); + context.setMotorFinder(new DatabaseMotorFinder()); + loader.loadFromStream(context, new BufferedInputStream(stream)); Rocket rocket = doc.getRocket(); Assert.assertNotNull(rocket); } catch (IllegalStateException ise) { @@ -67,8 +70,11 @@ public class RocksimLoaderTest { stream = this.getClass().getResourceAsStream("rocksimTestRocket2.rkt"); Assert.assertNotNull("Could not open rocksimTestRocket2.rkt", stream); - doc = OpenRocketDocumentFactory.createDocumentForFile(null, false); - loader.loadFromStream(doc, new BufferedInputStream(stream), new DatabaseMotorFinder()); + doc = OpenRocketDocumentFactory.createEmptyRocket(); + DocumentLoadingContext context = new DocumentLoadingContext(); + context.setOpenRocketDocument(doc); + context.setMotorFinder(new DatabaseMotorFinder()); + loader.loadFromStream(context, new BufferedInputStream(stream)); Assert.assertNotNull(doc); rocket = doc.getRocket(); @@ -92,8 +98,11 @@ public class RocksimLoaderTest { stream = this.getClass().getResourceAsStream("rocksimTestRocket3.rkt"); Assert.assertNotNull("Could not open rocksimTestRocket3.rkt", stream); - doc = OpenRocketDocumentFactory.createDocumentForFile(null, false); - loader.loadFromStream(doc, new BufferedInputStream(stream), new DatabaseMotorFinder()); + doc = OpenRocketDocumentFactory.createEmptyRocket(); + context = new DocumentLoadingContext(); + context.setOpenRocketDocument(doc); + context.setMotorFinder(new DatabaseMotorFinder()); + loader.loadFromStream(context, new BufferedInputStream(stream)); Assert.assertNotNull(doc); rocket = doc.getRocket(); @@ -139,8 +148,11 @@ public class RocksimLoaderTest { InputStream stream = RocksimLoaderTest.class.getResourceAsStream("rocksimTestRocket1.rkt"); try { Assert.assertNotNull("Could not open rocksimTestRocket1.rkt", stream); - OpenRocketDocument doc = OpenRocketDocumentFactory.createDocumentForFile(null, false); - theLoader.loadFromStream(doc, new BufferedInputStream(stream), new DatabaseMotorFinder()); + OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); + DocumentLoadingContext context = new DocumentLoadingContext(); + context.setOpenRocketDocument(doc); + context.setMotorFinder(new DatabaseMotorFinder()); + theLoader.loadFromStream(context, new BufferedInputStream(stream)); return doc; } finally { stream.close(); @@ -151,8 +163,11 @@ public class RocksimLoaderTest { InputStream stream = RocksimLoaderTest.class.getResourceAsStream("rocksimTestRocket3.rkt"); try { Assert.assertNotNull("Could not open rocksimTestRocket3.rkt", stream); - OpenRocketDocument doc = OpenRocketDocumentFactory.createDocumentForFile(null, false); - theLoader.loadFromStream(doc, new BufferedInputStream(stream), new DatabaseMotorFinder()); + OpenRocketDocument doc = OpenRocketDocumentFactory.createEmptyRocket(); + DocumentLoadingContext context = new DocumentLoadingContext(); + context.setOpenRocketDocument(doc); + context.setMotorFinder(new DatabaseMotorFinder()); + theLoader.loadFromStream(context, new BufferedInputStream(stream)); return doc; } finally { stream.close();