/** * 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.update; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.input.SAXBuilder; import edu.unc.lib.dl.fedora.AccessClient; import edu.unc.lib.dl.fedora.AuthorizationException; import edu.unc.lib.dl.fedora.ClientUtils; import edu.unc.lib.dl.fedora.FedoraException; import edu.unc.lib.dl.fedora.FileSystemException; 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.AtomPubMetadataParserUtil; import edu.unc.lib.dl.util.ContentModelHelper.Datastream; public class MetadataUIP extends FedoraObjectUIP { private static Logger log = Logger.getLogger(MetadataUIP.class); public MetadataUIP(PID pid, String user, UpdateOperation operation) { super(pid, user, operation); incomingData = new HashMap<String,Element>(); originalData = new HashMap<String,Element>(); modifiedData = new HashMap<String,Element>(); } @SuppressWarnings("unchecked") @Override public Map<String, Element> getIncomingData() { return (Map<String, Element>) incomingData; } @SuppressWarnings("unchecked") @Override public Map<String, Element> getOriginalData() { return (Map<String, Element>) originalData; } @SuppressWarnings("unchecked") @Override public Map<String, Element> getModifiedData() { return (Map<String, Element>) modifiedData; } @Override public String getMimetype(String key) { return "text/xml"; } @Override public void storeOriginalDatastreams(AccessClient accessClient) throws UIPException { if (incomingData == null) return; SAXBuilder builder = new SAXBuilder(); for (String datastream: incomingData.keySet()){ log.debug("Retrieving original document for " + datastream); // Only attempt to retrieve known datastreams if (Datastream.getDatastream(datastream) == null && !AtomPubMetadataParserUtil.ATOM_DC_DATASTREAM.equals(datastream)) { log.debug("Datastream " + datastream + " was not a known datastream, skipping"); continue; } ByteArrayInputStream inputStream = null; try { MIMETypedStream dsStream = accessClient.getDatastreamDissemination(pid, datastream, null); if (dsStream != null){ inputStream = new ByteArrayInputStream(dsStream.getStream()); Document dsDocument = builder.build(inputStream); Element rootElement = dsDocument.detachRootElement(); this.getOriginalData().put(datastream, rootElement); } } catch (NotFoundException e){ //Datastream wasn't found, therefore it doesn't exist and no original should be added log.debug("Datastream " + datastream + " was not found for pid " + pid); } catch (FedoraException e) { if (e instanceof FileSystemException || e instanceof AuthorizationException) throw new UIPException("Exception occurred while attempting to store datastream " + datastream + " for " + pid.getPid(), e); // Fedora isn't correctly identifying NotFoundExceptions in 3.6.2's soap client, so identify it by process of elimination } catch (Exception e) { throw new UIPException("Exception occurred while attempting to store datastream " + datastream + " for " + pid.getPid(), e); } finally { if (inputStream != null) try { inputStream.close(); } catch (IOException e) { throw new UIPException("Exception occurred while attempting to store datastream " + datastream + " for " + pid.getPid(), e); } } } } /** * Generates temporary files for each metadata datastream and returns a hash of them by datastream */ @Override public Map<String, File> getModifiedFiles() { Map<String, File> modifiedFiles = new HashMap<String, File>(); for (Entry<String, ?> modified : modifiedData.entrySet()) { Element modifiedElement = (Element)modified.getValue(); try { File temp = ClientUtils.writeXMLToTempFile(modifiedElement); modifiedFiles.put(modified.getKey(), temp); } catch (IOException e) { log.error("Failed to create temp file", e); } } return modifiedFiles; } }