Skip to content
This repository was archived by the owner on May 24, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@
</distributionManagement>

<dependencies>
<dependency>
<groupId>com.formulasearchengine.mathmltools</groupId>
<artifactId>mathml-core</artifactId>
<version>2.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
49 changes: 28 additions & 21 deletions src/main/java/org/dswarm/xsd2jsonschema/JsonSchemaParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to provide this attribute/information via a parameter? - since, "7" seems to be rather arbitrary ;)


static {
System.setProperty(DOMImplementationRegistry.PROPERTY, "com.sun.org.apache.xerces.internal.dom.DOMXSImplementationSourceImpl");
Expand All @@ -94,22 +95,22 @@ public class JsonSchemaParser {

private XSModel model;

private Collection<JSElement> iterateParticle(final XSParticle particle) {
private Collection<JSElement> 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<JSElement> jsElements = new ArrayList<>(1);
final Optional<JSElement> optionalJSElement = iterateSingleParticle(particle);
final Optional<JSElement> optionalJSElement = iterateSingleParticle(particle, depth);

if (optionalJSElement.isPresent()) {

Expand All @@ -119,14 +120,14 @@ else if (term instanceof XSModelGroupDefinition) {
return jsElements;
}

private Optional<JSElement> iterateSingleParticle(final XSParticle particle) {
private Optional<JSElement> iterateSingleParticle(final XSParticle particle, int depth) {

final XSTerm term = particle.getTerm();
if (term instanceof XSElementDeclaration) {

final XSElementDeclaration xsElementDecl = (XSElementDeclaration) term;

final Optional<JSElement> optionalElement = iterateElement(xsElementDecl);
final Optional<JSElement> optionalElement = iterateElement(xsElementDecl, depth);

return optionalElement.map(el -> isRepeated(particle) ? new JSArray(el) : el);
}
Expand All @@ -136,7 +137,7 @@ else if (term instanceof XSModelGroupDefinition) {
final XSModelGroupDefinition xsModelGroupDefinition = (XSModelGroupDefinition) term;
final String name = getDeclarationName(xsModelGroupDefinition);

final List<JSElement> elements = iterateModelGroup(xsModelGroupDefinition.getModelGroup());
final List<JSElement> elements = iterateModelGroup(xsModelGroupDefinition.getModelGroup(), depth);
return Optional.of(new JSObject(name, elements));
}

Expand All @@ -162,7 +163,7 @@ else if (term instanceof XSWildcard) {
return Optional.of(new JSNull(NULL));
}

private List<JSElement> iterateModelGroup(final XSModelGroup modelGroup) {
private List<JSElement> iterateModelGroup(final XSModelGroup modelGroup, int depth) {

final List<JSElement> list = new ArrayList<>();

Expand All @@ -174,31 +175,35 @@ private List<JSElement> 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<JSElement> optionalJSElement = iterateSingleParticle(xsParticle);
final Optional<JSElement> optionalJSElement = iterateSingleParticle(xsParticle, depth+1);
optionalJSElement.ifPresent(list::add);
}
}

return list;
}

private Optional<JSElement> iterateElement(final XSElementDeclaration elementDecl) {

private Optional<JSElement> iterateElement(final XSElementDeclaration elementDecl, int depth) {
if(depth>MAX_RECURSION_DEPTH) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to make this check optional? or to set the default value for MAX_RECURSION_DEPTH to a higher value?

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();

Expand Down Expand Up @@ -242,7 +247,7 @@ private Optional<JSElement> iterateElement(final XSElementDeclaration elementDec
}).orElseGet(() -> {
final JSObject jsElements = new JSObject(elementName, isMixed);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked into that deeper some time (until I figured out that I will be better off with parsing the rng file rather than the xsd file). In my second attempt I did drop the depth counter and installed bookkeeping for the jsobjects, here. The drawback of this approach is that it introduces state. Do you think that's a better way of fixing that?


final List<JSElement> elements = iterateComplexType(xsComplexType);
final List<JSElement> elements = iterateComplexType(xsComplexType, depth);

if (elements.size() == 1 && elements.get(0) instanceof JSOther) {

Expand All @@ -265,14 +270,14 @@ private Optional<JSElement> iterateElement(final XSElementDeclaration elementDec
return Optional.empty();
}

private List<JSElement> iterateComplexType(final XSComplexTypeDefinition complexType) {
private List<JSElement> iterateComplexType(final XSComplexTypeDefinition complexType, int depth) {

final List<JSElement> 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) {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand All @@ -370,8 +378,7 @@ public JSRoot apply(final String rootName) throws SAXException {

continue;
}

iterateElement(elementDecl).ifPresent(root::add);
iterateElement(elementDecl, 1).ifPresent(root::add);
}
}
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down