-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
- boolean createPGraph = true;\r
- boolean createImporter = true;\r
- boolean createExporter = true;\r
- \r
- \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
- 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
- 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
- String ontologyName = schema.getTargetNamespace();\r
- if (ontologyName == null) {\r
- ontologyName = getSchemaFile().getName();\r
- \r
- int index = ontologyName.lastIndexOf(".");\r
- if (index > 0)\r
- ontologyName = ontologyName.substring(0, index);\r
- } \r
- if (!ontologyName.startsWith("http"))\r
- ontologyName = "http://" + ontologyName;\r
- String parts[] = ontologyName.split("/");\r
- String name = parts[parts.length-1];\r
- //String ontRoot = name.substring(0, Math.min(3, name.length())).toUpperCase();\r
-\r
- \r
- name = name.replaceAll("\\.", "_");\r
- name = name.replaceAll(" ", "_");\r
- String className = getPluginName() + "." + name;\r
- \r
- if (createPGraph) {\r
- OntologyGenerator ontologyGenerator = new OntologyGenerator(configuration);\r
- ontologyGenerator.createOntology(schema, ontologyName, className, this);\r
- }\r
- if (createImporter) {\r
- ImporterGenerator importerGenerator = new ImporterGenerator(configuration);\r
- importerGenerator.createParser(schema, className, this);\r
- }\r
- if (createExporter) {\r
- ExporterGenerator exporterGenerator = new ExporterGenerator(configuration);\r
- exporterGenerator.createParser(schema, className, this);\r
- }\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.HashMap;
+import java.util.List;
+import java.util.Map;
+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;
+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 {
+
+ File outputPlugin;
+ File schemaFile;
+ File conversionFile;
+ File ontologyFile;
+ File parserDir;
+ Schema schema;
+ Configuration configuration;
+
+ 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;
+
+ String schemaNs;
+ String ontologyUri;
+ String className;
+ String name;
+ String shortName;
+
+ 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 {
+
+ 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 HashMap<>();
+ 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) 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 = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);
+ subConverter.createPGraph = this.createPGraph;
+ subConverter.createImporter = this.createImporter;
+ subConverter.createExporter = this.createExporter;
+ } else {
+ subConverter.parent.add(this);
+ }
+ return subConverter;
+ }
+
+ 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;
+ }
+ return s;
+ }
+
+ public void convert() throws JAXBException, IOException {
+
+ init();
+ 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 void init() throws IOException, JAXBException {
+ if (init)
+ return;
+ init = true;
+ 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);
+
+ if (conversionFile != null) {
+ jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
+ u = jc.createUnmarshaller();
+ 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 = "";
+ }
+ 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;
+ assignShortName();
+ if (schemaNs != null)
+ getRoot().schemaNSMap.add(schemaNs, this);
+
+
+ for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {
+ if (attrs instanceof Import) {
+ Import imp = (Import)attrs;
+ String location = imp.getSchemaLocation();
+ SchemaConverter sc = createSubConverter(location);
+ sc.init();
+ } else if (attrs instanceof Include) {
+ Include inc = (Include)attrs;
+ String location = inc.getSchemaLocation();
+ SchemaConverter sc = createSubConverter(location);
+ sc.init();
+ } else if (attrs instanceof Annotation) {
+
+ } else {
+ throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");
+ }
+ }
+ }
+
+ protected void doConvert() throws IOException, JAXBException {
+ if (!ontologyFile.exists()) {
+ ontologyFile.getParentFile().mkdirs();
+ ontologyFile.createNewFile();
+ }
+ 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();
+ }
+ 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 boolean isPrimary() {
+ return getRoot() == 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;
+ }
+
+
+}