]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConverter.java
XML data based schema and ontology generation
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConverter.java
index adab7f2af75112da339adba44dabab01fceb50f5..660b990975f640c66bc093f541fa024ccda7f16f 100644 (file)
@@ -7,16 +7,17 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Matcher;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
-import javax.xml.namespace.QName;
 
 import org.simantics.utils.datastructures.MapList;
 import org.simantics.xml.sax.configuration.Configuration;
@@ -34,15 +35,15 @@ import org.w3._2001.xmlschema.Schema;
  */
 public class SchemaConverter {
        
-       File outputPlugin;
-       File schemaFile;
-       File conversionFile;
-       File ontologyFile;
-       File parserDir;
-       Schema schema;
-       Configuration configuration;
+       protected File outputPlugin;
+       protected File schemaFile;
+       protected File conversionFile;
+       protected File ontologyFile;
+       protected File parserDir;
+       protected Schema schema;
+       protected Configuration configuration;
        
-       String pluginName;
+       protected String pluginName;
        
        private String[] header;
        
@@ -56,13 +57,13 @@ public class SchemaConverter {
        private MapList<String,SchemaConverter> schemaNSMap;
        private MapList<String,SchemaConverter> shortNameMap;
        
-       String schemaNs;
-       String ontologyUri;
-       String className;
-       String name;
-       String shortName;
+       protected String schemaNs;
+       protected String ontologyUri;
+       protected String className;
+       protected String name;
+       protected String shortName;
        
-       SchemaConversionBase base;
+       protected SchemaConversionBase base;
        
        private ManualSchemaFileImport fileImport;
        
@@ -71,7 +72,8 @@ public class SchemaConverter {
        }
        
        public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {
-               
+               if (schemaFile == null || outputPlugin == null)
+                       throw new IllegalArgumentException();
                this.outputPlugin = outputPlugin;
                this.schemaFile = schemaFile;
                this.conversionFile = conversionFile;
@@ -94,7 +96,7 @@ public class SchemaConverter {
                        this.parent.add(parent);
                        parent.subConverters.add(this);
                } else {
-                       fileMap = new HashMap<>();
+                       fileMap = new LinkedHashMap<>();
                        schemaNSMap = new MapList<>();
                        shortNameMap = new MapList<>();
                }
@@ -122,7 +124,7 @@ public class SchemaConverter {
                this.createPGraph = createPGraph;
        }
        
-       protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {
+       protected SchemaConverter createSubConverter(String location, String ns) throws JAXBException, IOException {
                File directory = schemaFile.getParentFile();
                File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);
                if (!schemaFile.exists()) {
@@ -134,32 +136,53 @@ public class SchemaConverter {
                }
                SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));
                if (subConverter == null) {
-                       subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);
+                       subConverter = constructSubConverter(this, schemaFile, conversionFile, outputPlugin, ns);
                        subConverter.createPGraph = this.createPGraph;
                        subConverter.createImporter = this.createImporter;
                        subConverter.createExporter = this.createExporter;
                } else {
                        subConverter.parent.add(this);
+                       subConverters.add(subConverter);
                }
                return subConverter;
        }
        
+       protected SchemaConverter constructSubConverter(SchemaConverter parent, File schemaFile, File conversionFile, File outputPlugin, String ns) throws IOException {
+               return new SchemaConverter(parent,schemaFile, conversionFile, outputPlugin);
+       }
+       
        protected SchemaConverter getRoot() {
-               SchemaConverter s = this;
-               if (s.fileMap != null)
-                       return s;
-               while (s.parent.size() > 0) {
-                       s = s.parent.get(0);
-                       if (s.fileMap != null)
-                               return s;
+               if (this.fileMap != null)
+                       return this;
+               Set<SchemaConverter> processed = new HashSet<>();
+               return _getRoot(processed);
+       }
+       
+       protected SchemaConverter _getRoot(Set<SchemaConverter> processed) {
+               if (processed.contains(this))
+                       return null;
+               if (this.fileMap != null)
+                       return this;
+               processed.add(this);
+               
+               for (SchemaConverter sc : this.parent) {
+                       if (sc.fileMap != null)
+                               return sc;
+               }
+               for (SchemaConverter sc : this.parent) {
+                       SchemaConverter root = sc._getRoot(processed);
+                       if (root != null)
+                               return root;
                }
-               return s;
+               return null;
        }
        
        public void convert() throws JAXBException, IOException {
                
                init();
-               doConvert();
+               for (SchemaConverter sc : getRoot().fileMap.values()) {
+                       sc.doConvert();
+               }
        }
        
        boolean init = false;
@@ -196,20 +219,25 @@ public class SchemaConverter {
                }
        }
        
-       protected void init() throws IOException, JAXBException {
-               if (init)
-                       return;
-               init = true;
+       protected Schema createSchema() throws JAXBException, FileNotFoundException {
                JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");
                Unmarshaller u = jc.createUnmarshaller();
                //u.setSchema(schema);
         InputStream fileStream = new FileInputStream(schemaFile);
-               schema = (Schema)u.unmarshal(fileStream);
+               return (Schema)u.unmarshal(fileStream);
+       }
+       
+       protected void init() throws IOException, JAXBException {
+               if (init)
+                       return;
+               init = true;
+               
+               schema = createSchema();
                
                if (conversionFile != null) {
-                       jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
-                       u = jc.createUnmarshaller();
-                       fileStream = new FileInputStream(conversionFile);
+                       JAXBContext jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
+                       Unmarshaller u = jc.createUnmarshaller();
+                       InputStream fileStream = new FileInputStream(conversionFile);
                        configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();
                } else {
                        configuration = new Configuration();
@@ -231,8 +259,18 @@ public class SchemaConverter {
                        if (index > 0)
                                ontologyUri = ontologyUri.substring(0, index);
                        schemaNs = "";
-               } 
+               } else {
+                       // Special case for XAML
+                       if (ontologyUri.startsWith("clr-namespace:")) {
+                               ontologyUri = ontologyUri.substring("clr-namespace:".length());
+                               int i = ontologyUri.indexOf(";assembly");
+                               if (i > 0)
+                                       ontologyUri = ontologyUri.substring(0, i);
+                       }
+               }
                ontologyUri = ontologyUri.replaceAll(" ", "_");
+               ontologyUri = ontologyUri.replaceAll(":", "_");
+               ontologyUri = ontologyUri.replaceAll(";", "_");
                String parts[] = ontologyUri.split("/");
                for (int i = parts.length-1; i >= 0; i--) {
                        name = parts[i];
@@ -256,22 +294,24 @@ public class SchemaConverter {
                ontologyUri +="-"+ version;
 
                
-               className = getPluginName() + "." + name;
+               className = getPluginName() + "." + name + "Ontology";
                assignShortName();
                if (schemaNs != null)
                        getRoot().schemaNSMap.add(schemaNs, this);
                
+               base = new SchemaConversionBase(this,ontologyUri,className);
+               base.init(schema);
                
                for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {
                        if (attrs instanceof Import) {
                                Import imp = (Import)attrs;
                                String location = imp.getSchemaLocation();
-                               SchemaConverter sc = createSubConverter(location);
+                               SchemaConverter sc = createSubConverter(location, imp.getNamespace());
                                sc.init();
                        } else if (attrs instanceof Include) {
                                Include inc = (Include)attrs;
                                String location = inc.getSchemaLocation();
-                               SchemaConverter sc = createSubConverter(location);
+                               SchemaConverter sc = createSubConverter(location, null);
                                sc.init();
                        } else if (attrs instanceof Annotation) {
                                
@@ -280,8 +320,13 @@ public class SchemaConverter {
                        }
                }
        }
+
+       private boolean converting = false;
        
        protected void doConvert() throws IOException, JAXBException {
+               if (converting)
+                       return;
+               converting = true;
                if (!ontologyFile.exists()) {
                        ontologyFile.getParentFile().mkdirs();
                        ontologyFile.createNewFile();
@@ -289,12 +334,6 @@ public class SchemaConverter {
                if (!parserDir.exists())
                        parserDir.mkdirs();
                
-               for (SchemaConverter sc : subConverters)
-                       sc.doConvert();
-               
-               base = new SchemaConversionBase(this,ontologyUri,className);
-               base.init(schema);
-               
                if (createPGraph) {
                        OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);
                        ontologyGenerator.createOntology();
@@ -337,8 +376,21 @@ public class SchemaConverter {
                return configuration;
        }
        
+       public List<SchemaConverter> getParent() {
+               return parent;
+       }
+       
+       public List<SchemaConverter> getSubConverters() {
+               return subConverters;
+       }
+       
        public boolean isPrimary() {
-               return getRoot() == this;
+               return true;
+//             if (getRoot() == this)
+//                     return true;
+//             List<SchemaConverter> conv = new ArrayList<>(getRoot().fileMap.values());
+//             int current = conv.indexOf(this);
+               
        }
 
        public String getShortName(String namespaceURI) {