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