1 package org.simantics.xml.sax;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.List;
13 import java.util.regex.Matcher;
15 import javax.xml.bind.JAXBContext;
16 import javax.xml.bind.JAXBElement;
17 import javax.xml.bind.JAXBException;
18 import javax.xml.bind.Unmarshaller;
19 import javax.xml.namespace.QName;
21 import org.simantics.utils.datastructures.MapList;
22 import org.simantics.xml.sax.configuration.Configuration;
23 import org.w3._2001.xmlschema.Annotation;
24 import org.w3._2001.xmlschema.Import;
25 import org.w3._2001.xmlschema.Include;
26 import org.w3._2001.xmlschema.OpenAttrs;
27 import org.w3._2001.xmlschema.Schema;
30 * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.
35 public class SchemaConverter {
43 Configuration configuration;
47 private String[] header;
49 boolean createPGraph = true;
50 boolean createImporter = true;
51 boolean createExporter = true;
53 private List<SchemaConverter> parent = new ArrayList<>();
54 private List<SchemaConverter> subConverters = new ArrayList<>();
55 private Map<String,SchemaConverter> fileMap;
56 private MapList<String,SchemaConverter> schemaNSMap;
57 private MapList<String,SchemaConverter> shortNameMap;
65 SchemaConversionBase base;
67 private ManualSchemaFileImport fileImport;
69 public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {
70 this(null,schemaFile,conversionFile,outputPlugin);
73 public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {
75 this.outputPlugin = outputPlugin;
76 this.schemaFile = schemaFile;
77 this.conversionFile = conversionFile;
79 pluginName = outputPlugin.getName();
80 String packageParts[] = pluginName.split("\\.");
81 String outputLoc = outputPlugin.getAbsolutePath();
83 for (String s : packageParts)
85 String outputGraph = outputPlugin.getAbsolutePath();
86 outputGraph += "/graph";
87 outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";
90 this.ontologyFile = new File(outputGraph);
91 this.parserDir = new File(outputLoc);
94 this.parent.add(parent);
95 parent.subConverters.add(this);
97 fileMap = new HashMap<>();
98 schemaNSMap = new MapList<>();
99 shortNameMap = new MapList<>();
101 getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);
104 public List<SchemaConverter> getConverter(String schemaNS) {
105 return getRoot().schemaNSMap.getValues(schemaNS);
108 public void setFileImport(ManualSchemaFileImport fileImport) {
109 this.fileImport = fileImport;
113 public void setCreateExporter(boolean createExporter) {
114 this.createExporter = createExporter;
117 public void setCreateImporter(boolean createImporter) {
118 this.createImporter = createImporter;
121 public void setCreatePGraph(boolean createPGraph) {
122 this.createPGraph = createPGraph;
125 protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {
126 File directory = schemaFile.getParentFile();
127 File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);
128 if (!schemaFile.exists()) {
129 if (getRoot().fileImport != null) {
130 schemaFile = getRoot().fileImport.getFileForLocation(location);
132 if (!schemaFile.exists())
133 throw new FileNotFoundException(schemaFile.getAbsolutePath());
135 SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));
136 if (subConverter == null) {
137 subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);
138 subConverter.createPGraph = this.createPGraph;
139 subConverter.createImporter = this.createImporter;
140 subConverter.createExporter = this.createExporter;
142 subConverter.parent.add(this);
147 protected SchemaConverter getRoot() {
148 SchemaConverter s = this;
149 if (s.fileMap != null)
151 while (s.parent.size() > 0) {
153 if (s.fileMap != null)
159 public void convert() throws JAXBException, IOException {
165 boolean init = false;
167 protected void assignShortName() {
168 shortName = name.substring(0, 3).toUpperCase();
169 SchemaConverter root = getRoot();
170 if (!root.shortNameMap.containsKey(shortName)) {
171 root.shortNameMap.add(shortName, this);
174 SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);
175 if (sc.schemaNs.equals(schemaNs)) {
176 root.shortNameMap.add(shortName, this);
182 String n = shortName+i;
183 if (!root.shortNameMap.containsKey(n)) {
185 root.shortNameMap.add(shortName, this);
188 SchemaConverter sc = root.shortNameMap.getValues(n).get(0);
189 if (sc.schemaNs.equals(schemaNs)) {
191 root.shortNameMap.add(shortName, this);
199 protected void init() throws IOException, JAXBException {
203 JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");
204 Unmarshaller u = jc.createUnmarshaller();
205 //u.setSchema(schema);
206 InputStream fileStream = new FileInputStream(schemaFile);
207 schema = (Schema)u.unmarshal(fileStream);
209 if (conversionFile != null) {
210 jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
211 u = jc.createUnmarshaller();
212 fileStream = new FileInputStream(conversionFile);
213 configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();
215 configuration = new Configuration();
218 header = new String[4];
219 header[0] = "Generated with org.simantics.xml.sax XML schema converter";
221 header[2] = "File " + schemaFile.getAbsolutePath().replaceAll(Matcher.quoteReplacement("\\"), "/");
222 header[3] = "Date " + new Date().toString();
224 schemaNs = schema.getTargetNamespace();
226 ontologyUri = schemaNs;
227 if (ontologyUri == null) {
228 ontologyUri = getSchemaFile().getName();
230 int index = ontologyUri.lastIndexOf(".");
232 ontologyUri = ontologyUri.substring(0, index);
235 ontologyUri = ontologyUri.replaceAll(" ", "_");
236 String parts[] = ontologyUri.split("/");
237 for (int i = parts.length-1; i >= 0; i--) {
239 if (!Character.isDigit(name.charAt(0)))
243 throw new JAXBException("Could not resolve proper name for schema " + ontologyUri);
247 name = name.replaceAll("\\.", "_");
248 if (!ontologyUri.startsWith("http://"))
249 ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");
251 ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");
253 String version = schema.getVersion();
256 ontologyUri +="-"+ version;
259 className = getPluginName() + "." + name;
261 if (schemaNs != null)
262 getRoot().schemaNSMap.add(schemaNs, this);
265 for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {
266 if (attrs instanceof Import) {
267 Import imp = (Import)attrs;
268 String location = imp.getSchemaLocation();
269 SchemaConverter sc = createSubConverter(location);
271 } else if (attrs instanceof Include) {
272 Include inc = (Include)attrs;
273 String location = inc.getSchemaLocation();
274 SchemaConverter sc = createSubConverter(location);
276 } else if (attrs instanceof Annotation) {
279 throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");
284 protected void doConvert() throws IOException, JAXBException {
285 if (!ontologyFile.exists()) {
286 ontologyFile.getParentFile().mkdirs();
287 ontologyFile.createNewFile();
289 if (!parserDir.exists())
292 for (SchemaConverter sc : subConverters)
295 base = new SchemaConversionBase(this,ontologyUri,className);
299 OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);
300 ontologyGenerator.createOntology();
302 if (createImporter) {
303 ImporterGenerator importerGenerator = new ImporterGenerator(this,base);
304 importerGenerator.createParser();
306 if (createExporter) {
307 ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);
308 exporterGenerator.createParser();
310 base.component = null;
313 public File getOntologyFile() {
316 public File getParserDir() {
320 public Schema getSchema() {
324 public File getSchemaFile() {
328 public String getPluginName() {
332 public String[] getHeader() {
336 public Configuration getConfiguration() {
337 return configuration;
340 public boolean isPrimary() {
341 return getRoot() == this;
344 public String getShortName(String namespaceURI) {
345 List<SchemaConverter> converters = getRoot().getConverter(namespaceURI);
346 for (SchemaConverter conv : converters) {
347 if (conv.shortName != null)
348 return conv.shortName;
353 public String getOntologyClassName(String namespaceURI) {
354 List<SchemaConverter> converters = getRoot().getConverter(namespaceURI);
355 for (SchemaConverter conv : converters) {
356 if (conv.className != null)
357 return conv.className;