Package com.rf1m.image2css.cmn.service

Source Code of com.rf1m.image2css.cmn.service.DefaultImageConversionService

/**
*
* Copyright (c) 2011 Matthew D Huckaby. All rights reservered.
* ------------------------------------------------------------------------------------
* Image2Css is licensed under Apache 2.0, please see LICENSE file.
*
* Use of this software indicates you agree to the following as well :
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
* ------------------------------------------------------------------------------------
*/
package com.rf1m.image2css.cmn.service;

import com.rf1m.image2css.domain.CssClass;
import com.rf1m.image2css.domain.SupportedImageType;
import com.rf1m.image2css.exception.Errors;
import com.rf1m.image2css.ioc.CommonObjectFactory;
import com.rf1m.image2css.cmn.util.bin.Base64Encoder;
import com.rf1m.image2css.cmn.util.file.FileUtils;
import org.apache.commons.lang3.tuple.Pair;

import javax.swing.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

import static com.rf1m.image2css.exception.Errors.*;
import static java.lang.String.format;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang3.StringUtils.*;

public class DefaultImageConversionService implements ImageConversionService {
    protected static final String underscore = "_";
    protected static final String http = "http://";

    protected final FileUtils fileUtils;
    protected final Base64Encoder base64Encoder;
    protected final CommonObjectFactory commonObjectFactory;
    protected final String cssClassTemplate;

    public DefaultImageConversionService(final FileUtils fileUtils,
                                         final Base64Encoder base64Encoder,
                                         final CommonObjectFactory commonObjectFactory,
                                         final String cssClassTemplate) {
        this.fileUtils = fileUtils;
        this.base64Encoder = base64Encoder;
        this.commonObjectFactory = commonObjectFactory;
        this.cssClassTemplate = cssClassTemplate;
    }

    @Override
    public CssClass convert(final File imageFile) {
        this.validateFile(imageFile);
        final Pair<String, String> validatedFilenameAndExtension = this.validateFilenameAndExtension(imageFile);
        final String cssClassName = this.determineCssClassName(validatedFilenameAndExtension.getLeft());
        final byte[] bytes = this.getFileBytes(imageFile);
        final String base64Bytes = this.base64Encoder.base64EncodeBytes(bytes);
        final Pair<Integer, Integer> dimension = this.getImageDimension(bytes);
        final String cssEntry = this.determineCssEntry(cssClassName, validatedFilenameAndExtension.getRight(), base64Bytes, dimension);
        final CssClass cssClass = this.commonObjectFactory.newCssClass(cssClassName, cssEntry);

        return cssClass;
    }

    @Override
    public CssClass convert(final URL url) {
        this.validateUrl(url);
        final Pair<String, String> validatedFilenameAndExtension = this.validateFilenameAndExtension(url);
        final String determinedCssClassName = this.determineCssClassName(validatedFilenameAndExtension.getLeft());
        final BufferedInputStream bufferedInputStream = this.commonObjectFactory.newBufferedInputStream(url);
        final byte[] bytes = this.readInputStreamToBytes(bufferedInputStream);
        final String base64Bytes = this.base64Encoder.base64EncodeBytes(bytes);
        final Pair<Integer, Integer> dimension = this.getImageDimension(bytes);
        final String cssEntry = this.determineCssEntry(determinedCssClassName, validatedFilenameAndExtension.getRight(), base64Bytes, dimension);
        final CssClass cssClass = this.commonObjectFactory.newCssClass(determinedCssClassName, cssEntry);

        return cssClass;
    }

    @Override
    public CssClass convertUrlAsString(final String urlAsString) {
        if(isEmpty(urlAsString)) {
            throw this.commonObjectFactory.newImage2CssValidationException(parameterUrlCannotBeEmpty);
        }

        final String urlStringWithProtocol = startsWith(urlAsString.toLowerCase(), http) ?
                urlAsString : this.commonObjectFactory.newStringBuilder(http).append(urlAsString).toString();

        final URL url = this.commonObjectFactory.newUrl(urlStringWithProtocol);

        return this.convert(url);
    }

    protected String determineCssEntry(final String cssClassName,
                                       final String fileExtension,
                                       final String base64Bytes,
                                       final Pair<Integer, Integer> dimension) {
        return format(cssClassTemplate, cssClassName, fileExtension, base64Bytes, dimension.getLeft(), dimension.getRight());
    }

