From fc2d758321e64f8c8c866ca55edfe4c135cdceaa Mon Sep 17 00:00:00 2001 From: Sonia Zorba <sonia.zorba@inaf.it> Date: Mon, 7 Dec 2020 15:39:19 +0100 Subject: [PATCH] Removed NodeTypeSetter. Added json-path-assert for testing JSON structure --- pom.xml | 12 + .../vospace/datamodel/NodeTypeSetter.java | 30 -- .../ivoa/xml/vospace/v2/ContainerNode.java | 125 ++------ .../net/ivoa/xml/vospace/v2/DataNode.java | 4 + .../net/ivoa/xml/vospace/v2/LinkNode.java | 3 - .../java/net/ivoa/xml/vospace/v2/Node.java | 13 +- .../ivoa/xml/vospace/v2/ObjectFactory.java | 284 ------------------ .../xml/vospace/v2/StructuredDataNode.java | 3 - .../xml/vospace/v2/UnstructuredDataNode.java | 3 - .../net/ivoa/xml/vospace/v2/NodeTest.java | 16 +- 10 files changed, 59 insertions(+), 434 deletions(-) delete mode 100644 src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeSetter.java delete mode 100644 src/main/java/net/ivoa/xml/vospace/v2/ObjectFactory.java diff --git a/pom.xml b/pom.xml index 17b96ac..379d41e 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,18 @@ <version>5.6.0</version> <scope>test</scope> </dependency> + <dependency> + <groupId>com.jayway.jsonpath</groupId> + <artifactId>json-path</artifactId> + <version>2.4.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.jayway.jsonpath</groupId> + <artifactId>json-path-assert</artifactId> + <version>2.4.0</version> + <scope>test</scope> + </dependency> </dependencies> <build> <finalName>${finalName}</finalName> diff --git a/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeSetter.java b/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeSetter.java deleted file mode 100644 index a428773..0000000 --- a/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeSetter.java +++ /dev/null @@ -1,30 +0,0 @@ -package it.inaf.oats.vospace.datamodel; - -import com.fasterxml.jackson.databind.util.StdConverter; -import net.ivoa.xml.vospace.v2.Node; - -/** - * Fills the type field at the end of the JSON deserialization. - * Node implementations must be annotated with - * @JsonDeserialize(converter = NodeTypeAdder.<NodeType>.class) - */ -public class NodeTypeSetter<T extends Node> extends StdConverter<T, T> { - - @Override - public T convert(T node) { - node.setType("vos:" + node.getClass().getSimpleName()); - return node; - } - - public static class UnstructuredDataNode extends NodeTypeSetter<net.ivoa.xml.vospace.v2.UnstructuredDataNode> { - } - - public static class StructuredDataNode extends NodeTypeSetter<net.ivoa.xml.vospace.v2.StructuredDataNode> { - } - - public static class ContainerNode extends NodeTypeSetter<net.ivoa.xml.vospace.v2.ContainerNode> { - } - - public static class LinkNode extends NodeTypeSetter<net.ivoa.xml.vospace.v2.LinkNode> { - } -} diff --git a/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java b/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java index 88a6e56..03a7880 100644 --- a/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java +++ b/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java @@ -4,30 +4,29 @@ // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2020.10.24 at 09:39:16 AM CEST // - - package net.ivoa.xml.vospace.v2; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import it.inaf.oats.vospace.datamodel.NodeTypeSetter; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; - /** - * - * A container node containing any type of node. - * - * - * <p>Java class for ContainerNode complex type. - * - * <p>The following schema fragment specifies the expected content contained within this class. - * + * + * A container node containing any type of node. + * + * + * <p> + * Java class for ContainerNode complex type. + * + * <p> + * The following schema fragment specifies the expected content contained within + * this class. + * * <pre> * <complexType name="ContainerNode"> * <complexContent> @@ -49,8 +48,8 @@ import javax.xml.bind.annotation.XmlType; * </complexContent> * </complexType> * </pre> - * - * + * + * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ContainerNode", propOrder = { @@ -58,96 +57,26 @@ import javax.xml.bind.annotation.XmlType; }) // <edit> @XmlRootElement(name = "node") -@JsonDeserialize(converter = NodeTypeSetter.ContainerNode.class) // </edit> public class ContainerNode - extends DataNode -{ + extends DataNode { - @XmlElement(required = true) - protected ContainerNode.Nodes nodes; + // <edit> + // Auto-generated class defined an inner ContainerNode.Nodes wrapper class. + // This should simplify usage and JSON compatibility. + @XmlElement(name = "node") + @XmlElementWrapper(name = "nodes", required = true) + protected List<Node> nodes; - /** - * Gets the value of the nodes property. - * - * @return - * possible object is - * {@link ContainerNode.Nodes } - * - */ - public ContainerNode.Nodes getNodes() { + public List<Node> getNodes() { + if (nodes == null) { + nodes = new ArrayList<>(); + } return nodes; } - /** - * Sets the value of the nodes property. - * - * @param value - * allowed object is - * {@link ContainerNode.Nodes } - * - */ - public void setNodes(ContainerNode.Nodes value) { + public void setNodes(List<Node> value) { this.nodes = value; } - - - /** - * <p>Java class for anonymous complex type. - * - * <p>The following schema fragment specifies the expected content contained within this class. - * - * <pre> - * <complexType> - * <complexContent> - * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> - * <sequence> - * <element name="node" type="{http://www.ivoa.net/xml/VOSpace/v2.0}Node" maxOccurs="unbounded" minOccurs="0"/> - * </sequence> - * </restriction> - * </complexContent> - * </complexType> - * </pre> - * - * - */ - @XmlAccessorType(XmlAccessType.FIELD) - @XmlType(name = "", propOrder = { - "node" - }) - public static class Nodes { - - protected List<Node> node; - - /** - * Gets the value of the node property. - * - * <p> - * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a <CODE>set</CODE> method for the node property. - * - * <p> - * For example, to add a new item, do as follows: - * <pre> - * getNode().add(newItem); - * </pre> - * - * - * <p> - * Objects of the following type(s) are allowed in the list - * {@link Node } - * - * - */ - public List<Node> getNode() { - if (node == null) { - node = new ArrayList<Node>(); - } - return this.node; - } - - } - + // </edit> } diff --git a/src/main/java/net/ivoa/xml/vospace/v2/DataNode.java b/src/main/java/net/ivoa/xml/vospace/v2/DataNode.java index 42bbef1..8e0a7fc 100644 --- a/src/main/java/net/ivoa/xml/vospace/v2/DataNode.java +++ b/src/main/java/net/ivoa/xml/vospace/v2/DataNode.java @@ -11,6 +11,7 @@ package net.ivoa.xml.vospace.v2; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.XmlType; @@ -52,6 +53,9 @@ import javax.xml.bind.annotation.XmlType; ContainerNode.class, UnstructuredDataNode.class }) +// <edit> +@XmlRootElement(name = "node") +// </edit> public class DataNode extends Node { diff --git a/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java b/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java index 0ca6e3e..0ce7b9b 100644 --- a/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java +++ b/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java @@ -8,8 +8,6 @@ package net.ivoa.xml.vospace.v2; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import it.inaf.oats.vospace.datamodel.NodeTypeSetter; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @@ -47,7 +45,6 @@ import javax.xml.bind.annotation.XmlType; }) // <edit> @XmlRootElement(name = "node") -@JsonDeserialize(converter = NodeTypeSetter.LinkNode.class) // </edit> public class LinkNode extends Node diff --git a/src/main/java/net/ivoa/xml/vospace/v2/Node.java b/src/main/java/net/ivoa/xml/vospace/v2/Node.java index 25da4e9..e682221 100644 --- a/src/main/java/net/ivoa/xml/vospace/v2/Node.java +++ b/src/main/java/net/ivoa/xml/vospace/v2/Node.java @@ -6,6 +6,7 @@ // package net.ivoa.xml.vospace.v2; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.databind.annotation.JsonTypeIdResolver; import it.inaf.oats.vospace.datamodel.NodeTypeJsonResolver; @@ -14,6 +15,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlType; /** @@ -57,17 +59,12 @@ public class Node { protected PropertyList properties; // <edit> - // Needed for handling inheritance in JSON (for XML is is automatically generated by JAXB). - @XmlAttribute(name = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance") - protected String type; - + // Needed for handling inheritance in JSON (in XML, type attribute is automatically generated by JAXB). + @JsonProperty + @XmlTransient public String getType() { return "vos:" + getClass().getSimpleName(); } - - public void setType(String type) { - this.type = type; - } // </edit> @XmlAttribute(name = "uri", required = true) diff --git a/src/main/java/net/ivoa/xml/vospace/v2/ObjectFactory.java b/src/main/java/net/ivoa/xml/vospace/v2/ObjectFactory.java deleted file mode 100644 index d1f39c9..0000000 --- a/src/main/java/net/ivoa/xml/vospace/v2/ObjectFactory.java +++ /dev/null @@ -1,284 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2020.10.24 at 09:39:16 AM CEST -// - - -package net.ivoa.xml.vospace.v2; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the net.ivoa.xml.vospace.v2 package. - * <p>An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Transfer_QNAME = new QName("http://www.ivoa.net/xml/VOSpace/v2.0", "transfer"); - private final static QName _SearchDetails_QNAME = new QName("http://www.ivoa.net/xml/VOSpace/v2.0", "searchDetails"); - private final static QName _Protocols_QNAME = new QName("http://www.ivoa.net/xml/VOSpace/v2.0", "protocols"); - private final static QName _Views_QNAME = new QName("http://www.ivoa.net/xml/VOSpace/v2.0", "views"); - private final static QName _Properties_QNAME = new QName("http://www.ivoa.net/xml/VOSpace/v2.0", "properties"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: net.ivoa.xml.vospace.v2 - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link ContainerNode } - * - */ - public ContainerNode createContainerNode() { - return new ContainerNode(); - } - - /** - * Create an instance of {@link NodeList } - * - */ - public NodeList createNodeList() { - return new NodeList(); - } - - /** - * Create an instance of {@link Transfer } - * - */ - public Transfer createTransfer() { - return new Transfer(); - } - - /** - * Create an instance of {@link ProtocolList } - * - */ - public ProtocolList createProtocolList() { - return new ProtocolList(); - } - - /** - * Create an instance of {@link ViewList } - * - */ - public ViewList createViewList() { - return new ViewList(); - } - - /** - * Create an instance of {@link PropertyList } - * - */ - public PropertyList createPropertyList() { - return new PropertyList(); - } - - /** - * Create an instance of {@link StructuredDataNode } - * - */ - public StructuredDataNode createStructuredDataNode() { - return new StructuredDataNode(); - } - - /** - * Create an instance of {@link Capability } - * - */ - public Capability createCapability() { - return new Capability(); - } - - /** - * Create an instance of {@link Node } - * - */ - public Node createNode() { - return new Node(); - } - - /** - * Create an instance of {@link PropertyReferenceList } - * - */ - public PropertyReferenceList createPropertyReferenceList() { - return new PropertyReferenceList(); - } - - /** - * Create an instance of {@link GetViewsResponse } - * - */ - public GetViewsResponse createGetViewsResponse() { - return new GetViewsResponse(); - } - - /** - * Create an instance of {@link GetPropertiesResponse } - * - */ - public GetPropertiesResponse createGetPropertiesResponse() { - return new GetPropertiesResponse(); - } - - /** - * Create an instance of {@link View } - * - */ - public View createView() { - return new View(); - } - - /** - * Create an instance of {@link PropertyReference } - * - */ - public PropertyReference createPropertyReference() { - return new PropertyReference(); - } - - /** - * Create an instance of {@link DataNode } - * - */ - public DataNode createDataNode() { - return new DataNode(); - } - - /** - * Create an instance of {@link Param } - * - */ - public Param createParam() { - return new Param(); - } - - /** - * Create an instance of {@link LinkNode } - * - */ - public LinkNode createLinkNode() { - return new LinkNode(); - } - - /** - * Create an instance of {@link CapabilityList } - * - */ - public CapabilityList createCapabilityList() { - return new CapabilityList(); - } - - /** - * Create an instance of {@link Protocol } - * - */ - public Protocol createProtocol() { - return new Protocol(); - } - - /** - * Create an instance of {@link UnstructuredDataNode } - * - */ - public UnstructuredDataNode createUnstructuredDataNode() { - return new UnstructuredDataNode(); - } - - /** - * Create an instance of {@link Property } - * - */ - public Property createProperty() { - return new Property(); - } - - /** - * Create an instance of {@link GetProtocolsResponse } - * - */ - public GetProtocolsResponse createGetProtocolsResponse() { - return new GetProtocolsResponse(); - } - - /** - * Create an instance of {@link ContainerNode.Nodes } - * - */ - public ContainerNode.Nodes createContainerNodeNodes() { - return new ContainerNode.Nodes(); - } - - /** - * Create an instance of {@link NodeList.Nodes } - * - */ - public NodeList.Nodes createNodeListNodes() { - return new NodeList.Nodes(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Transfer }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://www.ivoa.net/xml/VOSpace/v2.0", name = "transfer") - public JAXBElement<Transfer> createTransfer(Transfer value) { - return new JAXBElement<Transfer>(_Transfer_QNAME, Transfer.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link NodeList }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://www.ivoa.net/xml/VOSpace/v2.0", name = "searchDetails") - public JAXBElement<NodeList> createSearchDetails(NodeList value) { - return new JAXBElement<NodeList>(_SearchDetails_QNAME, NodeList.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link ProtocolList }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://www.ivoa.net/xml/VOSpace/v2.0", name = "protocols") - public JAXBElement<ProtocolList> createProtocols(ProtocolList value) { - return new JAXBElement<ProtocolList>(_Protocols_QNAME, ProtocolList.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link ViewList }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://www.ivoa.net/xml/VOSpace/v2.0", name = "views") - public JAXBElement<ViewList> createViews(ViewList value) { - return new JAXBElement<ViewList>(_Views_QNAME, ViewList.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link PropertyList }{@code >}} - * - */ - @XmlElementDecl(namespace = "http://www.ivoa.net/xml/VOSpace/v2.0", name = "properties") - public JAXBElement<PropertyList> createProperties(PropertyList value) { - return new JAXBElement<PropertyList>(_Properties_QNAME, PropertyList.class, null, value); - } - -} diff --git a/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java b/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java index 71922f5..6d8fcc6 100644 --- a/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java +++ b/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java @@ -8,8 +8,6 @@ package net.ivoa.xml.vospace.v2; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import it.inaf.oats.vospace.datamodel.NodeTypeSetter; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @@ -42,7 +40,6 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "StructuredDataNode") // <edit> @XmlRootElement(name = "node") -@JsonDeserialize(converter = NodeTypeSetter.StructuredDataNode.class) // </edit> public class StructuredDataNode extends DataNode diff --git a/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java b/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java index ae9256b..3fbf3d5 100644 --- a/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java +++ b/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java @@ -8,8 +8,6 @@ package net.ivoa.xml.vospace.v2; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import it.inaf.oats.vospace.datamodel.NodeTypeSetter; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; @@ -42,7 +40,6 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "UnstructuredDataNode") // <edit> @XmlRootElement(name = "node") // A single node can be the root of an XML document -@JsonDeserialize(converter = NodeTypeSetter.UnstructuredDataNode.class) // <edit> public class UnstructuredDataNode extends DataNode diff --git a/src/test/java/net/ivoa/xml/vospace/v2/NodeTest.java b/src/test/java/net/ivoa/xml/vospace/v2/NodeTest.java index 63ca6cc..09b23f5 100644 --- a/src/test/java/net/ivoa/xml/vospace/v2/NodeTest.java +++ b/src/test/java/net/ivoa/xml/vospace/v2/NodeTest.java @@ -1,6 +1,7 @@ package net.ivoa.xml.vospace.v2; import com.fasterxml.jackson.databind.ObjectMapper; +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; @@ -12,6 +13,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import org.w3c.dom.Document; import static net.ivoa.xml.VOSpaceXmlTestUtil.loadDocument; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; public class NodeTest { @@ -55,6 +58,11 @@ public class NodeTest { String json = MAPPER.writeValueAsString(root); System.out.println(json); + + assertThat(json, hasJsonPath("$.type", is("vos:ContainerNode"))); + + assertThat(json, hasJsonPath("$.nodes[0].type", is("vos:DataNode"))); + assertThat(json, hasJsonPath("$.nodes[0].uri", is("vos://example.com!vospace/node1"))); ContainerNode deserialized = MAPPER.readValue(json, ContainerNode.class); @@ -70,9 +78,7 @@ public class NodeTest { nodes.add(getDataNode("/node2", true, "g1", "g2", 305919869)); nodes.add(getContainerNode("/node3", true, "g1", "g2")); - ContainerNode.Nodes nodesEl = new ContainerNode.Nodes(); - nodesEl.getNode().addAll(nodes); - root.setNodes(nodesEl); + root.setNodes(nodes); return root; } @@ -115,7 +121,7 @@ public class NodeTest { private void verifyNodesAreEquals(ContainerNode serialized, ContainerNode deserialized) { verifyItem(serialized, deserialized, n -> n.getType()); - verifyItem(serialized, deserialized, n -> n.getNodes().getNode().size()); + verifyItem(serialized, deserialized, n -> n.getNodes().size()); verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#ispublic")); verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#groupread")); verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#groupwrite")); @@ -144,7 +150,7 @@ public class NodeTest { } private Node getChildNodeByPath(ContainerNode parent, String path) { - for (Node node : parent.getNodes().getNode()) { + for (Node node : parent.getNodes()) { if ((URI_PREFIX + path).equals(node.getUri())) { return node; } -- GitLab