]> gerrit.simantics Code Review - simantics/interop.git/blob - SchemaConverter.java
1b2b3722606832c8f55fc62cc7c082e97cc1eab6
[simantics/interop.git] / SchemaConverter.java
1 package org.simantics.xml.sax;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.util.ArrayList;
9 import java.util.Date;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.regex.Matcher;
14
15 import javax.xml.bind.JAXBContext;
16 import javax.xml.bind.JAXBElement;
17 import javax.xml.bind.JAXBException;
18 import javax.xml.bind.Unmarshaller;
19
20 import org.simantics.utils.datastructures.MapList;
21 import org.simantics.xml.sax.configuration.Configuration;
22 import org.w3._2001.xmlschema.Annotation;
23 import org.w3._2001.xmlschema.Import;
24 import org.w3._2001.xmlschema.Include;
25 import org.w3._2001.xmlschema.OpenAttrs;
26 import org.w3._2001.xmlschema.Schema;
27
28 /**
29  * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.
30  * 
31  * @author mlmarko
32  *
33  */
34 public class SchemaConverter {
35         
36         File outputPlugin;
37         File schemaFile;
38         File conversionFile;
39         File ontologyFile;
40         File parserDir;
41         Schema schema;
42         Configuration configuration;
43         
44         String pluginName;
45         
46         private String[] header;
47         
48         boolean createPGraph = true;
49         boolean createImporter = true;
50         boolean createExporter = true;
51         
52         private List<SchemaConverter> parent = new ArrayList<>();
53         private List<SchemaConverter> subConverters = new ArrayList<>();
54         private Map<String,SchemaConverter> fileMap;
55         private MapList<String,SchemaConverter> schemaNSMap;
56         private MapList<String,SchemaConverter> shortNameMap;
57         
58         String schemaNs;
59         String ontologyUri;
60         String className;
61         String name;
62         String shortName;
63         
64         SchemaConversionBase base;
65         
66         private ManualSchemaFileImport fileImport;
67         
68         public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {
69                 this(null,schemaFile,conversionFile,outputPlugin);
70         }
71         
72         public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {
73                 
74                 this.outputPlugin = outputPlugin;
75                 this.schemaFile = schemaFile;
76                 this.conversionFile = conversionFile;
77                 
78                 pluginName = outputPlugin.getName();
79                 String packageParts[] = pluginName.split("\\.");
80                 String outputLoc = outputPlugin.getAbsolutePath();
81                 outputLoc += "/src";
82                 for (String s : packageParts)
83                         outputLoc += "/"+s;
84                 String outputGraph = outputPlugin.getAbsolutePath();
85                 outputGraph += "/graph";
86                 outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";
87                 
88                 
89                 this.ontologyFile = new File(outputGraph);
90                 this.parserDir = new File(outputLoc);
91                 
92                 if (parent != null) {
93                         this.parent.add(parent);
94                         parent.subConverters.add(this);
95                 } else {
96                         fileMap = new HashMap<>();
97                         schemaNSMap = new MapList<>();
98                         shortNameMap = new MapList<>();
99                 }
100                 getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);
101         }
102         
103         public List<SchemaConverter> getConverter(String schemaNS) {
104                 return getRoot().schemaNSMap.getValues(schemaNS);
105         }
106         
107         public void setFileImport(ManualSchemaFileImport fileImport) {
108                 this.fileImport = fileImport;
109         }
110
111         
112         public void setCreateExporter(boolean createExporter) {
113                 this.createExporter = createExporter;
114         }
115         
116         public void setCreateImporter(boolean createImporter) {
117                 this.createImporter = createImporter;
118         }
119         
120         public void setCreatePGraph(boolean createPGraph) {
121                 this.createPGraph = createPGraph;
122         }
123         
124         protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {
125                 File directory = schemaFile.getParentFile();
126                 File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);
127                 if (!schemaFile.exists()) {
128                         if (getRoot().fileImport != null) {
129                                 schemaFile = getRoot().fileImport.getFileForLocation(location);
130                         }
131                         if (!schemaFile.exists())
132                                 throw new FileNotFoundException(schemaFile.getAbsolutePath());
133                 }
134                 SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));
135                 if (subConverter == null) {
136                         subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);
137                         subConverter.createPGraph = this.createPGraph;
138                         subConverter.createImporter = this.createImporter;
139                         subConverter.createExporter = this.createExporter;
140                 } else {
141                         subConverter.parent.add(this);
142                 }
143                 return subConverter;
144         }
145         
146         protected SchemaConverter getRoot() {
147                 SchemaConverter s = this;
148                 if (s.fileMap != null)
149                         return s;
150                 while (s.parent.size() > 0) {
151                         s = s.parent.get(0);
152                         if (s.fileMap != null)
153                                 return s;
154                 }
155                 return s;
156         }
157         
158         public void convert() throws JAXBException, IOException {
159                 
160                 init();
161                 doConvert();
162         }
163         
164         boolean init = false;
165         
166         protected void assignShortName() {
167                 shortName = name.substring(0, 3).toUpperCase();
168                 SchemaConverter root = getRoot();
169                 if (!root.shortNameMap.containsKey(shortName)) {
170                         root.shortNameMap.add(shortName, this);
171                         return;
172                 } else {
173                         SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);
174                         if (sc.schemaNs.equals(schemaNs)) {
175                                 root.shortNameMap.add(shortName, this);
176                                 return;
177                         }
178                 }
179                 int i = 1;
180                 while (true) {
181                         String n = shortName+i;
182                         if (!root.shortNameMap.containsKey(n)) {
183                                 shortName = n;
184                                 root.shortNameMap.add(shortName, this);
185                                 return;
186                         } else {
187                                 SchemaConverter sc = root.shortNameMap.getValues(n).get(0);
188                                 if (sc.schemaNs.equals(schemaNs)) {
189                                         shortName = n;
190                                         root.shortNameMap.add(shortName, this);
191                                         return;
192                                 }
193                         }
194                         i++;
195                 }
196         }
197         
198         protected void init() throws IOException, JAXBException {
199                 if (init)
200                         return;
201                 init = true;
202                 JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");
203                 Unmarshaller u = jc.createUnmarshaller();
204                 //u.setSchema(schema);
205         InputStream fileStream = new FileInputStream(schemaFile);
206                 schema = (Schema)u.unmarshal(fileStream);
207                 
208                 if (conversionFile != null) {
209                         jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
210                         u = jc.createUnmarshaller();
211                         fileStream = new FileInputStream(conversionFile);
212                         configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();
213                 } else {
214                         configuration = new Configuration();
215                 }
216                 
217                 header = new String[4];
218                 header[0] = "Generated with org.simantics.xml.sax XML schema converter";
219                 header[1] = "";
220                 header[2] = "File " + schemaFile.getAbsolutePath().replaceAll(Matcher.quoteReplacement("\\"), "/");
221                 header[3] = "Date " + new Date().toString();
222                 
223                 schemaNs = schema.getTargetNamespace();
224                 ontologyUri = schemaNs;
225                 if (ontologyUri == null) {
226                         ontologyUri = getSchemaFile().getName();
227                         
228                         int index = ontologyUri.lastIndexOf(".");
229                         if (index > 0)
230                                 ontologyUri = ontologyUri.substring(0, index);
231                 } 
232                 ontologyUri = ontologyUri.replaceAll(" ", "_");
233                 String parts[] = ontologyUri.split("/");
234                 for (int i = parts.length-1; i >= 0; i--) {
235                         name = parts[i];
236                         if (!Character.isDigit(name.charAt(0)))
237                                 break;
238                 }
239                 if (name == null) {
240                         throw new JAXBException("Could not resolve proper name for schema " + ontologyUri);
241                 }
242                 
243                 
244                 name = name.replaceAll("\\.", "_");
245                 if (!ontologyUri.startsWith("http://"))
246                         ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");
247                 else
248                         ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");
249                 
250                 String version = schema.getVersion();
251                 if (version == null)
252                         version = "1.0";
253                 ontologyUri +="-"+ version;
254
255                 
256                 className = getPluginName() + "." + name;
257                 assignShortName();
258                 if (schemaNs != null)
259                         getRoot().schemaNSMap.add(schemaNs, this);
260                 
261                 
262                 for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {
263                         if (attrs instanceof Import) {
264                                 Import imp = (Import)attrs;
265                                 String location = imp.getSchemaLocation();
266                                 SchemaConverter sc = createSubConverter(location);
267                                 sc.init();
268                         } else if (attrs instanceof Include) {
269                                 Include inc = (Include)attrs;
270                                 String location = inc.getSchemaLocation();
271                                 SchemaConverter sc = createSubConverter(location);
272                                 sc.init();
273                         } else if (attrs instanceof Annotation) {
274                                 
275                         } else {
276                                 throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");
277                         }
278                 }
279         }
280         
281         protected void doConvert() throws IOException, JAXBException {
282                 if (!ontologyFile.exists()) {
283                         ontologyFile.getParentFile().mkdirs();
284                         ontologyFile.createNewFile();
285                 }
286                 if (!parserDir.exists())
287                         parserDir.mkdirs();
288                 
289                 for (SchemaConverter sc : subConverters)
290                         sc.doConvert();
291                 
292                 base = new SchemaConversionBase(this,ontologyUri,className);
293                 base.init(schema);
294                 
295                 if (createPGraph) {
296                         OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);
297                         ontologyGenerator.createOntology();
298                 }
299                 if (createImporter) {
300                         ImporterGenerator importerGenerator = new ImporterGenerator(this,base);
301                         importerGenerator.createParser();
302                 }
303                 if (createExporter) {
304                         ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);
305                         exporterGenerator.createParser();
306                 }
307                 base.component = null;
308         }
309         
310         public File getOntologyFile() {
311                 return ontologyFile;
312         }
313         public File getParserDir() {
314                 return parserDir;
315         }
316         
317         public Schema getSchema() {
318                 return schema;
319         }
320         
321         public File getSchemaFile() {
322                 return schemaFile;
323         }
324         
325         public String getPluginName() {
326                 return pluginName;
327         }
328         
329         public String[] getHeader() {
330                 return header;
331         }
332         
333         public Configuration getConfiguration() {
334                 return configuration;
335         }
336         
337         public boolean isPrimary() {
338                 return getRoot().schemaNSMap.getValues(schemaNs).indexOf(this) == 0;
339         }
340
341
342 }