    protected String determineCssClassName(final String fileName) {
        final String candidate =
            fileName
                .replaceAll("\\.", underscore)
                .replaceAll("\\\\", underscore)
                .replaceAll("/", underscore);

        return isNotEmpty(candidate) ? candidate : randomAlphabetic(7);
    }

    /**
     * Return the dimension of an image represented by a byte array.
     * @param bytes
     * @return Pair with left as width and right as height.
     */
    protected Pair<Integer, Integer> getImageDimension(final byte[] bytes){
        final ImageIcon imageIcon = this.commonObjectFactory.newImageIcon(bytes);
        final Pair<Integer, Integer> result =
            this.commonObjectFactory.newPair(imageIcon.getIconWidth(), imageIcon.getIconHeight());

        return result;
    }

    /**
     * Read the bytes of a file into a byte array and return the array.
     * @param file
     * @return
     * @throws Exception
     */
    protected byte[] getFileBytes(final File file) {
        final FileInputStream fileInputStream = this.commonObjectFactory.newFileInputStream(file);
        final byte[] bytes = this.commonObjectFactory.newByteArray(file.length());

        try {
            fileInputStream.read(bytes);
        }catch(final IOException ioException) {
            throw this.commonObjectFactory.newImage2CssException(ioException, Errors.errorReadingFile);
        }finally {
            try {
                fileInputStream.close();
            }catch(final Exception exception) {
                throw this.commonObjectFactory.newImage2CssException(exception, Errors.errorClosingFile);
            }
        }

        return bytes;
    }

    protected void validateFile(final File file) {
        if(null == file) {
            throw this.commonObjectFactory.newImage2CssValidationException(parameterFileCannotBeNull);
        }
    }

    protected Pair<String, String> validateFilenameAndExtension(final File file) {
        final String imageFilename = file.getName();
        final String fileExtension = this.fileUtils.getExtension(imageFilename);

        if(!SupportedImageType.isSupportedImageType(fileExtension)){
            throw this.commonObjectFactory.newImage2CssValidationException(parameterUnsupportedImageType);
        }

        return this.commonObjectFactory.newPair(imageFilename, fileExtension);
    }

    protected Pair<String, String> validateFilenameAndExtension(final URL url) {
        final String imageFilename = url.getFile();

        if(isEmpty(imageFilename)) {
            throw this.commonObjectFactory.newImage2CssValidationException(parameterCannotDetermineFilenameFromUrl);
        }

        final String fileExtension = this.fileUtils.getExtension(imageFilename);

        if(isEmpty(fileExtension)) {
            throw this.commonObjectFactory.newImage2CssValidationException(parameterUrlCannotBeEmpty);
        }else if(!SupportedImageType.isSupportedImageType(fileExtension)){
            throw this.commonObjectFactory.newImage2CssValidationException(parameterUnsupportedImageType);
        }

        return this.commonObjectFactory.newPair(imageFilename, fileExtension);
    }

    protected void validateUrl(final URL url) {
        if(null == url) {
            throw this.commonObjectFactory.newImage2CssValidationException(parameterUrlCannotBeEmpty);
        }

        try {
            final HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
            httpURLConnection.setRequestMethod("HEAD");
            httpURLConnection.connect();
            if(200 != httpURLConnection.getResponseCode()) {
                throw this.commonObjectFactory.newImage2CssValidationException(parameterUrlDidNotResolveToAnImageResource);
            }
        }catch(final IOException e) {
            throw this.commonObjectFactory.newImage2CssValidationException(e, parameterUrlDidNotResolveToAnImageResource);
        }
    }

    protected byte[] readInputStreamToBytes(final BufferedInputStream bufferedInputStream) {
        final ByteArrayOutputStream byteArrayOutputStream = this.commonObjectFactory.newByteArrayOutputStream();
        final byte[] buffer = this.commonObjectFactory.newByteArray(1);

        try {
            int len;
            while((len = bufferedInputStream.read(buffer)) > 0) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            return byteArrayOutputStream.toByteArray();
        }catch(final IOException e) {
            throw this.commonObjectFactory.newImage2CssException(e, errorOpeningStream);
        }
    }

}
TOP

Related Classes of com.rf1m.image2css.cmn.service.DefaultImageConversionService

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.