001/*
002 * Licensed to DuraSpace under one or more contributor license agreements.
003 * See the NOTICE file distributed with this work for additional information
004 * regarding copyright ownership.
005 *
006 * DuraSpace licenses this file to you under the Apache License,
007 * Version 2.0 (the "License"); you may not use this file except in
008 * compliance with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.fcrepo.kernel.modeshape.rdf.impl;
019
020import static java.util.Arrays.asList;
021import static org.fcrepo.kernel.api.RdfLexicon.CONTAINER;
022import static org.fcrepo.kernel.api.RdfLexicon.CREATED_BY;
023import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE;
024import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_BINARY;
025import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_CONTAINER;
026import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_RESOURCE;
027import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_BY;
028import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_DATE;
029import static org.fcrepo.kernel.api.RdfLexicon.NON_RDF_SOURCE;
030import static org.fcrepo.kernel.api.RdfLexicon.RDF_SOURCE;
031
032import java.util.Collection;
033import org.apache.jena.rdf.model.Model;
034import org.apache.jena.rdf.model.Property;
035import org.apache.jena.rdf.model.RDFNode;
036import org.apache.jena.rdf.model.Resource;
037import org.apache.jena.vocabulary.RDF;
038import org.fcrepo.kernel.api.exception.ConstraintViolationException;
039
040/**
041 * Helper methods for determining if resources contain all required server managed triples.
042 *
043 * @author bbpennel
044 */
045public class RequiredPropertiesUtil {
046
047    private RequiredPropertiesUtil() {
048    }
049
050    private final static Collection<Property> REQUIRED_PROPERTIES = asList(
051            CREATED_BY, CREATED_DATE, LAST_MODIFIED_DATE, LAST_MODIFIED_BY);
052
053    private final static Collection<Resource> CONTAINER_TYPES = asList(
054            RDF_SOURCE, CONTAINER, FEDORA_CONTAINER, FEDORA_RESOURCE);
055
056    private final static Collection<Resource> BINARY_TYPES = asList(
057            NON_RDF_SOURCE, FEDORA_BINARY, FEDORA_RESOURCE);
058
059    /**
060     * Throws a ConstraintViolationException if the model does not contain all required server-managed triples for a
061     * container.
062     *
063     * @param model rdf to validate
064     * @throws ConstraintViolationException if model does not contain all required server-managed triples for container
065     */
066    public static void assertRequiredContainerTriples(final Model model)
067            throws ConstraintViolationException {
068        assertContainsRequiredProperties(model, REQUIRED_PROPERTIES);
069        assertContainsRequiredTypes(model, CONTAINER_TYPES);
070    }
071
072    /**
073     * Throws a ConstraintViolationException if the model does not contain all required server-managed triples for a
074     * binary description.
075     *
076     * @param model rdf to validate
077     * @throws ConstraintViolationException if model does not contain all required server-managed triples for binary
078     * description
079     */
080    public static void assertRequiredDescriptionTriples(final Model model)
081            throws ConstraintViolationException {
082        assertContainsRequiredProperties(model, REQUIRED_PROPERTIES);
083        assertContainsRequiredTypes(model, BINARY_TYPES);
084    }
085
086    private static void assertContainsRequiredProperties(final Model model, final Collection<Property> properties) {
087        for (final Property property : properties) {
088            if (!model.contains(null, property, (RDFNode) null)) {
089                throw new ConstraintViolationException("Missing required property " +
090                        property.getURI());
091            }
092        }
093    }
094
095    private static void assertContainsRequiredTypes(final Model model, final Collection<Resource> types) {
096        for (final Resource type : types) {
097            if (!model.contains(null, RDF.type, type)) {
098                throw new ConstraintViolationException("Missing required type " +
099                        type.getURI());
100            }
101        }
102    }
103}