Skip to content

Commit

Permalink
Fix ethlo#31: Allow unwrapping of repeated/array elements
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyanep committed Jun 11, 2020
1 parent 6ce2527 commit 397b549
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 35 deletions.
26 changes: 19 additions & 7 deletions src/main/java/com/ethlo/jsons2xsd/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -43,12 +43,13 @@ public class Config
private final boolean ignoreUnknownFormats;
private final String rootElement;
private final Function<String,String> itemNameMapper;
private final boolean unwrapArrays;

public boolean isAttributesQualified()
{
return attributesQualified;
}

public boolean isIncludeOnlyUsedTypes()
{
return includeOnlyUsedTypes;
Expand Down Expand Up @@ -97,6 +98,10 @@ public Function<String,String> getItemNameMapper() {
return itemNameMapper;
}

public boolean isUnwrapArrays() {
return unwrapArrays;
}

public String getType(String type, String format)
{
final String key = (type + (format != null ? ("|" + format) : "")).toLowerCase();
Expand All @@ -116,6 +121,7 @@ public static class Builder
private boolean ignoreUnknownFormats;
private String rootElement;
private Function<String,String> itemNameMapper = Function.identity();
private boolean unwrapArrays = false;

public Builder targetNamespace(String targetNamespace)
{
Expand All @@ -134,7 +140,7 @@ public Builder createRootElement(boolean b)
this.createRootElement = b;
return this;
}

public Builder includeOnlyUsedTypes(boolean b)
{
this.includeOnlyUsedTypes = b;
Expand All @@ -145,7 +151,7 @@ public Config build()
{
Assert.notNull(name, "name must be set");
Assert.notNull(targetNamespace, "targetNamespace must be set");

return new Config(this);
}

Expand All @@ -160,7 +166,7 @@ public Builder attributesQualified(boolean b)
this.attributesQualified = b;
return this;
}

public Builder validateXsdSchema(boolean b)
{
this.validateXsdSchema = b;
Expand Down Expand Up @@ -199,8 +205,13 @@ public Builder mapArrayItemNames(final Function<String, String> mapper) {
this.itemNameMapper = mapper;
return this;
}

public Builder unwrapArrays(final boolean unwrapArrays) {
this.unwrapArrays = unwrapArrays;
return this;
}
}

private Config(Builder builder)
{
this.targetNamespace = builder.targetNamespace;
Expand All @@ -214,5 +225,6 @@ private Config(Builder builder)
this.ignoreUnknownFormats = builder.ignoreUnknownFormats;
this.rootElement = builder.rootElement;
this.itemNameMapper = builder.itemNameMapper;
this.unwrapArrays = builder.unwrapArrays;
}
}
47 changes: 21 additions & 26 deletions src/main/java/com/ethlo/jsons2xsd/Jsons2Xsd.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand All @@ -26,26 +26,17 @@
* #L%
*/

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.IOException;
import java.io.Reader;
import java.util.*;
import java.util.Map.Entry;

public class Jsons2Xsd
{
Expand Down Expand Up @@ -477,16 +468,20 @@ private static void handleArray(Set<String> neededElements, Element nodeElem, Js
{
final JsonNode arrItems = jsonNode.path("items");
final String arrayXsdType = determineXsdType(cfg, arrItems.path("type").textValue(), arrItems);
final Element complexType = element(nodeElem, XSD_COMPLEXTYPE);
final Element sequence = element(complexType, XSD_SEQUENCE);
final Element arrElem = element(sequence, XSD_ELEMENT);
if (cfg.isUnwrapArrays()) {
handleArrayElements(neededElements, jsonNode, arrItems, arrayXsdType, nodeElem, cfg);
} else {
final Element complexType = element(nodeElem, XSD_COMPLEXTYPE);
final Element sequence = element(complexType, XSD_SEQUENCE);
final Element arrElem = element(sequence, XSD_ELEMENT);

handleArrayElements(neededElements, jsonNode, arrItems, arrayXsdType, arrElem, cfg);
handleArrayElements(neededElements, jsonNode, arrItems, arrayXsdType, arrElem, cfg);

final String o = arrElem.getAttribute("name");
if (o == null || o.trim().length() == 0)
{
arrElem.setAttribute(FIELD_NAME, "item");
final String o = arrElem.getAttribute("name");
if (o == null || o.trim().length() == 0)
{
arrElem.setAttribute(FIELD_NAME, "item");
}
}
}

Expand Down
16 changes: 14 additions & 2 deletions src/test/java/com/ethlo/jsons2xsd/ConversionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -232,6 +232,18 @@ public void testAnnotations() throws IOException {
}
}

@Test
public void testBasicRepeated() throws IOException {
try (final Reader r = reader("/schema/basicrepeated.json")) {
final Config cfg = new Config.Builder()
.targetNamespace("http://ethlo.com/schema/basicrepeated.xsd")
.name("basic")
.unwrapArrays(true)
.build();
assertSchema(r, cfg, "schema/basicrepeated.xsd");
}
}

private Reader reader(String path) {
return new InputStreamReader(getClass().getResourceAsStream(path));
}
Expand Down
36 changes: 36 additions & 0 deletions src/test/resources/schema/basicrepeated.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"definitions": {
"Bar": {
"title": "Bar",
"type": "object",
"properties": {
"baz": {
"type": "number"
},
"quokka": {
"type": "number"
}
},
"required": [
"baz",
"quokka"
]
}
},

"type": "object",
"properties": {
"Foo": {
"title": "Foo",
"type": "object",
"properties": {
"uris": {
"type": "array",
"items": {
"$ref": "#/definitions/Bar"
}
}
}
}
}
}
23 changes: 23 additions & 0 deletions src/test/resources/schema/basicrepeated.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema elementFormDefault="qualified"
targetNamespace="http://ethlo.com/schema/basicrepeated.xsd"
xmlns="http://www.w3.org/2001/XMLSchema" xmlns:x="http://ethlo.com/schema/basicrepeated.xsd">
<complexType name="basic">
<sequence>
<element minOccurs="0" name="Foo">
<complexType>
<sequence>
<element maxOccurs="unbounded" minOccurs="0"
name="uris" type="x:Bar"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
<complexType name="Bar">
<sequence>
<element name="baz" type="decimal"/>
<element name="quokka" type="decimal"/>
</sequence>
</complexType>
</schema>

0 comments on commit 397b549

Please sign in to comment.