de.fhg.iais.asc.xslt.binaries.DownloadAndScaleContext.java Source code

Java tutorial

Introduction

Here is the source code for de.fhg.iais.asc.xslt.binaries.DownloadAndScaleContext.java

Source

package de.fhg.iais.asc.xslt.binaries;

/******************************************************************************
 * 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.net.URI;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;

import de.fhg.iais.asc.commons.AscConfiguration;
import de.fhg.iais.asc.commons.exceptions.AscConfigFailureException;
import de.fhg.iais.asc.commons.exceptions.AscTechnicalErrorException;
import de.fhg.iais.asc.transformer.TransformationContext;
import de.fhg.iais.asc.xslt.binaries.download.BinaryDownloadMode;
import de.fhg.iais.asc.xslt.binaries.download.Downloader;
import de.fhg.iais.asc.xslt.binaries.scale.BinaryScaleMode;
import de.fhg.iais.asc.xslt.binaries.scale.ImageMagickScaler;
import de.fhg.iais.asc.xslt.binaries.scale.conf.PreviewImageType;
import de.fhg.iais.asc.xslt.binaries.util.PatternCache;
import de.fhg.iais.commons.annotation.OnlyCalledFromTests;

public class DownloadAndScaleContext {
    static final String CTXKEY_DOWNLOAD_MODE = "transform.download_binaries.mode";
    static final String CTXKEY_REDOWNLOAD = "transform.download_binaries.redownloadExisting";
    static final String PARAMNAME_DOWNLOAD_MODE = "download_type";
    static final String PARAMNAME_REDOWNLOAD = "download_redownload_existing";

    static final String CTXKEY_SCALE_MODE = "transform.scale_images.mode";

    static final String PARAMNAME_PREVIEW_TYPES_INCLUDE = "preview_types_include";
    static final String PARAMNAME_PREVIEW_TYPES_EXCLUDE = "preview_types_exclude";
    static final String CTXKEY_PREVIEW_TYPES_INCLUDE = "transform.scale_images.types.include";
    static final String CTXKEY_PREVIEW_TYPES_EXCLUDE = "transform.scale_images.types.exclude";

    static final String CTXKEY_PATH_CONVERT = "convert_location";

    private static final String NULL_STRING = null;

    private final TransformationContext transContext;
    protected final AscConfiguration ascContext;
    protected final File binaryRoot;
    protected final Map<String, String> parameters;

    protected final BinaryDownloadMode downloadMode;
    protected final boolean redownloadExisting;
    protected final BinaryScaleMode scaleMode;

    private ImageMagickScaler scaler;

    public DownloadAndScaleContext(TransformationContext transContext, File binaryRoot,
            Map<String, String> parameters) {
        this.transContext = transContext;
        this.ascContext = transContext.getConfig();
        this.binaryRoot = binaryRoot;
        this.parameters = parameters;

        try {
            this.downloadMode = BinaryDownloadMode.valueOf(this.ascContext.get(CTXKEY_DOWNLOAD_MODE, NULL_STRING));
        } catch (Exception e) {
            final String message = "Illegal value in key \"" + CTXKEY_DOWNLOAD_MODE + "\"";
            throw new AscConfigFailureException(message, e);
        }

        this.redownloadExisting = this.ascContext.get(CTXKEY_REDOWNLOAD, false);

        try {
            this.scaleMode = BinaryScaleMode.valueOf(this.ascContext.get(CTXKEY_SCALE_MODE, NULL_STRING));
        } catch (Exception e) {
            final String message = "Illegal value in key \"" + CTXKEY_SCALE_MODE + "\"";
            throw new AscConfigFailureException(message, e);
        }
    }

    public File getBinaryRoot() {
        return this.binaryRoot;
    }

    public boolean isTypeAllowed(String typeName) {
        return checkIncludeExcludeConstraints(typeName);
    }

    private boolean checkIncludeExcludeConstraints(String typeName) {
        if (match(typeName, this.parameters.get(PARAMNAME_PREVIEW_TYPES_EXCLUDE))) {
            return false;
        }

        if (match(typeName, this.parameters.get(PARAMNAME_PREVIEW_TYPES_INCLUDE))) {
            return true;
        }

        if (match(typeName, this.ascContext.get(CTXKEY_PREVIEW_TYPES_EXCLUDE, NULL_STRING))) {
            return false;
        }

        return match(typeName, this.ascContext.get(CTXKEY_PREVIEW_TYPES_INCLUDE, NULL_STRING));
    }

    private static boolean match(String name, String patternStr) {
        if (StringUtils.isEmpty(patternStr)) {
            return false;
        }

        Pattern pattern = PatternCache.get(patternStr);
        return pattern.matcher(name).matches();
    }

    public File downloadFile(URI uri, File permanentOriginal, boolean onlyPermanent) {
        final Boolean permanentDownload = getDownloadMode().getPermanentDownload();
        if (permanentDownload == null) {
            return null;
        }

        final boolean isPermanent = permanentDownload.booleanValue();
        if (onlyPermanent && !isPermanent) {
            return null;
        }

        final File target = isPermanent ? permanentOriginal : createTempFile(uri);

        if (shouldRedownloadExisting() || !isValidBinaryFile(target)) {
            Downloader.forContext(this.transContext).downloadBinary(uri, target);
        }
        return target;
    }

    private BinaryDownloadMode getDownloadMode() {
        final String modeString = this.parameters.get(PARAMNAME_DOWNLOAD_MODE);
        if (StringUtils.isNotEmpty(modeString)) {
            try {
                return BinaryDownloadMode.valueOf(modeString);
            } catch (Exception e) {
                final String message = "Illegal value for binary XSL parameter \"" + PARAMNAME_DOWNLOAD_MODE + "\"";
                throw AscTechnicalErrorException.wrap(message, e);
            }
        }

        return this.downloadMode;
    }

    private File createTempFile(URI uri) {
        return new File(this.binaryRoot, ".temp/" + Downloader.createPathFromURI(uri));
    }

    private boolean shouldRedownloadExisting() {
        final String value = this.parameters.get(PARAMNAME_REDOWNLOAD);
        if (StringUtils.isNotBlank(value)) {
            return Boolean.parseBoolean(value);
        }

        return this.redownloadExisting;
    }

    public boolean isAnyScaleAllowed() {
        return this.scaleMode != BinaryScaleMode.none;
    }

    public boolean createScaled(File original, String relativePath, PreviewImageType previewType, String mimetype) {
        if (this.scaler == null) {
            String convertPath = this.ascContext.get(CTXKEY_PATH_CONVERT, NULL_STRING);
            this.scaler = new ImageMagickScaler(convertPath);
        }

        File target = new File(this.binaryRoot, relativePath);
        boolean targetExists = target.exists();
        if (!this.scaleMode.shouldScale(targetExists)) {
            return targetExists;
        }

        return this.scaler.scale(original, target, previewType, mimetype);
    }

    private boolean isValidBinaryFile(File fileToCheck) {
        if (!fileToCheck.isFile()) {
            return false;
        }

        if (fileToCheck.length() < 1) {
            return false;
        }

        return true;
    }

    @OnlyCalledFromTests
    // because it is only for tests
    void setScaler(ImageMagickScaler scaler) {
        this.scaler = scaler;
    }
}