diff --git a/pom.xml b/pom.xml index b3830a6..cd3e9fe 100644 --- a/pom.xml +++ b/pom.xml @@ -176,6 +176,12 @@ + + com.formulasearchengine.mathmltools + mathml-core + 2.0.1 + test + junit junit diff --git a/src/main/java/org/dswarm/xsd2jsonschema/JsonSchemaParser.java b/src/main/java/org/dswarm/xsd2jsonschema/JsonSchemaParser.java index 3c3c5fc..c482072 100644 --- a/src/main/java/org/dswarm/xsd2jsonschema/JsonSchemaParser.java +++ b/src/main/java/org/dswarm/xsd2jsonschema/JsonSchemaParser.java @@ -76,6 +76,7 @@ public class JsonSchemaParser { //private static final XSImplementation impl = (XSImplementation) new XSImplementationImpl(); private static final XSLoader LOADER; + private static final int MAX_RECURSION_DEPTH = 7; static { System.setProperty(DOMImplementationRegistry.PROPERTY, "com.sun.org.apache.xerces.internal.dom.DOMXSImplementationSourceImpl"); @@ -94,22 +95,22 @@ public class JsonSchemaParser { private XSModel model; - private Collection iterateParticle(final XSParticle particle) { + private Collection iterateParticle(final XSParticle particle, int depth) { final XSTerm term = particle.getTerm(); if (term instanceof XSModelGroup) { final XSModelGroup modelGroup = (XSModelGroup) term; - return iterateModelGroup(modelGroup); + return iterateModelGroup(modelGroup,depth); } else if (term instanceof XSModelGroupDefinition) { final XSModelGroupDefinition xsModelGroupDefinition = (XSModelGroupDefinition) term; - return iterateModelGroup(xsModelGroupDefinition.getModelGroup()); + return iterateModelGroup(xsModelGroupDefinition.getModelGroup(), depth); } final Collection jsElements = new ArrayList<>(1); - final Optional optionalJSElement = iterateSingleParticle(particle); + final Optional optionalJSElement = iterateSingleParticle(particle, depth); if (optionalJSElement.isPresent()) { @@ -119,14 +120,14 @@ else if (term instanceof XSModelGroupDefinition) { return jsElements; } - private Optional iterateSingleParticle(final XSParticle particle) { + private Optional iterateSingleParticle(final XSParticle particle, int depth) { final XSTerm term = particle.getTerm(); if (term instanceof XSElementDeclaration) { final XSElementDeclaration xsElementDecl = (XSElementDeclaration) term; - final Optional optionalElement = iterateElement(xsElementDecl); + final Optional optionalElement = iterateElement(xsElementDecl, depth); return optionalElement.map(el -> isRepeated(particle) ? new JSArray(el) : el); } @@ -136,7 +137,7 @@ else if (term instanceof XSModelGroupDefinition) { final XSModelGroupDefinition xsModelGroupDefinition = (XSModelGroupDefinition) term; final String name = getDeclarationName(xsModelGroupDefinition); - final List elements = iterateModelGroup(xsModelGroupDefinition.getModelGroup()); + final List elements = iterateModelGroup(xsModelGroupDefinition.getModelGroup(), depth); return Optional.of(new JSObject(name, elements)); } @@ -162,7 +163,7 @@ else if (term instanceof XSWildcard) { return Optional.of(new JSNull(NULL)); } - private List iterateModelGroup(final XSModelGroup modelGroup) { + private List iterateModelGroup(final XSModelGroup modelGroup, int depth) { final List list = new ArrayList<>(); @@ -174,17 +175,17 @@ private List iterateModelGroup(final XSModelGroup modelGroup) { final XSTerm term = xsParticle.getTerm(); if (term instanceof XSModelGroup) { - list.addAll(iterateParticle(xsParticle)); + list.addAll(iterateParticle(xsParticle,depth+1)); } else if (term instanceof XSModelGroupDefinition) { final XSModelGroupDefinition xsModelGroupDefinition = (XSModelGroupDefinition) term; - list.addAll(iterateModelGroup(xsModelGroupDefinition.getModelGroup())); + list.addAll(iterateModelGroup(xsModelGroupDefinition.getModelGroup(),depth + 1 )); } else { - final Optional optionalJSElement = iterateSingleParticle(xsParticle); + final Optional optionalJSElement = iterateSingleParticle(xsParticle, depth+1); optionalJSElement.ifPresent(list::add); } } @@ -192,13 +193,17 @@ else if (term instanceof XSModelGroupDefinition) { return list; } - private Optional iterateElement(final XSElementDeclaration elementDecl) { - + private Optional iterateElement(final XSElementDeclaration elementDecl, int depth) { + if(depth>MAX_RECURSION_DEPTH) { + LOG.error("Structure deeper than " , MAX_RECURSION_DEPTH ); + return Optional.empty(); + } try { final String elementName = getDeclarationName(elementDecl); - //System.out.println(elementName); + // System.out.println(elementName); + // System.out.println(depth); final XSTypeDefinition xsElementDeclType = elementDecl.getTypeDefinition(); @@ -242,7 +247,7 @@ private Optional iterateElement(final XSElementDeclaration elementDec }).orElseGet(() -> { final JSObject jsElements = new JSObject(elementName, isMixed); - final List elements = iterateComplexType(xsComplexType); + final List elements = iterateComplexType(xsComplexType, depth); if (elements.size() == 1 && elements.get(0) instanceof JSOther) { @@ -265,14 +270,14 @@ private Optional iterateElement(final XSElementDeclaration elementDec return Optional.empty(); } - private List iterateComplexType(final XSComplexTypeDefinition complexType) { + private List iterateComplexType(final XSComplexTypeDefinition complexType, int depth) { final List result = new ArrayList<>(); final XSParticle xsParticle = complexType.getParticle(); if (xsParticle != null) { - result.addAll(iterateParticle(xsParticle)); + result.addAll(iterateParticle(xsParticle,depth)); } else { final XSSimpleTypeDefinition xsSimpleType = complexType.getSimpleType(); if (xsSimpleType != null) { @@ -307,13 +312,17 @@ private static JSElement iterateSimpleType(final XSObject simpleType) { return new JSString(simpleTypeName); } + public void parse(final LSInput input) { + model = LOADER.load(input); + } + public void parse(final InputStream is) throws SAXException { Preconditions.checkNotNull(LOADER, "The parser could not be initialised"); final LSInput input = new DOMInputImpl(); input.setByteStream(is); + parse(input); - model = LOADER.load(input); } public void parse(final Reader reader) throws SAXException { @@ -355,7 +364,6 @@ public JSRoot apply(final String rootName) throws SAXException { //final XSSchema xsSchema = xsSchemaIterator.next(); final XSNamedMap elements = model.getComponents(XSConstants.ELEMENT_DECLARATION); - for (int i = 0; i < elements.getLength(); i++) { final XSObject object = elements.item(i); @@ -370,8 +378,7 @@ public JSRoot apply(final String rootName) throws SAXException { continue; } - - iterateElement(elementDecl).ifPresent(root::add); + iterateElement(elementDecl, 1).ifPresent(root::add); } } // diff --git a/src/test/java/org/dswarm/xsd2jsonschema/test/JsonSchemaParserTest.java b/src/test/java/org/dswarm/xsd2jsonschema/test/JsonSchemaParserTest.java index fd2db62..5d9702b 100644 --- a/src/test/java/org/dswarm/xsd2jsonschema/test/JsonSchemaParserTest.java +++ b/src/test/java/org/dswarm/xsd2jsonschema/test/JsonSchemaParserTest.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.formulasearchengine.mathmltools.mml.MathDoc; import com.google.common.base.Charsets; import com.google.common.io.ByteSource; import com.google.common.io.Resources; @@ -66,6 +67,20 @@ public void testJsonSchemaParserWMarc21() throws Exception { testJsonSchemaParserInternal("MARC21slim.xsd", "marc21.jsonschema", "bla"); } + @Test + public void testJsonSchemaParserMathML() throws Exception { + + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + + final JsonSchemaParser schemaParser = new JsonSchemaParser(); + schemaParser.parse(MathDoc.getMathMLSchema()); + final JSRoot root = schemaParser.apply("math" ); + + final ObjectNode json = root.toJson(objectMapper); + Assert.assertEquals(4,json.size()); + } + private void testJsonSchemaParserInternal(final String xsdSchemaFileName, final String resultFileName, final String rootNodeIdentifier) throws Exception { final ObjectMapper objectMapper = new ObjectMapper();