Skip to content
NodeTest.java 6.11 KiB
Newer Older
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;
import java.util.List;
import java.util.function.Function;
import javax.xml.bind.JAXB;
import static org.junit.jupiter.api.Assertions.assertEquals;
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 {

    private static final ObjectMapper MAPPER = new ObjectMapper();

    private static final String URI_PREFIX = "vos://example.com!vospace";

    @Test
    public void testXmlSerialization() throws Exception {

        ContainerNode root = getRoot();

        String xml;
        try ( StringWriter sw = new StringWriter()) {
            JAXB.marshal(root, sw);
            xml = sw.toString();
            System.out.println(xml);
        }

        Document doc = loadDocument(xml);
        assertEquals("vos:node", doc.getDocumentElement().getNodeName());
        assertEquals("vos:ContainerNode", doc.getDocumentElement().getAttribute("xsi:type"));
        assertTrue(xml.contains("<vos:nodes>"));
        assertTrue(xml.contains("xsi:type=\"vos:DataNode\""));
        assertTrue(xml.contains("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""));

        ContainerNode deserialized;
        try ( StringReader sr = new StringReader(xml)) {
            deserialized = JAXB.unmarshal(sr, ContainerNode.class);
        }

        verifyNodesAreEquals(root, deserialized);
        verifyConstraints(deserialized);
    }

    @Test
    public void testJsonSerialization() throws Exception {

        ContainerNode root = getRoot();

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

        verifyNodesAreEquals(root, deserialized);
        verifyConstraints(deserialized);
    }

    private ContainerNode getRoot() {
        ContainerNode root = getContainerNode("/", true, "g1", "g2");

        List<Node> nodes = new ArrayList<>();
        nodes.add(getDataNode("/node1", false, "g1", "g2", 808009979));
        nodes.add(getDataNode("/node2", true, "g1", "g2", 305919869));
        nodes.add(getContainerNode("/node3", true, "g1", "g2"));


        return root;
    }

    private ContainerNode getContainerNode(String path, boolean isPublic, String groupRead, String groupWrite) {
        ContainerNode node = new ContainerNode();
        fillNode(node, path, isPublic, groupRead, groupWrite, 0);
        return node;
    }

    private DataNode getDataNode(String path, boolean isPublic, String groupRead, String groupWrite, long size) {
        DataNode node = new DataNode();
        fillNode(node, path, isPublic, groupRead, groupWrite, size);
        return node;
    }

    private void fillNode(Node node, String path, boolean isPublic, String groupRead, String groupWrite, long size) {

        node.setUri(URI_PREFIX + path);

        List<Property> properties = new ArrayList<>();

        properties.add(createProperty("ivo://ivoa.net/vospace/core#ispublic", String.valueOf(isPublic)));
        properties.add(createProperty("ivo://ivoa.net/vospace/core#groupread", groupRead));
        properties.add(createProperty("ivo://ivoa.net/vospace/core#groupwrite", groupWrite));
        properties.add(createProperty("ivo://ivoa.net/vospace/core#length", String.valueOf(size)));

        PropertyList propertyList = new PropertyList();
        propertyList.getProperty().addAll(properties);

        node.setProperties(propertyList);
    }

    private Property createProperty(String uri, String value) {
        Property prop = new Property();
        prop.setUri(uri);
        prop.setValue(value);
        return prop;
    }

    private void verifyNodesAreEquals(ContainerNode serialized, ContainerNode deserialized) {
        verifyItem(serialized, deserialized, n -> n.getType());
        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"));
        verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#length"));
    }

    private <T> void verifyItem(ContainerNode serialized, ContainerNode deserialized, Function<ContainerNode, T> function) {
        assertEquals(function.apply(serialized), function.apply(deserialized));
    }

    private String getProperty(Node node, String uri) {
        for (Property property : node.getProperties().getProperty()) {
            if (uri.equals(property.getUri())) {
                return property.getValue();
            }
        }
        throw new IllegalArgumentException("Node doesn't contain property having uri " + uri);
    }

    private void verifyConstraints(ContainerNode deserialized) {
        DataNode node1 = (DataNode) getChildNodeByPath(deserialized, "/node1");
        ContainerNode node3 = (ContainerNode) getChildNodeByPath(deserialized, "/node3");

        assertEquals("vos:DataNode", node1.getType());
        assertEquals("vos:ContainerNode", node3.getType());
    }

    private Node getChildNodeByPath(ContainerNode parent, String path) {
        for (Node node : parent.getNodes()) {
            if ((URI_PREFIX + path).equals(node.getUri())) {
                return node;
            }
        }
        throw new IllegalArgumentException("Node not found for path " + path);
    }
}