de.fhg.iais.asc.workflow.ASCTransform.java Source code

Java tutorial

Introduction

Here is the source code for de.fhg.iais.asc.workflow.ASCTransform.java

Source

package de.fhg.iais.asc.workflow;

/******************************************************************************
 * 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 static de.fhg.iais.cortex.report.common.sip.ErrorSip.SECTION_TRANSFORM;

import java.io.File;
import java.util.Iterator;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.fhg.iais.asc.commons.AscConfigEval;
import de.fhg.iais.asc.commons.AscConfiguration;
import de.fhg.iais.asc.commons.AscContext;
import de.fhg.iais.asc.commons.LogMessageBuilder;
import de.fhg.iais.asc.commons.PathNameUtils;
import de.fhg.iais.asc.commons.state.ASCState;
import de.fhg.iais.asc.contexts.AscProviderIngest;
import de.fhg.iais.asc.directories.AscDirectory;
import de.fhg.iais.asc.logging.ILogVocabulary;
import de.fhg.iais.asc.sipmaker.ISipMaker;
import de.fhg.iais.asc.sipmaker.SipMakerFactory;
import de.fhg.iais.asc.sipmaker.SipMakerKey;
import de.fhg.iais.asc.transformer.TransformationContext;
import de.fhg.iais.asc.transformer.jdom.AbstractTransformer;
import de.fhg.iais.asc.transformer.jdom.TransformDoc;
import de.fhg.iais.asc.transformer.jdom.TransformDocBuilder;
import de.fhg.iais.asc.transformer.jdom.TransformDocContextImpl;
import de.fhg.iais.asc.transformer.jdom.splitter.AscSplitLimitExceededException;
import de.fhg.iais.asc.viewspreview.ViewFilesGenerator;
import de.fhg.iais.commons.time.StopWatch;
import de.fhg.iais.cortex.report.common.sip.ErrorSip;

/**
 * This class manages the transformation processes of the Augmented SIP Creator (ASC)
 *
 * @author hjh, cto, kst
 */
final class ASCTransform {
    private static final Logger LOG = LoggerFactory.getLogger(ASCTransform.class);

    private static final String[] INBOX_EXTENSIONS = { "xml", "XML" };

    private final AscConfiguration config;
    private final ISipMaker maker;

    public ASCTransform(AscConfiguration config, SipMakerFactory makerFactory) {
        this.config = config;
        this.maker = loadMaker(makerFactory);
    }

    protected final ISipMaker loadMaker(SipMakerFactory factory) {
        String def = this.config.get(AscConfiguration.FORMAT, "");
        SipMakerKey description = SipMakerKey.fromCommaSeparated(def);
        return factory.getSipMaker(description, true, this.config);
    }

    /**
     * Transforms a single ingest.
     *
     * @param ingest The ingest to process, non-{@code null}.
     * @param parentAscContext The ASC context in which this method is executed, non-{@code null}.
     */
    public void run(AscProviderIngest ingest, AscContext parentAscContext) {
        AscContext ascContext = new AscContext(ILogVocabulary.EVENT_INGEST + "(" + ingest.getIngestEventId() + ")");
        try {
            AscConfiguration config = ingest.getConfiguration();
            ASCState ascState = config.getASCState();

            logInfoAndDisplayMessage("Removing errors from previous transformations ...", ascContext);
            ingest.removeOldErrors(ErrorSip.SECTION_TRANSFORM);

            if (AscConfigEval.isCleanupEnabled(config)) {
                logInfoAndDisplayMessage("Removing result directories from previous transformations ...",
                        ascContext);
                ingest.removeDirectory(AscDirectory.WORKSPACE);
                ingest.removeDirectory(AscDirectory.OUTBOX);
            }

            logInfoAndDisplayMessage("Transforming ...", ascContext);
            executeTransformations(ingest, ascContext);

            // Interrupt if needed.
            if (ascState.isCancelRequested()) {
                return;
            }

            // For debugging, generate HTML files out of the views of the generated SIPs.
            if (this.config.get(AscConfiguration.GENERATEHTMLPREVIEWS, false)) {
                String folder = ingest.checkedGetDirectory(AscDirectory.OUTBOX).getPath();
                logInfoAndDisplayMessage("Generating previews", ascContext);
                logInfoAndDisplayMessage("Folder is " + folder, ascContext);
                new ViewFilesGenerator(folder, config).generateViewFiles();
            }
        } catch (Exception e) {
            logWarnAndReportProblem(
                    "The transformation process of ingest event " + ingest.getIngestEventId() + " failed",
                    ascContext);

            // Write an error SIP.
            // At this point, we don't have a filename, so leave it empty.
            ingest.writeErrorSip(ErrorSip.SECTION_TRANSFORM, "", e);
        }
    }

    private void executeTransformations(AscProviderIngest ingest, AscContext parentAscContext) {
        TransformationContext transContext = new TransformationContext(ingest);
        transContext.register();
        try {
            executeTransformations(transContext, parentAscContext);
        } finally {
            transContext.unregister();
        }
    }

    private void executeTransformations(final TransformationContext transContext, AscContext parentAscContext) {
        StopWatch s = StopWatch.start();

        final int maxFileCount = this.config.get(AscConfiguration.MAX_FILES_EACH, Integer.MAX_VALUE);
        int remainingFileCount = maxFileCount;

        final AbstractTransformer transformer = this.maker.getRootTransformer();

        final TransformDocContextImpl transDocContext = new TransformDocContextImpl(transContext,
                this.maker.getInputSchema());
        final TransformDocBuilder builder = new TransformDocBuilder().withContext(transDocContext);

        final File root = transDocContext.getInboxRoot().getAbsoluteFile();

        final Iterator<File> fileIter = FileUtils.iterateFiles(root, INBOX_EXTENSIONS, true);

        while (fileIter.hasNext()) {
            if (--remainingFileCount < 0) {
                LOG.info("Transformation stopped by " + AscConfiguration.MAX_FILES_EACH + "=" + maxFileCount,
                        parentAscContext);
                break;
            }

            final File f = fileIter.next();
            final String relativePath = PathNameUtils.unbase(f, root);
            AscContext ascContext = new AscContext(ILogVocabulary.INPUT + "(" + relativePath + ")",
                    parentAscContext);
            try {
                final TransformDoc transformDoc = builder.withPath(relativePath).build();
                try {
                    transformer.transform(transformDoc, ascContext);
                } catch (AscSplitLimitExceededException e) {
                    LOG.info(LogMessageBuilder.getMessage(e));
                }
            } catch (Exception e) {
                transContext.getIngest().writeErrorSip(SECTION_TRANSFORM, relativePath, e);
                builder.withPath(relativePath).build().updateAscErrorLoggingStatistic(transformer.getName(), e);
                LOG.error(LogMessageBuilder.getMessage("Transformation of " + relativePath + " failed", ascContext),
                        e);
            }
        }
        s.stop("Time used for transformations");

    }

    private void logInfoAndDisplayMessage(String message, AscContext ascContext) {
        message = LogMessageBuilder.getMessage(message, ascContext);
        LOG.info(message);
        if (this.config != null && this.config.getASCState() != null) {
            this.config.getASCState().displayMessage(message);
        }
    }

    private void logWarnAndReportProblem(String message, AscContext ascContext) {
        message = LogMessageBuilder.getMessage(message, ascContext);
        LOG.warn(message);
        if (this.config != null && this.config.getASCState() != null) {
            this.config.getASCState().reportProblem(message);
        }
    }

}