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}