de.fhg.iais.cortex.services.AbstractAipIngestService.java Source code

Java tutorial

Introduction

Here is the source code for de.fhg.iais.cortex.services.AbstractAipIngestService.java

Source

package de.fhg.iais.cortex.services;

/******************************************************************************
 * Copyright 2011 (c) Fraunhofer IAIS Netmedia  http://www.iais.fraunhofer.de *
 * ************************************************************************** *
 * 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.                                             *
 ******************************************************************************/

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;

import javax.xml.bind.JAXBException;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.jdom.CDATA;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import com.google.common.base.Charsets;

import de.fhg.iais.commons.stream.INamedBinaryStream;
import de.fhg.iais.cortex.model.aip.AipObject;
import de.fhg.iais.cortex.model.aip.generated.Cortex;
import de.fhg.iais.cortex.model.aip.util.XmlProcessor;
import de.fhg.iais.cortex.model.util.GlobalConstants;
import de.fhg.iais.cortex.report.common.ReportSections;
import de.fhg.iais.cortex.report.common.revision.ErrorReport;
import de.fhg.iais.cortex.report.common.revision.RevisionReport;
import de.fhg.iais.cortex.report.common.sip.ErrorSip;
import de.fhg.iais.cortex.services.ingest.ErrorSipReader;
import de.fhg.iais.cortex.services.ingest.ZipStreamAipBinaries;

public abstract class AbstractAipIngestService implements IIngestService {

    @Override
    public IngestResult ingest(IIngestContext context, InputStream aipAsStream, String aipMimeType) {

        try {
            if (aipMimeType.equals(IIngestService.TYPE_CORTEX_AIP)) {

                AipObject aip = new AipObject((Cortex) XmlProcessor.unmarshalToObject(aipAsStream));
                context.setAipObject(aip);

                return ingestSipAndBinaries(context);
            } else if (aipMimeType.equals(IIngestService.TYPE_ZIP)) {
                return ingestSipZip(context, aipAsStream);
            } else {
                //report contains at least a bit of information unless the xml could not read.
                context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                        "Invalid MIME type, cancelling ", null);
            }
        } catch (JAXBException e) {
            context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                    "Invalid XML format, cancelling ", e);
        } finally {
            IOUtils.closeQuietly(aipAsStream);
        }
        return IngestResult.ERROR;
    }

    private IngestResult ingestSipZip(IIngestContext context, InputStream sipzipStream) {
        ZipStreamAipBinaries zipStream = null;
        try {
            zipStream = new ZipStreamAipBinaries(sipzipStream);
            INamedBinaryStream firstStream = zipStream.takeBinary();

            if (firstStream == null) {
                context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                        "Zip stream contains no files", null);
            } else {
                String firstStreamName = firstStream.getBinaryName();
                if (firstStreamName.equalsIgnoreCase("sip.xml")) {
                    InputStream input = null;
                    try {
                        input = firstStream.getBinaryStream();

                        String inputString = IOUtils.toString(input, Charsets.UTF_8);

                        inputString = sanitizeOldAscFormat(inputString);

                        Cortex cortexAipObject = (Cortex) XmlProcessor.unmarshalToObject(inputString);
                        AipObject aip = new AipObject(cortexAipObject, zipStream);
                        context.setAipObject(aip);
                    } finally {
                        IOUtils.closeQuietly(input);
                    }
                    return this.ingestSipAndBinaries(context);
                } else if (firstStreamName.equalsIgnoreCase("error.xml")) {
                    return ingestErrorSip(context, firstStream);
                } else {
                    context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                            "First file in the SIP must be error.sip or sip.xml - this one was:" + firstStreamName,
                            null);
                }
            }
        } catch (JDOMException e) {
            context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                    "Invalid XML format, cancelling ", e);
        } catch (IOException e) {
            context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE, "I/O error: ", e);
        } catch (JAXBException e) {
            context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                    "Invalid XML format, cancelling ", e);
        } finally {
            IOUtils.closeQuietly(zipStream);
            IOUtils.closeQuietly(sipzipStream);
        }
        return IngestResult.ERROR;
    }

    private String sanitizeOldAscFormat(String inputString) throws JDOMException, IOException {
        if (!StringUtils.containsIgnoreCase(inputString, GlobalConstants.CORTEX_NAMESPACE_URI)) {
            inputString = inputString.replaceFirst("<cortex>",
                    "<cortex xmlns=\"" + GlobalConstants.CORTEX_NAMESPACE_URI + "\">");
        }

        StringReader reader = null;
        try {
            reader = new StringReader(inputString);
            Document jdomAip = new SAXBuilder().build(reader);

            XMLOutputter outp = new XMLOutputter();
            outp.setFormat(Format.getPrettyFormat().setEncoding(Charsets.UTF_8.name()));

            if (jdomAip.getRootElement().getChild("edm", GlobalConstants.CORTEX_NAMESPACE) == null) {

                Element child = jdomAip.getRootElement()
                        .getChild("provider-metadata-sets", GlobalConstants.CORTEX_NAMESPACE)
                        .getChild("original-source", GlobalConstants.CORTEX_NAMESPACE);

                if (child.getChildren().size() > 0) {
                    String originalSourceCData = outp.outputString((Element) child.getChildren().get(0));
                    child.removeContent();
                    child.addContent(new CDATA(originalSourceCData));
                }

            }
            return outp.outputString(jdomAip);

        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    private IngestResult ingestErrorSip(IIngestContext context, INamedBinaryStream firstStream) {
        try {
            ErrorSip sip = ErrorSipReader.readFrom(firstStream.getBinaryStream());

            ErrorReport report = sip.getError();
            context.setItemId(report.getItemId());
            context.setFilename(report.getOriginalFilename());

            context.reportError(RevisionReport.ASC_PART, sip.getSection(), report, false);
        } catch (JAXBException e) {
            context.reportAndThrowDataError(RevisionReport.INGEST_PART, ReportSections.RECEIVE,
                    "Invalid content of error SIP", e);
        }
        return IngestResult.ERROR_SIP_INGESTED;
    }

    protected abstract IngestResult ingestSipAndBinaries(IIngestContext ingestContext);
}