/** * Copyright 2008 The University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.unc.lib.dl.cdr.sword.server.util; import java.io.ByteArrayInputStream; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.abdera.Abdera; import org.apache.abdera.i18n.iri.IRI; import org.apache.abdera.model.Document; import org.apache.abdera.model.Element; import org.apache.abdera.parser.Parser; import org.apache.log4j.Logger; import org.swordapp.server.DepositReceipt; import org.swordapp.server.OriginalDeposit; import edu.unc.lib.dl.cdr.sword.server.SwordConfigurationImpl; import edu.unc.lib.dl.fedora.AccessClient; import edu.unc.lib.dl.fedora.FedoraException; import edu.unc.lib.dl.fedora.NotFoundException; import edu.unc.lib.dl.fedora.PID; import edu.unc.lib.dl.fedora.types.MIMETypedStream; import edu.unc.lib.dl.util.ContentModelHelper; import edu.unc.lib.dl.util.ContentModelHelper.Datastream; import edu.unc.lib.dl.util.DateTimeUtil; import edu.unc.lib.dl.util.TripleStoreQueryService; public class DepositReportingUtil { private static Logger log = Logger.getLogger(DepositReportingUtil.class); private TripleStoreQueryService tripleStoreQueryService; private AccessClient accessClient; public static class OriginalDepositPair { public String originalDepositURI; public String mimetype; public OriginalDepositPair(String originalDepositURI, String mimetype) { this.originalDepositURI = originalDepositURI; this.mimetype = mimetype; } } public OriginalDepositPair getOriginalDeposit(PID pid, SwordConfigurationImpl config) { List<String> originalDeposits = tripleStoreQueryService.fetchBySubjectAndPredicate(pid, ContentModelHelper.Relationship.originalDeposit.toString()); if (originalDeposits.size() == 0) return null; PID depositPID = new PID(originalDeposits.get(0)); Map<String, List<String>> depositTriples = tripleStoreQueryService.fetchAllTriples(depositPID); // Get originalDeposit URI List<String> values = depositTriples.get(ContentModelHelper.FedoraProperty.disseminates.toString()); if (values != null) { for (String dissemination : values) { if (dissemination.endsWith("/" + Datastream.DATA_MANIFEST.getName())) { return new OriginalDepositPair(config.getSwordPath() + SwordConfigurationImpl.EDIT_MEDIA_PATH + "/" + depositPID.getPid() + "/" + Datastream.DATA_MANIFEST.getName(), "text/xml"); } } } // Use the objects datafile as its original deposit URI if there was no manifest return new OriginalDepositPair(config.getSwordPath() + SwordConfigurationImpl.EDIT_MEDIA_PATH + "/" + pid.getPid() + "/" + Datastream.DATA_FILE.getName(), tripleStoreQueryService.lookupSourceMimeType(pid)); } public List<OriginalDeposit> getOriginalDeposits(PID pid, SwordConfigurationImpl config) { List<OriginalDeposit> results = new ArrayList<OriginalDeposit>(); List<String> originalDeposits = tripleStoreQueryService.fetchBySubjectAndPredicate(pid, ContentModelHelper.Relationship.originalDeposit.toString()); Date depositedOn = null; String depositedBy = null; String depositedOnBehalfOf = null; String originalDepositURI = null; String mimetype = null; List<String> packageTypes = null; List<String> values = null; for (String originalDeposit : originalDeposits) { PID depositPID = new PID(originalDeposit); Map<String, List<String>> depositTriples = tripleStoreQueryService.fetchAllTriples(depositPID); // Get originalDeposit URI values = depositTriples.get(ContentModelHelper.FedoraProperty.disseminates.toString()); if (values != null) { for (String dissemination : values) { if (dissemination.endsWith("/" + Datastream.DATA_MANIFEST.getName())) { originalDepositURI = config.getSwordPath() + SwordConfigurationImpl.EDIT_MEDIA_PATH + "/" + depositPID.getPid() + "/" + Datastream.DATA_MANIFEST.getName(); mimetype = "text/xml"; break; } } } // Use the objects datafile as its original deposit URI if there was no manifest if (originalDepositURI == null) { originalDepositURI = config.getSwordPath() + SwordConfigurationImpl.EDIT_MEDIA_PATH + "/" + pid.getPid() + "/" + Datastream.DATA_FILE.getName(); mimetype = tripleStoreQueryService.lookupSourceMimeType(pid); } // Get depositedOn value values = depositTriples.get(ContentModelHelper.FedoraProperty.createdDate.toString()); if (values != null && values.size() > 0) { String depositedOnString = depositTriples.get(ContentModelHelper.FedoraProperty.createdDate.toString()) .get(0); try { depositedOn = DateTimeUtil.parseUTCToDate(depositedOnString); } catch (ParseException e) { log.error("Could not parse deposited on", e); } } // Get package types packageTypes = depositTriples.get(ContentModelHelper.CDRProperty.depositPackageType.toString()); values = depositTriples.get(ContentModelHelper.CDRProperty.depositPackageSubType.toString()); if (values != null && values.size() > 0) { if (packageTypes == null) packageTypes = new ArrayList<String>(); packageTypes.addAll(values); } // Get deposited by values = depositTriples.get(ContentModelHelper.Relationship.depositedBy.toString()); if (values != null && values.size() > 0) { PID depositedByPID = new PID(values.get(0)); depositedBy = tripleStoreQueryService.fetchFirstBySubjectAndPredicate(depositedByPID, ContentModelHelper.CDRProperty.onyen.toString()); } // Get on behalf of values = depositTriples.get(ContentModelHelper.CDRProperty.depositedOnBehalfOf.toString()); if (values != null && values.size() > 0) { depositedOnBehalfOf = values.get(0); } OriginalDeposit deposit = new OriginalDeposit(originalDepositURI, packageTypes, depositedOn, depositedBy, depositedOnBehalfOf); deposit.setMediaType(mimetype); results.add(deposit); } return results; } /** * Generates a DepositReceipt object for the specified PID. This represents state of the target, how it has * been unpacked, as well as paths to its individual components and deposit manifest. * @param targetPID * @param config * @return */ public DepositReceipt retrieveDepositReceipt(PID targetPID, SwordConfigurationImpl config) { DepositReceipt receipt = new DepositReceipt(); return retrieveDepositReceipt(receipt, targetPID, config); } /** * Adds receipt information to the DepositReceipt object for the specified PID. This represents state of the target, * how it has been unpacked, as well as paths to its individual components and deposit manifest. * * @param receipt * @param targetPID * @param config * @return */ public DepositReceipt retrieveDepositReceipt(DepositReceipt receipt, PID targetPID, SwordConfigurationImpl config) { IRI editIRI = new IRI(config.getSwordPath() + SwordConfigurationImpl.EDIT_PATH + "/" + targetPID.getPid()); receipt.setEditIRI(editIRI); IRI swordEditIRI = new IRI(config.getSwordPath() + SwordConfigurationImpl.EDIT_PATH + "/" + targetPID.getPid()); receipt.setSwordEditIRI(swordEditIRI); receipt.addEditMediaIRI(new IRI(config.getSwordPath() + SwordConfigurationImpl.EDIT_MEDIA_PATH + "/" + targetPID.getPid())); //Add in original deposit OriginalDepositPair originalDeposit = getOriginalDeposit(targetPID, config); if (originalDeposit != null) receipt.setOriginalDeposit(originalDeposit.originalDepositURI, originalDeposit.mimetype); // Add in derived resources representing all of the datastreams on this object Map<String,String> disseminators = tripleStoreQueryService.fetchDisseminatorMimetypes(targetPID); for (Map.Entry<String,String> disseminator: disseminators.entrySet()){ PID disseminatorPID = new PID(disseminator.getKey()); receipt.addDerivedResource(config.getSwordPath() + SwordConfigurationImpl.EDIT_MEDIA_PATH + "/" + disseminatorPID.getPid(), disseminator.getValue()); } receipt.setSplashUri(config.getBasePath() + "record?id=" + targetPID.getPid()); receipt.setStatementURI("application/atom+xml;type=feed", config.getSwordPath() + SwordConfigurationImpl.STATE_PATH + "/" + targetPID.getPid()); try { MIMETypedStream metadataStream = null; try { metadataStream = accessClient.getDatastreamDissemination(targetPID, ContentModelHelper.Datastream.MD_DESCRIPTIVE.getName(), null); } catch (NotFoundException notFound) { // There was no MODS, which is okay, look for DC next } if (metadataStream == null){ //If there is a DC stream instead, then add all its children try { metadataStream = accessClient.getDatastreamDissemination(targetPID, ContentModelHelper.Datastream.DC.getName(), null); if (metadataStream != null) { Abdera abdera = new Abdera(); Parser parser = abdera.getParser(); Document<Element> entryDoc = parser.parse(new ByteArrayInputStream(metadataStream.getStream())); for (Element child: entryDoc.getRoot().getElements()){ receipt.addDublinCore(child.getQName().getLocalPart(), child.getText()); } } } catch (NotFoundException notFound) { // No DC either, so no metadata } } else { // Build MODS as an Abdera entry and add it to the receipt entry. Abdera abdera = new Abdera(); Parser parser = abdera.getParser(); Document<Element> entryDoc = parser.parse(new ByteArrayInputStream(metadataStream.getStream())); receipt.getWrappedEntry().addExtension(entryDoc.getRoot()); } } catch (FedoraException e) { log.error("Error retrieving MD_DESCRIPTIVE for object " + targetPID.getPid(), e); } return receipt; } public void setTripleStoreQueryService(TripleStoreQueryService tripleStoreQueryService) { this.tripleStoreQueryService = tripleStoreQueryService; } public void setAccessClient(AccessClient accessClient) { this.accessClient = accessClient; } }