0173108556aae5be8fdebb74a19aa3c7a98d6e0c
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / modelica / Modelica.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2010 - DIGITEO - Clement DAVID <clement.david@scilab.org>
4  * Copyright (C) 2011-2011 - Scilab Enterprises - Clement DAVID
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 package org.scilab.modules.xcos.modelica;
15
16 import java.io.File;
17 import java.io.FileInputStream;
18 import java.io.FileNotFoundException;
19 import java.io.FileOutputStream;
20 import java.io.IOException;
21 import java.io.InputStreamReader;
22 import java.io.StringWriter;
23 import java.nio.charset.Charset;
24 import java.util.logging.Logger;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import javax.swing.SwingUtilities;
29 import javax.xml.XMLConstants;
30 import javax.xml.bind.JAXBContext;
31 import javax.xml.bind.JAXBElement;
32 import javax.xml.bind.JAXBException;
33 import javax.xml.bind.Marshaller;
34 import javax.xml.bind.Unmarshaller;
35 import javax.xml.stream.FactoryConfigurationError;
36 import javax.xml.validation.Schema;
37 import javax.xml.validation.SchemaFactory;
38
39 import org.scilab.modules.commons.ScilabConstants;
40 import org.scilab.modules.graph.utils.ScilabExported;
41 import org.scilab.modules.xcos.modelica.model.Model;
42 import org.scilab.modules.xcos.utils.XcosConstants;
43 import org.xml.sax.SAXException;
44
45 /**
46  * Main class for modelica manipulation.
47  */
48 public final class Modelica {
49     private static final String LATIN1_ENCODING = "ISO-8859-1";
50     private static final String MODEL_CLASS_PACKAGE = "org.scilab.modules.xcos.modelica.model";
51     private static final String SCHEMA_FILENAME = "/Modelica.xsd";
52
53     private static Modelica instance;
54
55     private Marshaller marshaller;
56     private Unmarshaller unmarshaller;
57
58     /**
59      * Default constructor.
60      */
61     private Modelica() {
62         final String schemaPath = ScilabConstants.SCI.getAbsolutePath() + XcosConstants.XCOS_ETC + SCHEMA_FILENAME;
63
64         JAXBContext jaxbContext;
65         try {
66             jaxbContext = JAXBContext.newInstance(MODEL_CLASS_PACKAGE);
67             marshaller = jaxbContext.createMarshaller();
68             unmarshaller = jaxbContext.createUnmarshaller();
69
70             Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(new File(schemaPath));
71
72             marshaller.setSchema(schema);
73             unmarshaller.setSchema(schema);
74
75             /*
76              * Customize the file to be handled by the xml2modelica and
77              * modelicat tool.
78              */
79             marshaller.setProperty(Marshaller.JAXB_ENCODING, LATIN1_ENCODING);
80
81             marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
82         } catch (JAXBException e) {
83             throw new RuntimeException(e);
84         } catch (SAXException e) {
85             Logger.getLogger(Modelica.class.getName()).severe(e.toString());
86         }
87     }
88
89     /**
90      * @return the instance
91      */
92     public static Modelica getInstance() {
93         if (instance == null) {
94             instance = new Modelica();
95         }
96         return instance;
97     }
98
99     /**
100      * Setup a new modelica settings UI
101      *
102      * @param init
103      *            the initialisation file.
104      * @param relation
105      *            the relation file
106      */
107     @ScilabExported(module = "xcos", filename = "Modelica.giws.xml")
108     public static void load(final String init, final String relation) {
109         SwingUtilities.invokeLater(new Runnable() {
110             @Override
111             public void run() {
112                 ModelicaController.showDialog(new File(init), new File(relation));
113             }
114         });
115     }
116
117     /**
118      * Load a file
119      *
120      * @param file
121      *            the file to load
122      * @return the model element
123      * @throws JAXBException
124      *             on error
125      */
126     @SuppressWarnings("unchecked")
127     public Model load(File file) throws JAXBException {
128         InputStreamReader reader;
129         try {
130             reader = new InputStreamReader(new FileInputStream(file), Charset.forName(LATIN1_ENCODING));
131         } catch (FileNotFoundException e) {
132             Logger.getLogger(Modelica.class.getName()).severe(e.toString());
133             return null;
134         }
135         return ((JAXBElement<Model>) unmarshaller.unmarshal(reader)).getValue();
136     }
137
138     /**
139      * Save the model into the file
140      *
141      * @param root
142      *            the root of the model to save
143      * @param file
144      *            the file to save
145      * @throws JAXBException
146      *             on error
147      */
148     public void save(Model root, File file) throws JAXBException {
149         try {
150             final StringWriter strw = new StringWriter();
151             marshaller.marshal(unmerge(root), strw);
152
153             /*
154              * Customize the file to be handled by the xml2modelica tool
155              */
156             final StringBuffer buffer = strw.getBuffer();
157             final String newline = System.getProperty("line.separator");
158
159             Pattern pat = Pattern.compile("(/\\w*>)(<[\\w/])");
160             Matcher m = pat.matcher(buffer);
161             while (m.find()) {
162                 final int index = m.end(1);
163                 buffer.insert(index, newline);
164                 m.reset();
165             }
166             buffer.append(newline);
167
168             new FileOutputStream(file).write(strw.toString().getBytes());
169         } catch (FactoryConfigurationError e) {
170             Logger.getLogger(Modelica.class.getName()).severe(e.toString());
171         } catch (IOException e) {
172             Logger.getLogger(Modelica.class.getName()).severe(e.toString());
173         }
174     }
175
176     /**
177      * Merge the models into a single shared model
178      *
179      * @param initModel
180      *            the initialization model
181      * @param relationModel
182      *            the relation model
183      * @return a new model
184      */
185     public Model merge(Model initModel, Model relationModel) {
186         // merge the relation model into the init model
187
188         initModel.setIdentifiers(relationModel.getIdentifiers());
189         initModel.setModelInfo(relationModel.getModelInfo());
190
191         initModel.setExplicitRelations(relationModel.getExplicitRelations());
192         initModel.setImplicitRelations(relationModel.getImplicitRelations());
193
194         initModel.setOutputs(relationModel.getOutputs());
195         return initModel;
196     }
197
198     /**
199      * Unmerge the model
200      *
201      * @param model
202      *            the model
203      * @return the unmerged model
204      */
205     public Model unmerge(Model initModel) {
206         final Model model = new Model();
207
208         /*
209          * From xMLTree.ml
210          */
211         model.setName(initModel.getName());
212
213         model.setElements(initModel.getElements());
214         model.setEquations(initModel.getEquations());
215         model.setWhenClauses(initModel.getWhenClauses());
216
217         return model;
218     }
219 }