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;
20 import org.simantics.utils.datastructures.MapList;
21 import org.simantics.xml.sax.configuration.Configuration;
22 import org.w3._2001.xmlschema.Annotation;
23 import org.w3._2001.xmlschema.Import;
24 import org.w3._2001.xmlschema.Include;
25 import org.w3._2001.xmlschema.OpenAttrs;
26 import org.w3._2001.xmlschema.Schema;
29 * This file is developed for XMpLant / Proteus schema conversion is not able to handle all XML Schema definitions.
34 public class SchemaConverter {
42 Configuration configuration;
46 private String[] header;
48 boolean createPGraph = true;
49 boolean createImporter = true;
50 boolean createExporter = true;
52 private List<SchemaConverter> parent = new ArrayList<>();
53 private List<SchemaConverter> subConverters = new ArrayList<>();
54 private Map<String,SchemaConverter> fileMap;
55 private MapList<String,SchemaConverter> schemaNSMap;
56 private MapList<String,SchemaConverter> shortNameMap;
64 SchemaConversionBase base;
66 private ManualSchemaFileImport fileImport;
68 public SchemaConverter(File schemaFile, File conversionFile, File outputPlugin) throws IOException {
69 this(null,schemaFile,conversionFile,outputPlugin);
72 public SchemaConverter(SchemaConverter parent,File schemaFile, File conversionFile, File outputPlugin) throws IOException {
74 this.outputPlugin = outputPlugin;
75 this.schemaFile = schemaFile;
76 this.conversionFile = conversionFile;
78 pluginName = outputPlugin.getName();
79 String packageParts[] = pluginName.split("\\.");
80 String outputLoc = outputPlugin.getAbsolutePath();
82 for (String s : packageParts)
84 String outputGraph = outputPlugin.getAbsolutePath();
85 outputGraph += "/graph";
86 outputGraph += "/" + schemaFile.getName().substring(0, schemaFile.getName().length()-4) +".pgraph";
89 this.ontologyFile = new File(outputGraph);
90 this.parserDir = new File(outputLoc);
93 this.parent.add(parent);
94 parent.subConverters.add(this);
96 fileMap = new HashMap<>();
97 schemaNSMap = new MapList<>();
98 shortNameMap = new MapList<>();
100 getRoot().fileMap.put(schemaFile.getAbsolutePath(), this);
103 public List<SchemaConverter> getConverter(String schemaNS) {
104 return getRoot().schemaNSMap.getValues(schemaNS);
107 public void setFileImport(ManualSchemaFileImport fileImport) {
108 this.fileImport = fileImport;
112 public void setCreateExporter(boolean createExporter) {
113 this.createExporter = createExporter;
116 public void setCreateImporter(boolean createImporter) {
117 this.createImporter = createImporter;
120 public void setCreatePGraph(boolean createPGraph) {
121 this.createPGraph = createPGraph;
124 protected SchemaConverter createSubConverter(String location) throws JAXBException, IOException {
125 File directory = schemaFile.getParentFile();
126 File schemaFile = new File(directory.getAbsolutePath()+File.separator+location);
127 if (!schemaFile.exists()) {
128 if (getRoot().fileImport != null) {
129 schemaFile = getRoot().fileImport.getFileForLocation(location);
131 if (!schemaFile.exists())
132 throw new FileNotFoundException(schemaFile.getAbsolutePath());
134 SchemaConverter subConverter = getRoot().fileMap.get((schemaFile.getAbsolutePath()));
135 if (subConverter == null) {
136 subConverter = new SchemaConverter(this,schemaFile, conversionFile, outputPlugin);
137 subConverter.createPGraph = this.createPGraph;
138 subConverter.createImporter = this.createImporter;
139 subConverter.createExporter = this.createExporter;
141 subConverter.parent.add(this);
146 protected SchemaConverter getRoot() {
147 SchemaConverter s = this;
148 if (s.fileMap != null)
150 while (s.parent.size() > 0) {
152 if (s.fileMap != null)
158 public void convert() throws JAXBException, IOException {
164 boolean init = false;
166 protected void assignShortName() {
167 shortName = name.substring(0, 3).toUpperCase();
168 SchemaConverter root = getRoot();
169 if (!root.shortNameMap.containsKey(shortName)) {
170 root.shortNameMap.add(shortName, this);
173 SchemaConverter sc = root.shortNameMap.getValues(shortName).get(0);
174 if (sc.schemaNs.equals(schemaNs)) {
175 root.shortNameMap.add(shortName, this);
181 String n = shortName+i;
182 if (!root.shortNameMap.containsKey(n)) {
184 root.shortNameMap.add(shortName, this);
187 SchemaConverter sc = root.shortNameMap.getValues(n).get(0);
188 if (sc.schemaNs.equals(schemaNs)) {
190 root.shortNameMap.add(shortName, this);
198 protected void init() throws IOException, JAXBException {
202 JAXBContext jc = JAXBContext.newInstance("org.w3._2001.xmlschema");
203 Unmarshaller u = jc.createUnmarshaller();
204 //u.setSchema(schema);
205 InputStream fileStream = new FileInputStream(schemaFile);
206 schema = (Schema)u.unmarshal(fileStream);
208 if (conversionFile != null) {
209 jc = JAXBContext.newInstance("org.simantics.xml.sax.configuration");
210 u = jc.createUnmarshaller();
211 fileStream = new FileInputStream(conversionFile);
212 configuration = (Configuration)((JAXBElement<?>)u.unmarshal(fileStream)).getValue();
214 configuration = new Configuration();
217 header = new String[4];
218 header[0] = "Generated with org.simantics.xml.sax XML schema converter";
220 header[2] = "File " + schemaFile.getAbsolutePath().replaceAll(Matcher.quoteReplacement("\\"), "/");
221 header[3] = "Date " + new Date().toString();
223 schemaNs = schema.getTargetNamespace();
224 ontologyUri = schemaNs;
225 if (ontologyUri == null) {
226 ontologyUri = getSchemaFile().getName();
228 int index = ontologyUri.lastIndexOf(".");
230 ontologyUri = ontologyUri.substring(0, index);
232 ontologyUri = ontologyUri.replaceAll(" ", "_");
233 String parts[] = ontologyUri.split("/");
234 for (int i = parts.length-1; i >= 0; i--) {
236 if (!Character.isDigit(name.charAt(0)))
240 throw new JAXBException("Could not resolve proper name for schema " + ontologyUri);
244 name = name.replaceAll("\\.", "_");
245 if (!ontologyUri.startsWith("http://"))
246 ontologyUri = "http://" + ontologyUri.replaceAll("/", "_");
248 ontologyUri = "http://" + ontologyUri.substring("http://".length()).replaceAll("/", "_");
250 String version = schema.getVersion();
253 ontologyUri +="-"+ version;
256 className = getPluginName() + "." + name;
258 if (schemaNs != null)
259 getRoot().schemaNSMap.add(schemaNs, this);
262 for (OpenAttrs attrs : schema.getIncludeOrImportOrRedefine()) {
263 if (attrs instanceof Import) {
264 Import imp = (Import)attrs;
265 String location = imp.getSchemaLocation();
266 SchemaConverter sc = createSubConverter(location);
268 } else if (attrs instanceof Include) {
269 Include inc = (Include)attrs;
270 String location = inc.getSchemaLocation();
271 SchemaConverter sc = createSubConverter(location);
273 } else if (attrs instanceof Annotation) {
276 throw new IOException("Cannot handle schema file " + schemaFile.getName() + ", the schema uses redefine elements.");
281 protected void doConvert() throws IOException, JAXBException {
282 if (!ontologyFile.exists()) {
283 ontologyFile.getParentFile().mkdirs();
284 ontologyFile.createNewFile();
286 if (!parserDir.exists())
289 for (SchemaConverter sc : subConverters)
292 base = new SchemaConversionBase(this,ontologyUri,className);
296 OntologyGenerator ontologyGenerator = new OntologyGenerator(this,base);
297 ontologyGenerator.createOntology();
299 if (createImporter) {
300 ImporterGenerator importerGenerator = new ImporterGenerator(this,base);
301 importerGenerator.createParser();
303 if (createExporter) {
304 ExporterGenerator exporterGenerator = new ExporterGenerator(this,base);
305 exporterGenerator.createParser();
307 base.component = null;
310 public File getOntologyFile() {
313 public File getParserDir() {
317 public Schema getSchema() {
321 public File getSchemaFile() {
325 public String getPluginName() {
329 public String[] getHeader() {
333 public Configuration getConfiguration() {
334 return configuration;
337 public boolean isPrimary() {
338 return getRoot().schemaNSMap.getValues(schemaNs).indexOf(this) == 0;