/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE file at the root of the source * tree and available online at * * https://github.com/keeps/roda */ package org.roda.core.storage.fedora.utils; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.fcrepo.client.FedoraContent; import org.fcrepo.client.FedoraDatastream; import org.fcrepo.client.FedoraException; import org.fcrepo.client.FedoraObject; import org.roda.core.data.exceptions.GenericException; import org.roda.core.data.exceptions.RequestNotValidException; import org.roda.core.data.v2.ip.StoragePath; import org.roda.core.storage.Binary; import org.roda.core.storage.BinaryVersion; import org.roda.core.storage.Container; import org.roda.core.storage.ContentPayload; import org.roda.core.storage.DefaultBinary; import org.roda.core.storage.DefaultBinaryVersion; import org.roda.core.storage.DefaultContainer; import org.roda.core.storage.DefaultDirectory; import org.roda.core.storage.Directory; import org.roda.core.storage.fedora.FedoraContentPayload; import org.roda.core.storage.fedora.FedoraStorageService; import com.hp.hpl.jena.graph.Node; import com.hp.hpl.jena.graph.Triple; /** * Fedora related conversions utility class * * @author Sébastien Leroux <sleroux@keep.pt> * @author Hélder Silva <hsilva@keep.pt> */ public final class FedoraConversionUtils { /** * Private empty constructor */ private FedoraConversionUtils() { // do nothing } /** * Converts a {@code ContentPayload} into a {@code FedoraContent} object * * @param payload * the payload to be converted * @param mimetype * the mimetype of the payload * @throws GenericException */ public static FedoraContent contentPayloadToFedoraContent(ContentPayload payload, String mimetype) throws GenericException { InputStream inputStream = null; try { inputStream = payload.createInputStream(); return new FedoraContent().setContent(inputStream).setContentType(mimetype); } catch (IOException e) { throw new GenericException("Error while converting content payload into fedora content", e); } } /** * Converts a {@code ContentPayload} into a {@code FedoraContent} object using * the default mimetype "application/octet-stream" * * @param payload * the payload to be converted */ public static FedoraContent contentPayloadToFedoraContent(ContentPayload payload) throws GenericException { return contentPayloadToFedoraContent(payload, "application/octet-stream"); } private static StoragePath getStoragePath(FedoraDatastream ds) throws GenericException, RequestNotValidException { try { return FedoraUtils.fedoraPathToStoragePath(ds.getPath()); } catch (FedoraException e) { throw new GenericException("Error while getting the storage path from a particular Fedora datastream", e); } } private static StoragePath getStoragePath(FedoraObject obj) throws GenericException, RequestNotValidException { try { return FedoraUtils.fedoraPathToStoragePath(obj.getPath()); } catch (FedoraException e) { throw new GenericException("Error while getting the storage path from a particular Fedora object", e); } } /** * Converts a {@code FedoraDatastream} into a {@code Binary} * * @param datastream * the Fedora datastream to be converted * @throws RequestNotValidException */ public static Binary fedoraDatastreamToBinary(FedoraDatastream datastream) throws GenericException, RequestNotValidException { try { ContentPayload cp = new FedoraContentPayload(datastream); // TODO version properties doesn't contain size... long sizeInBytes = 0; try { sizeInBytes = datastream.getContentSize(); } catch (NullPointerException npe) { // do nothing } URI contentDigest = datastream.getContentDigest(); return new DefaultBinary(getStoragePath(datastream), cp, sizeInBytes, false, extractContentDigest(contentDigest)); } catch (FedoraException e) { throw new GenericException("Error while converting a Fedora datastream into a Binary", e); } } private static Map<String, String> extractContentDigest(URI contentDigest) { Map<String, String> ret = new HashMap<>(); if (contentDigest != null) { final String[] values = contentDigest.getSchemeSpecificPart().split(":"); if (values.length == 2) { ret.put(values[0], values[1]); } } return ret; } /** * Converts a {@code FedoraObject} into a {@code Directory} * * @param object * the Fedora object to be converted * @throws RequestNotValidException */ public static Directory fedoraObjectToDirectory(String fedoraRepositoryURL, FedoraObject object) throws GenericException, RequestNotValidException { return new DefaultDirectory(getStoragePath(object)); } /** * Converts a {@code Triple} iterator into a {@code Map} * * @param iterator * triple iterator to be converted */ public static Map<String, Set<String>> tripleIteratorToMap(Iterator<Triple> iterator) { Map<String, Set<String>> map = new HashMap<>(); while (iterator.hasNext()) { Triple t = iterator.next(); if (t.getMatchObject().isLiteral() && t.getMatchPredicate().getNameSpace().equalsIgnoreCase(FedoraStorageService.RODA_NAMESPACE)) { if (map.containsKey(t.getMatchPredicate().getLocalName())) { Set<String> oldList = map.get(t.getMatchPredicate().getLocalName()); oldList.add(t.getMatchObject().getLiteral().getValue().toString()); map.put(t.getMatchPredicate().getLocalName(), oldList); } else { Set<String> values = new HashSet<>(); values.add(t.getMatchObject().getLiteral().getValue().toString()); map.put(t.getMatchPredicate().getLocalName(), values); } } } return map; } /** * Converts a {@code Triple} iterator into a {@code Map} filtering by subject * * @param fedoraRepositoryURL * fedora repository url (will be used to create an URI for matching * the triple subject) * @param iterator * triple iterator to be converted * @param subject * subject by which the triples should be filtered */ public static Map<String, Set<String>> tripleIteratorToMap(String fedoraRepositoryURL, Iterator<Triple> iterator, Node subject) { Map<String, Set<String>> map = new HashMap<>(); while (iterator.hasNext()) { Triple t = iterator.next(); if (t.getMatchSubject().hasURI(fedoraRepositoryURL + subject.getURI()) && t.getMatchObject().isLiteral() && t.getMatchPredicate().getNameSpace().equalsIgnoreCase(FedoraStorageService.RODA_NAMESPACE)) { if (map.containsKey(t.getMatchPredicate().getLocalName())) { Set<String> oldList = map.get(t.getMatchPredicate().getLocalName()); oldList.add(t.getMatchObject().getLiteral().getValue().toString()); map.put(t.getMatchPredicate().getLocalName(), oldList); } else { Set<String> values = new HashSet<>(); values.add(t.getMatchObject().getLiteral().getValue().toString()); map.put(t.getMatchPredicate().getLocalName(), values); } } } return map; } /** * Converts a {@code FedoraObject} into a {@code Container} * * @param object * Fedora object to be converted * @throws RequestNotValidException */ public static Container fedoraObjectToContainer(FedoraObject object) throws GenericException, RequestNotValidException { return new DefaultContainer(getStoragePath(object)); } /** * Converts a {@code FedoraDatastream} into a {@code BinaryVersion} * * @param datastream * Fedora data stream to be converted * @param version * The version label * @param id * @throws GenericException, * RequestNotValidException, FedoraException */ public static BinaryVersion convertDataStreamToBinaryVersion(FedoraDatastream datastream, String id, Map<String, String> properties) throws GenericException, RequestNotValidException, FedoraException { Binary binary = FedoraConversionUtils.fedoraDatastreamToBinary(datastream); return new DefaultBinaryVersion(binary, id, datastream.getCreatedDate(), properties); } }