Package de.innovationgate.wgpublisher

Source Code of de.innovationgate.wgpublisher.PublishingFile

/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

package de.innovationgate.wgpublisher;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.activation.DataSource;

import de.innovationgate.utils.ImageScaler;
import de.innovationgate.utils.MimeTypeSpecificImageScaler;
import de.innovationgate.utils.io.IOBackendException;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGBackendException;
import de.innovationgate.webgate.api.WGDocument;
import de.innovationgate.webgate.api.WGFileContainer;
import de.innovationgate.webgate.api.WGNotSupportedException;
import de.innovationgate.wga.config.WGAConfiguration;
import de.innovationgate.wga.modules.ModuleInstantiationException;
import de.innovationgate.wgpublisher.webtml.utils.ImageScalerFactory;

public class PublishingFile implements DataSource {

    private final WGPDispatcher _dispatcher;

    private boolean _zipped = false;
    private WGDocument _container;

    private String _fileName;

    private String _zippedFileName;

    private ZipEntry _zipEntry;

    private ZipInputStream _zipStream;

    private boolean _publishable = true;

    private boolean _streamRetrieved = false;
   
    private int _scaleMaxHeight = -1;
    private int _scaleMaxWidth = -1;
    private byte[] _scaledVersion = null;

    private MimeTypeSpecificImageScaler _scaler = null;

    private String _mimeType;

    public PublishingFile(WGPDispatcher wgpDispatcher, WGDocument container, String fileName) throws WGAPIException {
        _dispatcher = wgpDispatcher;
        _container = container;
        _fileName = fileName;
       
        // If the filename contains slashes we must address a file inside a
        // zip file
        int firstSlashIndex = fileName.indexOf("/");
        if (firstSlashIndex != -1) {
            String zipFileCandidate = fileName.substring(0, firstSlashIndex);
            if (hasZipFileSuffix(zipFileCandidate) && _container.hasFile(zipFileCandidate)) {
                _zippedFileName = fileName.substring(firstSlashIndex + 1);
                _fileName = zipFileCandidate;
                _zipped = true;
            }
        }

        // We do not want to publish files from the system file container.
        // They are the WGA pendant of J2EE's "WEB-INF" directory which is
        // also unpublished.
        if (container instanceof WGFileContainer) {
            WGFileContainer fc = (WGFileContainer) container;
            if (fc.getName().equals("system")) {
                _publishable = false;
            }
        }
    }
   
    public long getLastModifiedTime() throws WGAPIException {
        return _container.getFileLastModified(_fileName).getTime();
    }

    private void retrieveZipInputStream() throws WGAPIException {

        if (_streamRetrieved) {
            return;
        }

        InputStream in = _container.getFileData(_fileName);
        _zipStream = new ZipInputStream(in);
        _zipEntry = moveStreamToFile(_zipStream);
        if (_zipEntry == null) {
            try {
                _zipStream.close();
            }
            catch (IOException e) {
                _dispatcher.getCore().getLog().error("Error closing zip stream", e);
            }
            _zipStream = null;
        }
        _streamRetrieved = true;

    }

    private boolean hasZipFileSuffix(String zipFileCandidate) {

        zipFileCandidate = zipFileCandidate.toLowerCase();
        return (zipFileCandidate.endsWith(".zip") || zipFileCandidate.endsWith(".jar"));

    }

    /**
     * @return Returns the container.
     */
    public WGDocument getContainer() {
        return _container;
    }

    /**
     * @return Returns the fileName.
     */
    public String getFileName() {
        return _fileName;
    }

    /**
     * @return Returns the zipped.
     */
    public boolean isZipped() {
        return _zipped;
    }

    /**
     * @return Returns the zippedFileName.
     */
    public String getZippedFileName() {
        return _zippedFileName;
    }

    public long getFileSize() throws WGAPIException {

        if (isScaled()) {
            byte[] bytes;
            try {
                bytes = getScaledVersion();
                return bytes.length;
            }
            catch (Exception e) {
                throw new WGBackendException("Exception determining scaled file size on " + getCachingKey(), e);
            }
        }
       
        if (isZipped()) {
            retrieveZipInputStream();
            if (_zipEntry != null) {
                return _zipEntry.getSize();
            }
            else {
                return -1;
            }
        }
        else {
            return _container.getFileSize(_fileName);
        }

    }

    public InputStream getInputStream() throws IOException {

       
        try {
            if (isScaled()) {
                return new ByteArrayInputStream(getScaledVersion());
            }
            else {
                return innerGetInputStream();
            }
           
        }
        catch (WGAPIException e) {
            throw new IOBackendException("Exception serving file input stream", e);
        }
        catch (ModuleInstantiationException e) {
            throw new IOBackendException("Exception scaling file", e);
        }

    }

