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