001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.kernel.impl.rdf.impl;
017
018import static com.google.common.base.Throwables.propagate;
019import static com.google.common.collect.ImmutableSet.builder;
020import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
021import static com.hp.hpl.jena.graph.NodeFactory.createURI;
022import static com.hp.hpl.jena.graph.Triple.create;
023import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
024import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral;
025import static org.fcrepo.kernel.RdfLexicon.CONTENT_LOCATION_TYPE;
026import static org.fcrepo.kernel.RdfLexicon.FIXITY_TYPE;
027import static org.fcrepo.kernel.RdfLexicon.HAS_MESSAGE_DIGEST;
028import static org.fcrepo.kernel.RdfLexicon.HAS_SIZE;
029import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_RESULT;
030import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_STATE;
031import static org.fcrepo.kernel.RdfLexicon.HAS_CONTENT_LOCATION;
032import static org.fcrepo.kernel.RdfLexicon.HAS_CONTENT_LOCATION_VALUE;
033
034import java.net.URI;
035import java.util.Calendar;
036import java.util.Iterator;
037import javax.jcr.RepositoryException;
038
039import com.hp.hpl.jena.rdf.model.Resource;
040import com.hp.hpl.jena.vocabulary.RDF;
041import org.fcrepo.kernel.models.FedoraResource;
042import org.fcrepo.kernel.identifiers.IdentifierConverter;
043import org.fcrepo.kernel.utils.FixityResult;
044
045import com.google.common.base.Function;
046import com.google.common.collect.ImmutableSet;
047import com.google.common.collect.Iterators;
048import com.hp.hpl.jena.graph.Triple;
049
050/**
051 * An {@link org.fcrepo.kernel.utils.iterators.RdfStream} containing information about the fixity of a
052 * {@link org.fcrepo.kernel.models.FedoraBinary}.
053 *
054 * @author ajs6f
055 * @since Oct 15, 2013
056 */
057public class FixityRdfContext extends NodeRdfContext {
058
059    /**
060     * Ordinary constructor.
061     *
062     * @param resource
063     * @param idTranslator
064     * @param blobs
065     */
066    public FixityRdfContext(final FedoraResource resource,
067                            final IdentifierConverter<Resource, FedoraResource> idTranslator,
068                            final Iterable<FixityResult> blobs,
069                            final URI digest,
070                            final long size) {
071        super(resource, idTranslator);
072
073        concat(Iterators.concat(Iterators.transform(blobs.iterator(),
074                new Function<FixityResult, Iterator<Triple>>() {
075
076                    @Override
077                    public Iterator<Triple> apply(final FixityResult blob) {
078                        final com.hp.hpl.jena.graph.Node resultSubject = getTransientFixitySubject();
079                        final ImmutableSet.Builder<Triple> b = builder();
080                        try {
081                            b.add(create(idTranslator.reverse().convert(resource).asNode(),
082                                    HAS_FIXITY_RESULT.asNode(), resultSubject));
083                            b.add(create(resultSubject, RDF.type.asNode(), FIXITY_TYPE.asNode()));
084                            final String storeIdentifier = blob.getStoreIdentifier();
085                            final com.hp.hpl.jena.graph.Node contentLocation = createResource(storeIdentifier)
086                                                                     .asNode();
087
088                            for (final FixityResult.FixityState state : blob.getStatus(size, digest)) {
089                                b.add(create(resultSubject, HAS_FIXITY_STATE
090                                        .asNode(), createLiteral(state
091                                        .toString())));
092                            }
093                            final String checksum =
094                                    blob.getComputedChecksum().toString();
095                            b.add(create(resultSubject, HAS_MESSAGE_DIGEST
096                                    .asNode(), createURI(checksum)));
097                            b.add(create(resultSubject, HAS_SIZE.asNode(),
098                                    createTypedLiteral(
099                                            blob.getComputedSize())
100                                    .asNode()));
101                            b.add(create(resultSubject, HAS_CONTENT_LOCATION.asNode(),
102                                    contentLocation));
103                            b.add(create(contentLocation,
104                                    RDF.type.asNode(),
105                                    CONTENT_LOCATION_TYPE.asNode()));
106                            b.add(create(contentLocation,
107                                    HAS_CONTENT_LOCATION_VALUE.asNode(),
108                                    createLiteral(storeIdentifier)));
109
110                            return b.build().iterator();
111                        } catch (final RepositoryException e) {
112                            throw propagate(e);
113                        }
114                    }
115                })));
116    }
117
118    private com.hp.hpl.jena.graph.Node getTransientFixitySubject() {
119        return createURI(subject().getURI() + "#fixity/" + Calendar.getInstance().getTimeInMillis());
120    }
121}