]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.xml.sax/src/org/simantics/xml/sax/SchemaConverter.java
Replace log4j with slf4j
[simantics/interop.git] / org.simantics.xml.sax / src / org / simantics / xml / sax / SchemaConverter.java
index 523788c8e33971819ed2c709cc79c48c642edb66..660b990975f640c66bc093f541fa024ccda7f16f 100644 (file)
-package org.simantics.xml.sax;\r
-\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.util.Date;\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.xml.sax.configuration.Configuration;\r
-import org.w3._2001.xmlschema.Schema;\r
-\r
-/**\r
- * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.\r
- * \r
- * @author mlmarko\r
- *\r
- */\r
-public class SchemaConverter {\r
-       \r
-       File schemaFile;\r
-       File conversionFile;\r
-       File ontologyFile;\r
-       File parserDir;\r
-       Schema schema;\r
-       Configuration configuration;\r
-       \r
-       String pluginName;\r
-       \r
-       private String[] header;\r
-       \r
-\r
-       public void convertSchema(File schemaFile, File conversionFile, File outputPlugin) throws JAXBException, IOException {\r
-               pluginName = outputPlugin.getName();\r
-               String packageParts[] = pluginName.split("\\.");\r
-               String outputLoc = outputPlugin.getAbsolutePath();\r
-               outputLoc += "/src";\r
-               for (String s : packageParts)\r
-                       outputLoc += "/"+s;\r
-               String outputGraph = outputPlugin.getAbsolutePath();\r
-               outputGraph += "/graph";\r
-               outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";\r
-               \r
-               this.schemaFile = schemaFile;\r
-               this.conversionFile = conversionFile;\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
-               }\r
-               if (!parserDir.exists())\r
-                       parserDir.mkdirs();\r
-               \r
-               convert();\r
-               \r
-       }\r
-       \r
-       private void convert() throws JAXBException, IOException {\r
-               JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");\r
-               Unmarshaller u = jc.createUnmarshaller();\r
-               //u.setSchema(schema);\r
-        InputStream fileStream = new FileInputStream(schemaFile);\r
-               schema = (Schema)u.unmarshal(fileStream);\r
-               \r
-               if (conversionFile != null) {\r
-                       jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");\r
-                       u = jc.createUnmarshaller();\r
-                       fileStream = new FileInputStream(conversionFile);\r
-                       configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();\r
-               } else {\r
-                       configuration = new Configuration();\r
-               }\r
-               \r
-               header = new String[4];\r
-               header[0] = "Generated with org.simantics.xml.sax XML schema converter";\r
-               header[1] = "";\r
-               header[2] = "File " + schemaFile.getAbsolutePath();\r
-               header[3] = "Date " + new Date().toString();\r
-               \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
-       \r
-       public File getOntologyFile() {\r
-               return ontologyFile;\r
-       }\r
-       public File getParserDir() {\r
-               return parserDir;\r
-       }\r
-       \r
-       public Schema getSchema() {\r
-               return schema;\r
-       }\r
-       \r
-       public File getSchemaFile() {\r
-               return schemaFile;\r
-       }\r
-       \r
-       public String getPluginName() {\r
-               return pluginName;\r
-       }\r
-       \r
-       public String[] getHeader() {\r
-               return header;\r
-       }\r
-       \r
-       public Configuration getConfiguration() {\r
-               return configuration;\r
-       }\r
-\r
-\r
-}\r
+package org.simantics.xml.sax;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+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 org.simantics.utils.datastructures.MapList;
+import org.simantics.xml.sax.configuration.Configuration;
+import org.w3._2001.xmlschema.Annotation;
+import org.w3._2001.xmlschema.Import;
+import org.w3._2001.xmlschema.Include;
+import org.w3._2001.xmlschema.OpenAttrs;
+import org.w3._2001.xmlschema.Schema;
+
+/**
+ * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.
+ * 
+ * @author mlmarko
+ *
+ */
+public class SchemaConverter {
+       
+       protected File outputPlugin;
+       protected File schemaFile;
+       protected File conversionFile;
+       protected File ontologyFile;
+       protected File parserDir;
+       protected Schema schema;
+       protected Configuration configuration;
+       
+       protected String pluginName;
+       
+       private String[] header;
+       
+       boolean createPGraph = true;
+       boolean createImporter = true;
+       boolean createExporter = true;
+       
+       private List<SchemaConverter> parent = new ArrayList<>();
+       private List<SchemaConverter> subConverters = new ArrayList<>();
+       private Map<String,SchemaConverter> fileMap;
+       private MapList<String,SchemaConverter> schemaNSMap;
+       private MapList<String,SchemaConverter> shortNameMap;
+       
+       protected String schemaNs;
+       protected String ontologyUri;
+       protected String className;
+       protected String name;
+       protected String shortName;
+       
+       protected SchemaConversionBase base;
+       
+       private ManualSchemaFileImport fileImport;
+       
+       public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {
+               this(null,schemaFile,conversionFile,outputPlugin);
+       }
+       
+       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;
+               
+               pluginName = outputPlugin.getName();
+               String packageParts[] = pluginName.split("\\.");
+               String outputLoc = outputPlugin.getAbsolutePath();
+               outputLoc += "/src";
+               for (String s : packageParts)
+                       outputLoc += "/"+s;
+               String outputGraph = outputPlugin.getAbsolutePath();
+               outputGraph += "/graph";
+               outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";
+               
+               
+               this.ontologyFile = new File(outputGraph);
+               this.parserDir = new File(outputLoc);
+               
+               if (parent != null) {
+                       this.parent.add(parent);
+                       parent.subConverters.add(this);
+               } else {
+                       fileMap = new LinkedHashMap<>();
+                       schemaNSMap = new MapList<>();
+                       shortNameMap = new MapList<>();
+               }
+               getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);
+       }
+       
+       public List<SchemaConverter> getConverter(String schemaNS) {
+               return getRoot().schemaNSMap.getValues(schemaNS);
+       }
+       
+       public void setFileImport(ManualSchemaFileImport fileImport) {
+               this.fileImport = fileImport;
+       }
+
+       
+       public void setCreateExporter(boolean createExporter) {
+               this.createExporter = createExporter;
+       }
+       
+       public void setCreateImporter(boolean createImporter) {
+               this.createImporter = createImporter;
+       }
+       
+       public void setCreatePGraph(boolean createPGraph) {
+               this.createPGraph = createPGraph;
+       }
+       
+       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()) {
+                       if (getRoot().fileImport != null) {
+                               schemaFile = getRoot().fileImport.getFileForLocation(location);
+                       }
+                       if (!schemaFile.exists())
+                               throw new FileNotFoundException(schemaFile.getAbsolutePath());
+               }
+               SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));
+               if (subConverter == null) {
+                       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() {
+               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 null;
+       }
+       
+       public void convert() throws JAXBException, IOException {
+               
+               init();
+               for (SchemaConverter sc : getRoot().fileMap.values()) {
+                       sc.doConvert();
+               }
+       }
+       
+       boolean init = false;
+       
+       protected void assignShortName() {
+               shortName = name.substring(0, 3).toUpperCase();
+               SchemaConverter root = getRoot();
+               if (!root.shortNameMap.containsKey(shortName)) {
+                       root.shortNameMap.add(shortName, this);
+                       return;
+               } else {
+                       SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);
+                       if (sc.schemaNs.equals(schemaNs)) {
+                               root.shortNameMap.add(shortName, this);
+                               return;
+                       }
+               }
+               int i = 1;
+               while (true) {
+                       String n = shortName+i;
+                       if (!root.shortNameMap.containsKey(n)) {
+                               shortName = n;
+                               root.shortNameMap.add(shortName, this);
+                               return;
+                       } else {
+                               SchemaConverter sc = root.shortNameMap.getValues(n).get(0);
+                               if (sc.schemaNs.equals(schemaNs)) {
+                                       shortName = n;
+                                       root.shortNameMap.add(shortName, this);
+                                       return;
+                               }
+                       }
+                       i++;
+               }
+       }
+       
+       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);
+               return (Schema)u.unmarshal(fileStream);
+       }
+       
+       protected void init() throws IOException, JAXBException {
+               if (init)
+                       return;
+               init = true;
+               
+               schema = createSchema();
+               
+               if (conversionFile != null) {
+                       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();
+               }
+               
+               header = new String[4];
+               header[0] = "Generated with org.simantics.xml.sax XML schema converter";
+               header[1] = "";
+               header[2] = "File " + schemaFile.getAbsolutePath().replaceAll(Matcher.quoteReplacement("\\"), "/");
+               header[3] = "Date " + new Date().toString();
+               
+               schemaNs = schema.getTargetNamespace();
+               
+               ontologyUri = schemaNs;
+               if (ontologyUri == null) {
+                       ontologyUri = getSchemaFile().getName();
+                       
+                       int index = ontologyUri.lastIndexOf(".");
+                       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];
+                       if (!Character.isDigit(name.charAt(0)))
+                               break;
+               }
+               if (name == null) {
+                       throw new JAXBException("Could not resolve proper name for schema " + ontologyUri);
+               }
+               
+               
+               name = name.replaceAll("\\.", "_");
+               if (!ontologyUri.startsWith("http://"))
+                       ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");
+               else
+                       ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");
+               
+               String version = schema.getVersion();
+               if (version == null)
+                       version = "1.0";
+               ontologyUri +="-"+ version;
+
+               
+               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, imp.getNamespace());
+                               sc.init();
+                       } else if (attrs instanceof Include) {
+                               Include inc = (Include)attrs;
+                               String location = inc.getSchemaLocation();
+                               SchemaConverter sc = createSubConverter(location, null);
+                               sc.init();
+                       } else if (attrs instanceof Annotation) {
+                               
+                       } else {
+                               throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");
+                       }
+               }
+       }
+
+       private boolean converting = false;
+       
+       protected void doConvert() throws IOException, JAXBException {
+               if (converting)
+                       return;
+               converting = true;
+               if (!ontologyFile.exists()) {
+                       ontologyFile.getParentFile().mkdirs();
+                       ontologyFile.createNewFile();
+               }
+               if (!parserDir.exists())
+                       parserDir.mkdirs();
+               
+               if (createPGraph) {
+                       OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);
+                       ontologyGenerator.createOntology();
+               }
+               if (createImporter) {
+                       ImporterGenerator importerGenerator = new ImporterGenerator(this,base);
+                       importerGenerator.createParser();
+               }
+               if (createExporter) {
+                       ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);
+                       exporterGenerator.createParser();
+               }
+               base.component = null;
+       }
+       
+       public File getOntologyFile() {
+               return ontologyFile;
+       }
+       public File getParserDir() {
+               return parserDir;
+       }
+       
+       public Schema getSchema() {
+               return schema;
+       }
+       
+       public File getSchemaFile() {
+               return schemaFile;
+       }
+       
+       public String getPluginName() {
+               return pluginName;
+       }
+       
+       public String[] getHeader() {
+               return header;
+       }
+       
+       public Configuration getConfiguration() {
+               return configuration;
+       }
+       
+       public List<SchemaConverter> getParent() {
+               return parent;
+       }
+       
+       public List<SchemaConverter> getSubConverters() {
+               return subConverters;
+       }
+       
+       public boolean isPrimary() {
+               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) {
+               List<SchemaConverter> converters = getRoot().getConverter(namespaceURI);
+               for (SchemaConverter conv : converters) {
+                       if (conv.shortName != null)
+                               return conv.shortName;
+               }
+               return null;
+       }
+       
+       public String getOntologyClassName(String namespaceURI) {
+               List<SchemaConverter> converters = getRoot().getConverter(namespaceURI);
+               for (SchemaConverter conv : converters) {
+                       if (conv.className != null)
+                               return conv.className;
+               }
+               return null;
+       }
+
+
+}