de.fhg.iais.asc.sipmaker.impl.DefaultSipMaker.java Source code

Java tutorial

Introduction

Here is the source code for de.fhg.iais.asc.sipmaker.impl.DefaultSipMaker.java

Source

package de.fhg.iais.asc.sipmaker.impl;

/******************************************************************************
 * 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.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;

import javax.inject.Inject;
import javax.inject.Named;
import javax.xml.validation.Schema;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

import com.google.common.base.Strings;
import com.google.inject.Injector;

import de.fhg.iais.asc.commons.AscConfiguration;
import de.fhg.iais.asc.commons.exceptions.AscConfigFailureException;
import de.fhg.iais.asc.sipmaker.ISipMaker;
import de.fhg.iais.asc.sipmaker.SipMakerDynamicClass;
import de.fhg.iais.asc.transformer.jdom.AbstractSplitter;
import de.fhg.iais.asc.transformer.jdom.AbstractTransformer;
import de.fhg.iais.asc.transformer.jdom.LastMinuteAipTransformer;
import de.fhg.iais.asc.transformer.jdom.MultiTransformer;
import de.fhg.iais.asc.transformer.jdom.ParentTransformerDecorator;
import de.fhg.iais.asc.transformer.jdom.SaveAipToTargetFileTransformer;
import de.fhg.iais.asc.transformer.jdom.validator.AipSchemaValidator;
import de.fhg.iais.asc.transformer.jdom.validator.EDMSchemaValidator;
import de.fhg.iais.asc.transformer.jdom.validator.SchemaValidator;
import de.fhg.iais.asc.transformer.jdom.validator.SchematronValidator;
import de.fhg.iais.asc.transformer.jdom.xslt.impl.AscTransformXSLResolver;
import de.fhg.iais.asc.util.FileInProject;
import de.fhg.iais.commons.annotation.UsedBy;

@UsedBy("guice")
public class DefaultSipMaker implements ISipMaker {
    private static final Pattern COMMA = Pattern.compile(",");

    private class TransformerListBuilder {
        private final Injector injector;
        private final AscTransformXSLResolver xslTransformContext;
        private final List<AbstractTransformer> list = new LinkedList<AbstractTransformer>();

        TransformerListBuilder(File sipMakerBaseDir, Injector injector) {
            this.injector = injector;
            this.xslTransformContext = new AscTransformXSLResolver(getTransformersDir(sipMakerBaseDir));
        }

        void addXmlProcessors(Properties config, String packageKey, String processorsKey) {
            String xmlProcessorPackage = config.getProperty(packageKey);
            String xmlProcessorsCommaSeparated = StringUtils.trimToEmpty(config.getProperty(processorsKey));

            for (String xmlProcessor : COMMA.split(xmlProcessorsCommaSeparated)) {
                xmlProcessor = StringUtils.trimToNull(xmlProcessor);

                if (xmlProcessor != null) {
                    String fullName = SipMakerDynamicClass.fullClassName(xmlProcessorPackage, xmlProcessor);
                    this.list.add(SipMakerDynamicClass.resolve(this.injector, fullName, AbstractTransformer.class));
                }
            }
        }

        void addXslTransformersForFormat(String mdFormat, List<String> omitFolders) {
            this.list.addAll(this.xslTransformContext.createAipTransformers(mdFormat, omitFolders));
        }

        void addSchematronValidator(boolean continueOnCritical) {
            this.list.add(new SchematronValidator(this.xslTransformContext, "common/schematron/validator",
                    continueOnCritical));
        }

        void addEnvironmentVariablesTransformer(String transformerDesc) {
            AbstractTransformer transformer = this.xslTransformContext.createEnvironmentVariables(transformerDesc);
            this.list.add(transformer);
        }

        void addTransformer(AbstractTransformer transformer) {
            this.list.add(transformer);
        }

        MultiTransformer build() {
            MultiTransformer result = new MultiTransformer(this.list);
            this.list.clear();
            return result;
        }

    }

    private final ParentTransformerDecorator rootTransformer;
    private final Schema inputSchema;

    @Inject
    public DefaultSipMaker(@Named(ISipMaker.BASE_DIR) File sipMakerBaseDir,
            @Named(ISipMaker.CONFIG) Properties config, AscConfiguration ascConfig, Injector injector) {

        // Init global preprocessing, if activated
        TransformerListBuilder preprocessingBuilder = new TransformerListBuilder(sipMakerBaseDir, injector);

        if (ascConfig.get(AscConfiguration.TRANSFORM_GLOBAL_PREPROCESSING_ENABLED, false)) {
            addPreprocessingScripts(ascConfig.get(AscConfiguration.TRANSFORM_GLOBAL_PREPROCESSING_FOLDER, ""),
                    sipMakerBaseDir, preprocessingBuilder);
        }

        this.rootTransformer = new ParentTransformerDecorator(preprocessingBuilder.build());

        AbstractSplitter splitter = (AbstractSplitter) SipMakerDynamicClass.resolve(injector,
                config.getProperty("splitterPackage"), config.getProperty("splitter"));

        String mdFormat = ascConfig.get(AscConfiguration.FORMAT, "");
        for (String format : COMMA.split(mdFormat)) {
            if (!Strings.isNullOrEmpty(format)) {
                mdFormat = format;
            }
        }

        List<String> skipFolders = new ArrayList<String>();
        if (config.getProperty("skipFolders") != null) {
            skipFolders = Arrays.asList(config.getProperty("skipFolders").split(","));
        }

        TransformerListBuilder multiBuilder = new TransformerListBuilder(sipMakerBaseDir, injector);

        // Init local preprocessing, if activated
        if (ascConfig.get(AscConfiguration.TRANSFORM_LOCAL_PREPROCESSING_ENABLED, false)) {
            addPreprocessingScripts(
                    mdFormat + File.separator
                            + ascConfig.get(AscConfiguration.TRANSFORM_LOCAL_PREPROCESSING_FOLDER, ""),
                    sipMakerBaseDir, multiBuilder);
        }

        // do regular transformations
        multiBuilder.addEnvironmentVariablesTransformer(mdFormat);
        multiBuilder.addXmlProcessors(config, "xmlProcessorPackage", "xmlProcessors");
        multiBuilder.addXslTransformersForFormat(mdFormat, skipFolders);
        multiBuilder.addTransformer(new LastMinuteAipTransformer());

        if (ascConfig.get(AscConfiguration.TRANSFORM_VALIDATE_WITH_SCHEMATRON, false)) {
            boolean continueOnCritical = ascConfig
                    .get(AscConfiguration.TRANSFORM_VALIDATE_WITH_SCHEMATRON_CONTINUE_ON_CRITICAL, false);
            multiBuilder.addSchematronValidator(continueOnCritical);
        }

        // Init global postprocessing, if activated
        if (ascConfig.get(AscConfiguration.TRANSFORM_GLOBAL_POSTPROCESSING_ENABLED, false)) {
            addPostprocessingScripts(ascConfig.get(AscConfiguration.TRANSFORM_GLOBAL_POSTPROCESSING_FOLDER, ""),
                    sipMakerBaseDir, multiBuilder);
        }

        // Init local postprocessing, if activated
        if (ascConfig.get(AscConfiguration.TRANSFORM_LOCAL_POSTPROCESSING_ENABLED, false)) {
            addPostprocessingScripts(
                    mdFormat + File.separator
                            + ascConfig.get(AscConfiguration.TRANSFORM_LOCAL_POSTPROCESSING_FOLDER, ""),
                    sipMakerBaseDir, multiBuilder);
        }

        // Save output to disk
        addOutputValidator(ascConfig, multiBuilder);
        addEDMValidator(ascConfig, multiBuilder);

        multiBuilder.addTransformer(new SaveAipToTargetFileTransformer());

        splitter.setChildTransformer(multiBuilder.build());

        this.rootTransformer.setChildTransformer(splitter);

        this.inputSchema = createInputSchema(ascConfig, sipMakerBaseDir, config);
    }

    private void addPreprocessingScripts(String scriptsFolder, File sipMakerBaseDir,
            TransformerListBuilder builder) {

        File preprocessingFolder = new File(getTransformersDir(sipMakerBaseDir), scriptsFolder);
        if (!preprocessingFolder.exists()) {
            throw new AscConfigFailureException("Loading preprocessing scripts failed: Folder '"
                    + preprocessingFolder.getAbsolutePath() + "' does not exist!");
        }

        Collection<File> preprocessingScripts = FileUtils.listFiles(preprocessingFolder, new String[] { "xsl" },
                true);
        Iterator<File> scriptIter = preprocessingScripts.iterator();
        while (scriptIter.hasNext()) {
            AbstractTransformer preprocessTransformer = new AscTransformXSLResolver(preprocessingFolder)
                    .createTransformer(FilenameUtils.removeExtension(scriptIter.next().getName()));
            builder.addTransformer(preprocessTransformer);
        }

    }

    private void addPostprocessingScripts(String scriptsFolder, File sipMakerBaseDir,
            TransformerListBuilder builder) {

        File postprocessingFolder = new File(getTransformersDir(sipMakerBaseDir), scriptsFolder);
        if (!postprocessingFolder.exists()) {
            throw new AscConfigFailureException("Loading postprocessing scripts failed: Folder '"
                    + postprocessingFolder.getAbsolutePath() + "' does not exist!");
        }

        Collection<File> postprocessingScripts = FileUtils.listFiles(postprocessingFolder, new String[] { "xsl" },
                true);
        Iterator<File> scriptIter = postprocessingScripts.iterator();
        while (scriptIter.hasNext()) {
            AbstractTransformer preprocessTransformer = new AscTransformXSLResolver(postprocessingFolder)
                    .createPostprocessingTransformer(FilenameUtils.removeExtension(scriptIter.next().getName()));
            builder.addTransformer(preprocessTransformer);
        }

    }

    private void addOutputValidator(AscConfiguration config, TransformerListBuilder multiBuilder) {
        final String schemaPath = config.get(AscConfiguration.TRANSFORM_VALIDATE_OUTPUT_SCHEMA, "");
        if (StringUtils.isNotBlank(schemaPath)) {
            final File schemaFile = FileInProject.find(schemaPath, "Cortex");
            multiBuilder.addTransformer(new AipSchemaValidator("Output", schemaFile));
        }
    }

    private void addEDMValidator(AscConfiguration config, TransformerListBuilder multiBuilder) {
        final String schemaPath = config.get(AscConfiguration.TRANSFORM_VALIDATE_OUTPUT_SCHEMA_EDM, "");
        if (StringUtils.isNotBlank(schemaPath)) {
            final File schemaFile = FileInProject.find(schemaPath, "Cortex");
            multiBuilder.addTransformer(new EDMSchemaValidator("EDM", schemaFile));
        }
    }

    public static File getTransformersDir(File sipMakerBaseDir) {
        return new File(sipMakerBaseDir, "transformers_edm");
    }

    private Schema createInputSchema(AscConfiguration ascConfig, File sipMakerBaseDir, Properties config) {
        if (ascConfig.get(AscConfiguration.TRNS_VALIDATE_INPUT_SCHEMA_FIXED, false)) {
            final String inputSchemaPath = ascConfig.get(AscConfiguration.FORMAT, "") + File.separator
                    + config.getProperty("inputSchema");

            if (StringUtils.isNotBlank(inputSchemaPath)) {
                File schemaFile = new File(getTransformersDir(sipMakerBaseDir), inputSchemaPath);
                return new SchemaValidator(null, schemaFile).getSchema();
            }
        }

        if (ascConfig.get(AscConfiguration.TRNS_VALIDATE_INPUT_SCHEMA_EMBEDDED, false)) {
            return SchemaValidator.createEmbeddedSchema();
        }

        return null;
    }

    @Override
    public AbstractTransformer getRootTransformer() {
        return this.rootTransformer;
    }

    @Override
    public Schema getInputSchema() {
        return this.inputSchema;
    }
}