create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / file / rocksim / export / RocksimSaver.java
1 package net.sf.openrocket.file.rocksim.export;
2
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;
14
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;
22
23 /**
24  * This class is responsible for converting an OpenRocket design to a Rocksim design.
25  */
26 public class RocksimSaver extends RocketSaver {
27
28     /**
29      * The logger.
30      */
31     private static final LogHelper log = Application.getLogger();
32
33     /**
34      * This method marshals an OpenRocketDocument (OR design) to Rocksim-compliant XML.
35      *
36      * @param doc the OR design
37      * @return Rocksim-compliant XML
38      */
39     public String marshalToRocksim(OpenRocketDocument doc) {
40
41         try {
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();
47
48             marshaller.marshal(toRocksimDocumentDTO(doc), sw);
49             return sw.toString();
50         } catch (Exception e) {
51             log.error("Could not marshall a design to Rocksim format. " + e.getMessage());
52         }
53
54         return null;
55     }
56
57     @Override
58     public void save(OutputStream dest, OpenRocketDocument doc, StorageOptions options) throws IOException {
59         log.info("Saving .rkt file");
60
61         BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, "UTF-8"));
62         writer.write(marshalToRocksim(doc));
63         writer.flush();
64         writer.close();
65     }
66
67     @Override
68     public long estimateFileSize(OpenRocketDocument doc, StorageOptions options) {
69         return marshalToRocksim(doc).length();
70     }
71
72     /**
73      * Root conversion method.  It iterates over all subcomponents.
74      *
75      * @param doc the OR design
76      * @return a corresponding Rocksim representation
77      */
78     private RocksimDocumentDTO toRocksimDocumentDTO(OpenRocketDocument doc) {
79         RocksimDocumentDTO rsd = new RocksimDocumentDTO();
80
81         rsd.setDesign(toRocksimDesignDTO(doc.getRocket()));
82
83         return rsd;
84     }
85
86     private RocksimDesignDTO toRocksimDesignDTO(Rocket rocket) {
87         RocksimDesignDTO result = new RocksimDesignDTO();
88         result.setDesign(toRocketDesignDTO(rocket));
89         return result;
90     }
91
92     private RocketDesignDTO toRocketDesignDTO(Rocket rocket) {
93         RocketDesignDTO result = new RocketDesignDTO();
94
95         MassCalculator massCalc = new BasicMassCalculator();
96
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);
104         } else {
105             result.setStage3CG(cg);
106         }
107
108         result.setName(rocket.getName());
109         result.setStageCount(stageCount);
110         if (stageCount > 0) {
111             result.setStage3(toStageDTO(rocket.getChild(0).getStage(), result, 3));
112         }
113         if (stageCount > 1) {
114             result.setStage2(toStageDTO(rocket.getChild(1).getStage(), result, 2));
115         }
116         if (stageCount > 2) {
117             result.setStage1(toStageDTO(rocket.getChild(2).getStage(), result, 1));
118         }
119         //Set the last serial number element and reset it.
120         result.setLastSerialNumber(BasePartDTO.getCurrentSerialNumber());
121         BasePartDTO.resetCurrentSerialNumber();
122         return result;
123     }
124
125     private StageDTO toStageDTO(Stage stage, RocketDesignDTO designDTO, int stageNumber) {
126         return new StageDTO(stage, designDTO, stageNumber);
127     }
128
129 }