]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConverter.java
Schema parsing can access data from other schemas (work in progress)
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConverter.java
index 523788c8e33971819ed2c709cc79c48c642edb66..ed11c14cd7ad762f9cb4ffc81b49db92ad1387ef 100644 (file)
@@ -2,16 +2,26 @@ package org.simantics.xml.sax;
 \r
 import java.io.File;\r
 import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
+import java.util.ArrayList;\r
 import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
 \r
 import javax.xml.bind.JAXBContext;\r
 import javax.xml.bind.JAXBElement;\r
 import javax.xml.bind.JAXBException;\r
 import javax.xml.bind.Unmarshaller;\r
 \r
+import org.simantics.utils.datastructures.MapList;\r
 import org.simantics.xml.sax.configuration.Configuration;\r
+import org.w3._2001.xmlschema.Annotation;\r
+import org.w3._2001.xmlschema.Import;\r
+import org.w3._2001.xmlschema.Include;\r
+import org.w3._2001.xmlschema.OpenAttrs;\r
 import org.w3._2001.xmlschema.Schema;\r
 \r
 /**\r
@@ -22,6 +32,7 @@ import org.w3._2001.xmlschema.Schema;
  */\r
 public class SchemaConverter {\r
        \r
+       File outputPlugin;\r
        File schemaFile;\r
        File conversionFile;\r
        File ontologyFile;\r
@@ -33,8 +44,36 @@ public class SchemaConverter {
        \r
        private String[] header;\r
        \r
-\r
-       public void convertSchema(File schemaFile, File conversionFile, File outputPlugin) throws JAXBException, IOException {\r
+       boolean createPGraph = true;\r
+       boolean createImporter = true;\r
+       boolean createExporter = true;\r
+       \r
+       private List<SchemaConverter> parent = new ArrayList<>();\r
+       private List<SchemaConverter> subConverters = new ArrayList<>();\r
+       private Map<String,SchemaConverter> fileMap;\r
+       private MapList<String,SchemaConverter> schemaNSMap;\r
+       private MapList<String,SchemaConverter> shortNameMap;\r
+       \r
+       String schemaNs;\r
+       String ontologyUri;\r
+       String className;\r
+       String name;\r
+       String shortName;\r
+       \r
+       SchemaConversionBase base;\r
+       \r
+       private ManualSchemaFileImport fileImport;\r
+       \r
+       public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {\r
+               this(null,schemaFile,conversionFile,outputPlugin);\r
+       }\r
+       \r
+       public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {\r
+               \r
+               this.outputPlugin = outputPlugin;\r
+               this.schemaFile = schemaFile;\r
+               this.conversionFile = conversionFile;\r
+               \r
                pluginName = outputPlugin.getName();\r
                String packageParts[] = pluginName.split("\\.");\r
                String outputLoc = outputPlugin.getAbsolutePath();\r
@@ -45,23 +84,115 @@ public class SchemaConverter {
                outputGraph += "/graph";\r
                outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";\r
                \r
-               this.schemaFile = schemaFile;\r
-               this.conversionFile = conversionFile;\r
+               \r
                this.ontologyFile = new File(outputGraph);\r
                this.parserDir = new File(outputLoc);\r
                \r
-               if (!ontologyFile.exists()) {\r
-                       ontologyFile.getParentFile().mkdirs();\r
-                       ontologyFile.createNewFile();\r
+               if (parent != null) {\r
+                       this.parent.add(parent);\r
+                       parent.subConverters.add(this);\r
+               } else {\r
+                       fileMap = new HashMap<>();\r
+                       schemaNSMap = new MapList<>();\r
+                       shortNameMap = new MapList<>();\r
                }\r
-               if (!parserDir.exists())\r
-                       parserDir.mkdirs();\r
-               \r
-               convert();\r
+               getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);\r
+       }\r
+       \r
+       public List<SchemaConverter> getConverter(String schemaNS) {\r
+               return getRoot().schemaNSMap.getValues(schemaNS);\r
+       }\r
+       \r
+       public void setFileImport(ManualSchemaFileImport fileImport) {\r
+               this.fileImport = fileImport;\r
+       }\r
+\r
+       \r
+       public void setCreateExporter(boolean createExporter) {\r
+               this.createExporter = createExporter;\r
+       }\r
+       \r
+       public void setCreateImporter(boolean createImporter) {\r
+               this.createImporter = createImporter;\r
+       }\r
+       \r
+       public void setCreatePGraph(boolean createPGraph) {\r
+               this.createPGraph = createPGraph;\r
+       }\r
+       \r
+       protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {\r
+               File directory = schemaFile.getParentFile();\r
+               File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);\r
+               if (!schemaFile.exists()) {\r
+                       if (getRoot().fileImport != null) {\r
+                               schemaFile = getRoot().fileImport.getFileForLocation(location);\r
+                       }\r
+                       if (!schemaFile.exists())\r
+                               throw new FileNotFoundException(schemaFile.getAbsolutePath());\r
+               }\r
+               SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));\r
+               if (subConverter == null) {\r
+                       subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);\r
+                       subConverter.createPGraph = this.createPGraph;\r
+                       subConverter.createImporter = this.createImporter;\r
+                       subConverter.createExporter = this.createExporter;\r
+               } else {\r
+                       subConverter.parent.add(this);\r
+               }\r
+               return subConverter;\r
+       }\r
+       \r
+       protected SchemaConverter getRoot() {\r
+               SchemaConverter s = this;\r
+               while (s.parent.size() > 0)\r
+                       s = s.parent.get(0);\r
+               return s;\r
+       }\r
+       \r
+       public void convert() throws JAXBException, IOException {\r
                \r
+               init();\r
+               doConvert();\r
        }\r
        \r
