Package org.fcrepo.server.validation

Source Code of org.fcrepo.server.validation.RelsValidatorTest

/* The contents of this file are subject to the license and copyright terms
* detailed in the license directory at the root of the source tree (also
* available online at http://fedora-commons.org/license/).
*/
package org.fcrepo.server.validation;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import java.net.URI;
import java.net.URISyntaxException;

import java.util.Collection;
import java.util.HashSet;

import org.jrdf.graph.ObjectNode;
import org.jrdf.graph.Triple;

import org.trippi.RDFFormat;
import org.trippi.TripleIterator;

import org.fcrepo.common.Constants;
import org.fcrepo.common.PID;
import org.fcrepo.common.rdf.SimpleLiteral;
import org.fcrepo.common.rdf.SimpleTriple;
import org.fcrepo.common.rdf.SimpleURIReference;
import org.fcrepo.server.errors.GeneralException;
import org.fcrepo.server.errors.ServerException;
import org.fcrepo.server.errors.ValidationException;
import org.fcrepo.server.validation.RelsValidator;

import junit.framework.TestCase;



/**
* Tests the RELS-EXT and RELS-INT datastream deserializer and validation.
*
* @author Edwin Shin
* @author Stephen Bayliss
*/
public class RelsValidatorTest
        extends TestCase {

    private Collection<Triple> triples;

    private static byte[] RELS_EXT;
    private static byte[] RELS_INT;


    private PID pid;

    static {
        // create valid RELS-EXT and RELS-INT contents
        StringBuilder sbRelsExt  = new StringBuilder();
        StringBuilder sbRelsInt = new StringBuilder();
        sbRelsExt
                .append("<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
                        + "         xmlns:rel=\"info:fedora/fedora-system:def/relations-external#\">"
                        + "  <rdf:Description rdf:about=\"info:fedora/demo:888\">"
                        + "     <rel:isMemberOf rdf:resource=\"info:fedora/demo:X\" />"
                        + "  </rdf:Description>" + "</rdf:RDF>");
        sbRelsInt
                .append("<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\""
                        + "         xmlns:relint=\"http://www.example.org/rels-int#\">"
                        + "  <rdf:Description rdf:about=\"info:fedora/demo:888/DS1\">"
                        + "     <relint:someRelation rdf:resource=\"info:fedora/demo:X\" />"
                        + "  </rdf:Description>"
                        + "  <rdf:Description rdf:about=\"info:fedora/demo:888/DS2\">"
                        + "     <relint:someProperty>value</relint:someProperty>"
                        + "  </rdf:Description>"

                        + "</rdf:RDF>");

        try {
            RELS_EXT = sbRelsExt.toString().getBytes("UTF-8");
            RELS_INT = sbRelsInt.toString().getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
        }
    }

    @Override
    public void setUp() {
        triples = new HashSet<Triple>();
    }

    public void testValidateValidRelsExt() throws Exception {
        pid = PID.getInstance("demo:888");
        InputStream in = new ByteArrayInputStream(RELS_EXT);
        RelsValidator validator = new RelsValidator();
        validator.validate(pid, "RELS-EXT", in);
    }
    public void testValidateValidRelsInt() throws Exception {
        pid = PID.getInstance("demo:888");
        InputStream in = new ByteArrayInputStream(RELS_INT);
        RelsValidator validator = new RelsValidator();
        validator.validate(pid, "RELS-INT", in);
    }
    public void testValidateInvalidRelsExt() throws Exception {
        pid = PID.getInstance("demo:888");
        // use RELS-INT sample as a RELS-EXT datastream
        InputStream in = new ByteArrayInputStream(RELS_INT);
        RelsValidator validator = new RelsValidator();
        try {
            validator.validate(pid, "RELS-EXT", in);
            fail("Multiple Description elements not allowed for RELS-EXT");
        } catch (ValidationException e) {}
    }

    public void testEmpty() throws Exception {
        testEmpty("RELS-EXT");
        testEmpty("RELS-INT");
    }

    private void testEmpty(String dsId) throws Exception {
        pid = PID.getInstance("demo:demo");
        InputStream in;
        String[] empties = {"", " ", "</>"};

        for (String s : empties) {
            in = new ByteArrayInputStream(s.getBytes());

            try {
                new RelsValidator().validate(pid, dsId, in);
                fail("Empty " + dsId + " datastream incorrectly passed"
                     + " validation: \"" + s + "\"");
            } catch (ValidationException e) {}
        }
    }

    public void testBadSubjectURI() throws Exception {
        pid = PID.getInstance("demo:foo");

        String s, p, o;

        s = PID.getInstance("demo:bar").toURI();
        p = "urn:p";
        o = "urn:o";
        triples.add(createTriple(s, p, o, false, null));

        try {
            validateAndClear("RELS-EXT");
            fail("RELS-EXT Assertion's subject URI different from digital object URI not allowed");
        } catch (ValidationException e) {
        }

        s = PID.getInstance("demo:foo").toURI();
        triples.add(createTriple(s, p, o, false, null));

        try {
            validateAndClear("RELS-INT");
            fail("RELS-INT Assertion's subject URI is digital object URI not allowed");
        } catch (ValidationException e) {
        }

        s = PID.getInstance("demo:bar").toURI() + "/DS1";
        triples.add(createTriple(s, p, o, false, null));

        try {
            validateAndClear("RELS-INT");
            fail("RELS-INT Assertion's subject URI is datastream in different digital object not allowed");
        } catch (ValidationException e) {
        }

        s = PID.getInstance("demo:foo").toURI() + "/";
        triples.add(createTriple(s, p, o, false, null));

        try {
            validateAndClear("RELS-INT");
            fail("RELS-INT Assertion's subject URI zero length datastream ID not allowed");
        } catch (ValidationException e) {
        }

        s = PID.getInstance("demo:foo") + "/DS1:Test";
        triples.add(createTriple(s, p, o, false, null));

        try {
            validateAndClear("RELS-INT");
            fail("RELS-INT Assertion's subject URI invalid datastream ID not allowed (colon)");
        } catch (ValidationException e) {
        }


    }
    public void testBadAssertions() throws Exception {
        testBadAssertions("RELS-EXT");
        testBadAssertions("RELS-INT");
    }

    // assertions that are invalid for both RELS-EXT and RELS-INT
    private void testBadAssertions(String dsId) throws Exception {
        pid = PID.getInstance("demo:foo");

        String p, o;

        // Model namespace
        p = Constants.MODEL.CONTROL_GROUP.uri;
        o = "demo:baz";
        triples.add(createTriple(pid, p, o, false, null));

        try {
            validateAndClear(dsId);
            fail(dsId + "Fedora Model namespace assertions not allowed");
        } catch (ValidationException e) {
        }
        // View namespace
        p = Constants.VIEW.DISSEMINATES.uri;
        triples.add(createTriple(pid, p, o, false, null));

        try {
            validateAndClear(dsId);
            fail(dsId + "Fedora View namespace assertions not allowed");
        } catch (ValidationException e) {
        }


    }

    // RELS-EXT specific assertions (RELS-INT allows these)
    public void testAssertionsRelsExt() throws Exception{
        pid = PID.getInstance("demo:foo");

        String p, o;

        p = "http://purl.org/dc/elements/1.1/title";
        o = "The God of Small Things";
        triples.add(createTriple(pid, p, o, true, null));

        try {
            validateAndClear("RELS-EXT");
            fail("RELS-EXT Dublin Core assertions not allowed");
        } catch (ValidationException e) {
        }

        // specific model relationships are allowed
        o = "urn:xyz";
        p = Constants.MODEL.HAS_SERVICE.uri;
        triples.add(createTriple(pid, p, o, false, null));
        try {
            validateAndClear("RELS-EXT");
        } catch (ValidationException e) {
            fail("RELS-EXT Model relationship " + p + " should be allowed");
        }

        p = Constants.MODEL.IS_CONTRACTOR_OF.uri;
        triples.add(createTriple(pid, p, o, false, null));
        try {
            validateAndClear("RELS-EXT");
        } catch (ValidationException e) {
            fail("RELS-EXT Model relationship " + p + " should be allowed");
        }

        p = Constants.MODEL.HAS_MODEL.uri;
        triples.add(createTriple(pid, p, o, false, null));
        try {
            validateAndClear("RELS-EXT");
        } catch (ValidationException e) {
            fail("RELS-EXT Model relationship " + p + " should be allowed");
        }

        p = Constants.MODEL.IS_DEPLOYMENT_OF.uri;
        triples.add(createTriple(pid, p, o, false, null));
        try {
            validateAndClear("RELS-EXT");
        } catch (ValidationException e) {
            fail("RELS-EXT Model relationship " + p + " should be allowed");
        }


    }

    // probably overkill to run these tests for RELS-EXT and RELS-INT, but just in case ...

    public void testResourceURI() throws Exception {
        testResourceURI("RELS-EXT");
        testResourceURI("RELS-INT");
    }
    private void testResourceURI(String dsId) throws Exception {
        pid = PID.getInstance("demo:foo");
        String s, p, o;

        if (dsId.equals("RELS-INT")) {
            s = pid.toURI() + "/DS1";
        } else {
            s = pid.toURI();
        }

        p = "urn:p";
        o = "urn:o";
        triples.add(createTriple(s, p, o, false, null));
        p = "urn:p";
        o = "urn:o";
        triples.add(createTriple(s, p, o, true, null));
        p = "urn:p";
        o = "1970-01-01T00:00:00Z";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        p = "urn:p";
        o = s;
        triples.add(createTriple(s, p, o, false, null));

        try {
            validateAndClear(dsId);
        } catch (ValidationException e) {
            fail(dsId + " Self-referential assertions should be allowed.");
        }
    }

    public void testDatatypes() throws Exception {
        testDatatypes("RELS-EXT");
        testDatatypes("RELS-INT");
    }
    private void testDatatypes(String dsId) throws Exception {
        pid = PID.getInstance("demo:foo");
        String s, p, o;

        if (dsId.equals("RELS-INT")) {
            s = pid.toURI() + "/DS1";
        } else {
            s = pid.toURI();
        }


        p = "urn:p";
        o = "abc:123";
        triples.add(createTriple(s, p, o, false, null));
        validateAndClear(dsId);

        o = "1";
        triples.add(createTriple(s, p, o, true, Constants.RDF_XSD.INT.uri));
        validateAndClear(dsId);

        o = "abc";
        triples.add(createTriple(s, p, o, true, Constants.RDF_XSD.INT.uri));
        try {
            validateAndClear(dsId);
            fail("Invalid integer value: " + o);
        } catch (ValidationException e) {
        }

        o = "-0001-01-01T00:00:00";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00.1";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00.01";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00.001";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "-0001-01-01T00:00:00Z";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00Z";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00.1Z";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00.01Z";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "1970-01-01T00:00:00.001Z";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        validateAndClear(dsId);

        o = "abc";
        triples.add(createTriple(s,
                                 p,
                                 o,
                                 true,
                                 Constants.RDF_XSD.DATE_TIME.uri));
        try {
            validateAndClear(dsId);
            fail("Invalid dateTime value: " + o);
        } catch (ValidationException e) {
        }
    }

    private void validateAndClear(String dsId) throws Exception {
        try {
            TripleIterator iter = new MockTripleIterator(triples);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            iter.toStream(out, RDFFormat.RDF_XML, false);
            new RelsValidator().validate(pid, dsId, new ByteArrayInputStream(out.toByteArray()));
        } finally {
            triples.clear();
        }
    }
    private static Triple createTriple(PID pid,
                                       String predicate,
                                       String object,
                                       boolean isLiteral,
                                       String datatype)
            throws ServerException {
        return createTriple(pid.toURI(), predicate, object, isLiteral, datatype);
    }

    private static Triple createTriple(String subject,
                                       String predicate,
                                       String object,
                                       boolean isLiteral,
                                       String datatype)
            throws ServerException {
        ObjectNode o = null;
        try {
            if (isLiteral) {
                if (datatype == null || datatype.length() == 0) {
                    o = new SimpleLiteral(object);
                } else {
                    o = new SimpleLiteral(object, new URI(datatype));
                }
            } else {
                o = new SimpleURIReference(new URI(object));
            }
            return new SimpleTriple(new SimpleURIReference(new URI(subject)),
                                    new SimpleURIReference(new URI(predicate)),
                                    o);
        } catch (URISyntaxException e) {
            throw new GeneralException(e.getMessage(), e);
        }
    }

}
TOP

Related Classes of org.fcrepo.server.validation.RelsValidatorTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.