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.collect.ImmutableSet.builder;
019import static com.hp.hpl.jena.graph.NodeFactory.createLiteral;
020import static com.hp.hpl.jena.graph.NodeFactory.createURI;
021import static com.hp.hpl.jena.graph.Triple.create;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
023import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral;
024import static org.fcrepo.kernel.RdfLexicon.CONTENT_LOCATION_TYPE;
025import static org.fcrepo.kernel.RdfLexicon.FIXITY_TYPE;
026import static org.fcrepo.kernel.RdfLexicon.HAS_MESSAGE_DIGEST;
027import static org.fcrepo.kernel.RdfLexicon.HAS_SIZE;
028import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_RESULT;
029import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_STATE;
030import static org.fcrepo.kernel.RdfLexicon.HAS_CONTENT_LOCATION;
031import static org.fcrepo.kernel.RdfLexicon.HAS_CONTENT_LOCATION_VALUE;
032
033import java.net.URI;
034import java.util.Calendar;
035import java.util.Iterator;
036import javax.jcr.RepositoryException;
037
038import com.hp.hpl.jena.rdf.model.Resource;
039import com.hp.hpl.jena.vocabulary.RDF;
040import org.fcrepo.kernel.exception.RepositoryRuntimeException;
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 the resource
063     * @param idTranslator the id translator
064     * @param blobs the blobs
065     * @param digest the digest uri
066     * @param size the size
067     */
068    public FixityRdfContext(final FedoraResource resource,
069                            final IdentifierConverter<Resource, FedoraResource> idTranslator,
070                            final Iterable<FixityResult> blobs,
071                            final URI digest,
072                            final long size) {
073        super(resource, idTranslator);
074
075        concat(Iterators.concat(Iterators.transform(blobs.iterator(),
076                new FixityResultIteratorFunction(resource, idTranslator, digest, size))));
077    }
078
079    private class FixityResultIteratorFunction implements Function<FixityResult, Iterator<Triple>> {
080
081        private final FedoraResource resource;
082        private final IdentifierConverter<Resource, FedoraResource> idTranslator;
083        private URI digest;
084        private final long size;
085
086        public FixityResultIteratorFunction(final FedoraResource resource,
087                                            final IdentifierConverter<Resource, FedoraResource> idTranslator,
088                                            final URI digest,  final long size) {
089            this.resource = resource;
090            this.idTranslator = idTranslator;
091            this.digest = digest;
092            this.size = size;
093        }
094
095        @Override
096        public Iterator<Triple> apply(final FixityResult blob) {
097            final com.hp.hpl.jena.graph.Node resultSubject = getTransientFixitySubject();
098            final ImmutableSet.Builder<Triple> b = builder();
099            try {
100                b.add(create(idTranslator.reverse().convert(resource).asNode(),
101                        HAS_FIXITY_RESULT.asNode(), resultSubject));
102                b.add(create(resultSubject, RDF.type.asNode(), FIXITY_TYPE.asNode()));
103                final String storeIdentifier = blob.getStoreIdentifier();
104                final com.hp.hpl.jena.graph.Node contentLocation = createResource(storeIdentifier)
105                        .asNode();
106
107                for (final FixityResult.FixityState state : blob.getStatus(size, digest)) {
108                    b.add(create(resultSubject, HAS_FIXITY_STATE
109                            .asNode(), createLiteral(state
110                            .toString())));
111                }
112                final String checksum =
113                        blob.getComputedChecksum().toString();
114                b.add(create(resultSubject, HAS_MESSAGE_DIGEST
115                        .asNode(), createURI(checksum)));
116                b.add(create(resultSubject, HAS_SIZE.asNode(),
117                        createTypedLiteral(
118                                blob.getComputedSize())
119                                .asNode()));
120                b.add(create(resultSubject, HAS_CONTENT_LOCATION.asNode(),
121                        contentLocation));
122                b.add(create(contentLocation,
123                        RDF.type.asNode(),
124                        CONTENT_LOCATION_TYPE.asNode()));
125                b.add(create(contentLocation,
126                        HAS_CONTENT_LOCATION_VALUE.asNode(),
127                        createLiteral(storeIdentifier)));
128
129                return b.build().iterator();
130            } catch (final RepositoryException e) {
131                throw new RepositoryRuntimeException(e);
132            }
133        }
134
135    }
136
137    private com.hp.hpl.jena.graph.Node getTransientFixitySubject() {
138        return createURI(subject().getURI() + "#fixity/" + Calendar.getInstance().getTimeInMillis());
139    }
140}