-       private void convert() throws JAXBException, IOException {\r
+       boolean init = false;\r
+       \r
+       protected void assignShortName() {\r
+               shortName = name.substring(0, 3).toUpperCase();\r
+               SchemaConverter root = getRoot();\r
+               if (!root.shortNameMap.containsKey(shortName)) {\r
+                       root.shortNameMap.add(shortName, this);\r
+                       return;\r
+               } else {\r
+                       SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);\r
+                       if (sc.schemaNs.equals(schemaNs)) {\r
+                               root.shortNameMap.add(shortName, this);\r
+                               return;\r
+                       }\r
+               }\r
+               int i = 1;\r
+               while (true) {\r
+                       String n = shortName+i;\r
+                       if (!root.shortNameMap.containsKey(n)) {\r
+                               shortName = n;\r
+                               root.shortNameMap.add(shortName, this);\r
+                               return;\r
+                       } else {\r
+                               SchemaConverter sc = root.shortNameMap.getValues(n).get(0);\r
+                               if (sc.schemaNs.equals(schemaNs)) {\r
+                                       shortName = n;\r
+                                       root.shortNameMap.add(shortName, this);\r
+                                       return;\r
+                               }\r
+                       }\r
+                       i++;\r
+               }\r
+       }\r
+       \r
+       protected void init() throws IOException, JAXBException {\r
+               if (init)\r
+                       return;\r
+               init = true;\r
                JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");\r
                Unmarshaller u = jc.createUnmarshaller();\r
                //u.setSchema(schema);\r
@@ -83,11 +214,82 @@ public class SchemaConverter {
                header[2] = "File " + schemaFile.getAbsolutePath();\r
                header[3] = "Date " + new Date().toString();\r
                \r
+               schemaNs = schema.getTargetNamespace();\r
+               ontologyUri = schemaNs;\r
+               if (ontologyUri == null) {\r
+                       ontologyUri = getSchemaFile().getName();\r
+                       \r
+                       int index = ontologyUri.lastIndexOf(".");\r
+                       if (index > 0)\r
+                               ontologyUri = ontologyUri.substring(0, index);\r
+               } \r
+               ontologyUri = ontologyUri.replaceAll(" ", "_");\r
+               String parts[] = ontologyUri.split("/");\r
+               name = parts[parts.length-1];\r
+               name = name.replaceAll("\\.", "_");\r
+               if (!ontologyUri.startsWith("http://"))\r
+                       ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");\r
+               else\r
+                       ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");\r
+               \r
+               String version = schema.getVersion();\r
+               if (version == null)\r
+                       version = "1.0";\r
+               ontologyUri +="-"+ version;\r
+\r
+               \r
+               className = getPluginName() + "." + name;\r
+               assignShortName();\r
+               if (schemaNs != null)\r
+                       getRoot().schemaNSMap.add(schemaNs, this);\r
                \r
-               OntologyGenerator ontologyGenerator = new OntologyGenerator(configuration);\r
-               ontologyGenerator.createOntology(schema, this);\r
-               ImporterGenerator importerGenerator = new ImporterGenerator(configuration);\r
-               importerGenerator.createParser(schema, ontologyGenerator.getClassName(), this);\r
+               \r
+               for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {\r
+                       if (attrs instanceof Import) {\r
+                               Import imp = (Import)attrs;\r
+                               String location = imp.getSchemaLocation();\r
+                               SchemaConverter sc = createSubConverter(location);\r
+                               sc.init();\r
+                       } else if (attrs instanceof Include) {\r
+                               Include inc = (Include)attrs;\r
+                               String location = inc.getSchemaLocation();\r
+                               SchemaConverter sc = createSubConverter(location);\r
+                               sc.init();\r
+                       } else if (attrs instanceof Annotation) {\r
+                               \r
+                       } else {\r
+                               throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");\r
+                       }\r
+               }\r
+       }\r
+       \r
+       protected void doConvert() throws IOException, JAXBException {\r
+               if (!ontologyFile.exists()) {\r
+                       ontologyFile.getParentFile().mkdirs();\r
+                       ontologyFile.createNewFile();\r
+               }\r
+               if (!parserDir.exists())\r
+                       parserDir.mkdirs();\r
+               \r
+               for (SchemaConverter sc : subConverters)\r
+                       sc.doConvert();\r
+               \r
+               base = new SchemaConversionBase(this,ontologyUri,className);\r
+               base.init(schema);\r
+               \r
+               if (createPGraph) {\r
+                       OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);\r
+                       ontologyGenerator.createOntology();\r
+               }\r
+               if (createImporter) {\r
+                       ImporterGenerator importerGenerator = new ImporterGenerator(this,base);\r
+                       importerGenerator.createParser();\r
+               }\r
+               if (createExporter) {\r
+                       ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);\r
+                       exporterGenerator.createParser();\r
+               }\r
+               base.component = null;\r
        }\r
        \r
        public File getOntologyFile() {\r