1 package net.sf.openrocket.file.rocksim.export;
3 import net.sf.openrocket.document.OpenRocketDocument;
4 import net.sf.openrocket.document.StorageOptions;
5 import net.sf.openrocket.file.RocketSaver;
6 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
7 import net.sf.openrocket.logging.LogHelper;
8 import net.sf.openrocket.masscalc.BasicMassCalculator;
9 import net.sf.openrocket.masscalc.MassCalculator;
10 import net.sf.openrocket.rocketcomponent.Configuration;
11 import net.sf.openrocket.rocketcomponent.Rocket;
12 import net.sf.openrocket.rocketcomponent.Stage;
13 import net.sf.openrocket.startup.Application;
15 import javax.xml.bind.JAXBContext;
16 import javax.xml.bind.Marshaller;
17 import java.io.BufferedWriter;
18 import java.io.IOException;
19 import java.io.OutputStream;
20 import java.io.OutputStreamWriter;
21 import java.io.StringWriter;
24 * This class is responsible for converting an OpenRocket design to a Rocksim design.
26 public class RocksimSaver extends RocketSaver {
31 private static final LogHelper log = Application.getLogger();
34 * This method marshals an OpenRocketDocument (OR design) to Rocksim-compliant XML.
36 * @param doc the OR design
37 * @return Rocksim-compliant XML
39 public String marshalToRocksim(OpenRocketDocument doc) {
42 JAXBContext binder = JAXBContext.newInstance(RocksimDocumentDTO.class);
43 Marshaller marshaller = binder.createMarshaller();
44 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
45 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
46 StringWriter sw = new StringWriter();
48 marshaller.marshal(toRocksimDocumentDTO(doc), sw);
50 } catch (Exception e) {
51 log.error("Could not marshall a design to Rocksim format. " + e.getMessage());
58 public void save(OutputStream dest, OpenRocketDocument doc, StorageOptions options) throws IOException {
59 log.info("Saving .rkt file");
61 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, "UTF-8"));
62 writer.write(marshalToRocksim(doc));
68 public long estimateFileSize(OpenRocketDocument doc, StorageOptions options) {
69 return marshalToRocksim(doc).length();
73 * Root conversion method. It iterates over all subcomponents.
75 * @param doc the OR design
76 * @return a corresponding Rocksim representation
78 private RocksimDocumentDTO toRocksimDocumentDTO(OpenRocketDocument doc) {
79 RocksimDocumentDTO rsd = new RocksimDocumentDTO();
81 rsd.setDesign(toRocksimDesignDTO(doc.getRocket()));
86 private RocksimDesignDTO toRocksimDesignDTO(Rocket rocket) {
87 RocksimDesignDTO result = new RocksimDesignDTO();
88 result.setDesign(toRocketDesignDTO(rocket));
92 private RocketDesignDTO toRocketDesignDTO(Rocket rocket) {
93 RocketDesignDTO result = new RocketDesignDTO();
95 MassCalculator massCalc = new BasicMassCalculator();
97 final double cg = massCalc.getCG(new Configuration(rocket), MassCalculator.MassCalcType.NO_MOTORS).x *
98 RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH;
99 int stageCount = rocket.getStageCount();
100 if (stageCount == 3) {
101 result.setStage321CG(cg);
102 } else if (stageCount == 2) {
103 result.setStage32CG(cg);
105 result.setStage3CG(cg);
108 result.setName(rocket.getName());
109 result.setStageCount(stageCount);
110 if (stageCount > 0) {
111 result.setStage3(toStageDTO(rocket.getChild(0).getStage(), result, 3));
113 if (stageCount > 1) {
114 result.setStage2(toStageDTO(rocket.getChild(1).getStage(), result, 2));
116 if (stageCount > 2) {
117 result.setStage1(toStageDTO(rocket.getChild(2).getStage(), result, 1));
119 //Set the last serial number element and reset it.
120 result.setLastSerialNumber(BasePartDTO.getCurrentSerialNumber());
121 BasePartDTO.resetCurrentSerialNumber();
125 private StageDTO toStageDTO(Stage stage, RocketDesignDTO designDTO, int stageNumber) {
126 return new StageDTO(stage, designDTO, stageNumber);