    private InputStream innerGetInputStream() throws WGAPIException {
        InputStream stream;
       
        if (isZipped()) {
            retrieveZipInputStream();
            stream = _zipStream;
        }
        else {
            stream = _container.getFileData(_fileName);
        }
       
        return stream;
    }

    private ZipEntry moveStreamToFile(ZipInputStream in) {

        try {
            ZipEntry entry;
            do {
                entry = in.getNextEntry();
            } while (entry != null && !entry.getName().equals(getZippedFileName()));

            return entry;
        }
        catch (IOException e) {
            _dispatcher.getCore().getLog().error("Error reading zip file entry", e);
            return null;
        }
    }

    public boolean isPublishable() {
        return _publishable;
    }

    public String getName() {
        if (isZipped()) {
            return getZippedFileName() + " in archive '" + getFileName() + "' on document " + _container.getDocumentKey();
        } else {
            return getFileName() + " on document " + _container.getDocumentKey();
        }
    }

    public String getContentType() {
        return _dispatcher.getServletContext().getMimeType(_fileName);
    }

    public OutputStream getOutputStream() throws IOException {
        throw new IOException("Not supported");
    }

    public boolean isScaled() {
        return _scaler != null;
    }
   
    public String getCachingKey() {
       
        StringBuffer key = new StringBuffer();
        key.append(_container.getDocumentKey());
        key.append("/");
        key.append(_fileName);
       
        if (_zippedFileName != null) {
            key.append("/").append(_zippedFileName);
        }
       
        if (_scaler != null) {
            key.append("//");
            key.append(_scaleMaxWidth + "x" + _scaleMaxHeight);
        }
        return key.toString();
       
    }

    public int getScaleMaxHeight() {
        return _scaleMaxHeight;
    }

    public void setScaleMaxHeight(int scaleMaxHeight) throws WGAPIException {
        _scaleMaxHeight = scaleMaxHeight;
        prepareScaler();
    }

    private void prepareScaler() throws WGAPIException {
       
        // Scaler already prepared?
        if (_scaler != null) {
            return;
        }
       
        // File size below threshold?
        int scalingThreshold = (Integer) _dispatcher._variousServerOptionReader.readOptionValueOrDefault(WGACore.SERVEROPTION_SERVER_SCALINGTHRESHOLD);
        long thresholdBytes = scalingThreshold * 1024 * 1024;
        long fileSize = getFileSize(); // Works here normally since the scaler is not yet prepared
        if (thresholdBytes < fileSize) {
            return;
        }
       
        // Find out the mime type, must be an image
        if (_mimeType == null) {
            _mimeType = _dispatcher.getServletContext().getMimeType(_fileName);
        }
        if (!_mimeType.startsWith("image/")) {
            return;
        }
       
        // Find out about the max size threshold
        WGAConfiguration wgaConfig = _dispatcher.getCore().getWgaConfiguration();
        //wgaConfig.getOptionReader(wgaConfig.getServerOptions(), new Var)
       
        // Try to allocate a scaler
        try {
             _scaler = ImageScalerFactory.createMimeTypeSpecificImageScaler(_dispatcher.getCore(), _mimeType);
        }
        catch (WGNotSupportedException e) {
            // Fail silently here. This is the case when no scaler for this type is installed
        }
        catch (Exception e) {
            throw new WGBackendException("Exception creating scaler", e);
        }
    }

    public int getScaleMaxWidth() {
        return _scaleMaxWidth;
    }

    public void setScaleMaxWidth(int scaleMaxWidth) throws WGAPIException {
        _scaleMaxWidth = scaleMaxWidth;
        prepareScaler();
    }
   
    private byte[] getScaledVersion() throws WGAPIException, IOException, ModuleInstantiationException {
       
        if (_scaledVersion == null && _scaler != null) {
            _scaler.load(innerGetInputStream(), _mimeType);
            int maxHeight = (_scaleMaxHeight != -1 ? _scaleMaxHeight : Integer.MAX_VALUE);
            int maxWidth = (_scaleMaxWidth != -1 ? _scaleMaxWidth : Integer.MAX_VALUE);
            _scaler.shrinkToSize(maxWidth, maxHeight);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            _scaler.writeImage(out);
            _scaledVersion = out.toByteArray();
        }
        return _scaledVersion;
           
       
    }


}
TOP

Related Classes of de.innovationgate.wgpublisher.PublishingFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.