de.romankreisel.faktotum.beans.BundesbruderBean.java Source code

Java tutorial

Introduction

Here is the source code for de.romankreisel.faktotum.beans.BundesbruderBean.java

Source

/**
 * This file is part of Faktotum.
 *
 *
 *  Faktotum is free software: you can redistribute it and/or 
 *  modify it under the terms of the GNU Lesser General Public License 
 *  as published by the Free Software Foundation, either version 3 of 
 *  the License, or (at your option) any later version.
 *
 *  Faktotum 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 Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public 
 *  License along with Faktotum.  
 *
 *  If not, see <http://www.gnu.org/licenses/>.
 */
package de.romankreisel.faktotum.beans;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.imageio.ImageIO;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import de.romankreisel.faktotum.beans.CryptBean.AUTHENTICATION_SCHEME;
import de.romankreisel.faktotum.dao.BundesbruderDao;
import de.romankreisel.faktotum.datamodel.BundesbruderEntity;
import de.romankreisel.faktotum.exceptions.FaktotumRuntimeException;
import de.romankreisel.faktotum.exceptions.InvalidPasswordException;

/**
 * @author Roman Kreisel <mail@romankreisel.de>
 * 
 */
@Stateless
public class BundesbruderBean extends FaktotumBean {
    @EJB
    private SettingBean settingBean;

    @EJB
    private CryptBean cryptBean;

    @EJB
    private BundesbruderDao bundesbruderDao;

    /**
     * Encrypts a password and stores it for a BundesbruderEntity.
     * 
     * @param bundesbruderEntity
     *            The Bundesbruder to have the new password set
     * @param password
     *            the password to be hashed and stored
     * @throws InvalidPasswordException
     *             If the password is not valid and must not be used
     */
    public void encryptAndSetPassword(BundesbruderEntity bundesbruderEntity, String password)
            throws InvalidPasswordException {
        AUTHENTICATION_SCHEME authenticationScheme = (AUTHENTICATION_SCHEME) this.settingBean
                .getEnumSettingValue(SettingBean.SETTING_STRING_AUTH_SCHEME);
        if (password.isEmpty()) {
            throw new InvalidPasswordException("Empty password not allowed, reset user to disable access!");
        }
        String passwordToken = this.cryptBean.crypt(password, authenticationScheme);
        if (StringUtils.isEmpty(passwordToken)) {
            throw new FaktotumRuntimeException("Error generating token for password!");
        }
        bundesbruderEntity.setPassword(passwordToken);
    }

    /**
     * @return
     */
    public Long getBundesbruderCount() {
        return this.bundesbruderDao.getCount(BundesbruderEntity.class);
    }

    public BufferedImage getImageFromByteArray(byte[] array) throws IOException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(array);
        BufferedImage originalImage = ImageIO.read(byteArrayInputStream);
        byteArrayInputStream.close();
        return originalImage;
    }

    public BufferedImage getImageFromByteArray(Byte[] array) throws IOException {
        byte[] primitiveArray = ArrayUtils.toPrimitive(array);
        return this.getImageFromByteArray(primitiveArray);
    }

    /**
     * Calculates the size of a downscaled image, keeping the aspect ratio
     * http:/
     * /stackoverflow.com/questions/10245220/java-image-resize-maintain-aspect
     * -ratio
     * 
     * @param imageSize
     * @param boundary
     * @return the scaled dimension
     */
    private Dimension getScaledDimension(Dimension imageSize, Dimension boundary) {
        int originalWidth = imageSize.width;
        int originalHeight = imageSize.height;
        int bound_width = boundary.width;
        int bound_height = boundary.height;
        int newWidth = originalWidth;
        int newWeight = originalHeight;

        // first check if we need to scale width
        if (originalWidth > bound_width) {
            // scale width to fit
            newWidth = bound_width;
            // scale height to maintain aspect ratio
            newWeight = newWidth * originalHeight / originalWidth;
        }

        // then check if we need to scale even with the new height
        if (newWeight > bound_height) {
            // scale height to fit instead
            newWeight = bound_height;
            // scale width to maintain aspect ratio
            newWidth = newWeight * originalWidth / originalHeight;
        }

        return new Dimension(newWidth, newWeight);
    }

    /**
     * @param originalPicture
     * @param pictureHeight
     * @param pictureWidth
     * @return
     * @throws IOException
     */
    public Byte[] resizeProfilePicture(Byte[] originalPicture, int width, int height) throws IOException {
        BufferedImage originalImage = this.getImageFromByteArray(originalPicture);
        Dimension newDimension = this.getScaledDimension(
                new Dimension(originalImage.getWidth(), originalImage.getHeight()), new Dimension(width, height));
        Image scaledImage = originalImage.getScaledInstance(newDimension.width, newDimension.height,
                Image.SCALE_SMOOTH);
        return this.storeImageToByteArray(scaledImage);
    }

    public void rotateProfilePictureClockwise(BundesbruderEntity bundesbruder, double angle) throws IOException {
        BufferedImage image = this.getImageFromByteArray(bundesbruder.getPictureOriginal());
        double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
        int w = image.getWidth(), h = image.getHeight();
        int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math.floor(h * cos + w * sin);
        GraphicsConfiguration gc = image.createGraphics().getDeviceConfiguration();
        BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
        Graphics2D g = result.createGraphics();
        g.translate((neww - w) / 2, (newh - h) / 2);
        g.rotate(angle, w / 2, h / 2);
        g.drawRenderedImage(image, null);
        g.dispose();
        this.setProfilePicture(bundesbruder, this.storeImageToByteArray(image));
    }

    public void setProfilePicture(BundesbruderEntity bundesbruder, Byte[] originalPicture) throws IOException {
        // TODO: configurable?
        int pictureHeight = 300;
        int pictureWidth = 200;
        int thumbnailHeight = 60;
        int thumbnailWidth = 40;

        Byte[] picture = this.resizeProfilePicture(originalPicture, pictureHeight, pictureWidth);
        Byte[] thumbnail = this.resizeProfilePicture(originalPicture, thumbnailHeight, thumbnailWidth);
        bundesbruder.setPictureOriginal(originalPicture);
        bundesbruder.setPicture(picture);
        bundesbruder.setPictureThumbnail(thumbnail);
    }

    private Byte[] storeImageToByteArray(Image image) throws IOException {
        if (!(image instanceof RenderedImage)) {
            BufferedImage newImage = new BufferedImage(image.getWidth(null), image.getHeight(null),
                    BufferedImage.TYPE_INT_RGB);
            newImage.getGraphics().drawImage(image, 0, 0, null);
            image = newImage;
        }
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write((RenderedImage) image, "jpg", byteArrayOutputStream);
        byteArrayOutputStream.flush();
        byte[] imageInByte = byteArrayOutputStream.toByteArray();
        byteArrayOutputStream.close();
        return ArrayUtils.toObject(imageInByte);
    }
}