eu.inn.biosign.BioSign.java Source code

Java tutorial

Introduction

Here is the source code for eu.inn.biosign.BioSign.java

Source

package eu.inn.biosign;

/*
 * #%L
 * Java Applet for biometric trait acquisition [http://www.biosignin.org]
 * BioSign.java is part of BioSignIn project
 * %%
 * Copyright (C) 2014 Innovery SpA
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.bouncycastle.util.encoders.Base64;

import eu.inn.biometric.signature.managed.ManagedIsoPoint;
import eu.inn.biometric.signature.renderer.ImageRenderer;
import eu.inn.biosign.device.BaseDeviceHandler;
import eu.inn.biosign.device.SignatureBean;
import eu.inn.biosign.device.config.DeviceConfig;
import eu.inn.biosign.device.config.DeviceConfig.ImageBean;
import eu.inn.biosign.device.impl.DummyHandlerImpl;
import eu.inn.biosign.device.impl.MouseHandlerImpl;
import eu.inn.biosign.device.sp.DeviceHandlerServiceProvider;
import eu.inn.biosign.listener.IDeviceListener;
import eu.inn.configuration.Device;
import eu.inn.configuration.ManagedIsoPointSimulated;
import eu.inn.signature.Signature;

public class BioSign extends JPanel implements MouseListener, MouseMotionListener {

    @Override
    public void mouseClicked(MouseEvent e) {
        System.out.println("clicked");
        genericMouseEvent(e);
        // TODO Auto-generated method stub

    }

    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println("pressed");
        genericMouseEvent(e);
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        System.out.println("released");
        genericMouseEvent(e);
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseEntered(MouseEvent e) {
        System.out.println("entered");
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseExited(MouseEvent e) {
        System.out.println("exited");
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseDragged(MouseEvent e) {
        //      System.out.println("dragged");
        genericMouseEvent(e);
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        //      System.out.println("moved");
        genericMouseEvent(e);

    }

    int lastPressure = 0;

    private void genericMouseEvent(MouseEvent e) {
        if (tablet.getDeviceConfig().isAirModeSupported()) {
            int pressure = (e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) == 0 ? 0 : 1;
            //         System.out.println("Pressure: "+pressure);
            if (lastPressure == 0 && pressure > 0)
                tablet.resetLastPoint();
            //            t.lastPoint=null;//new PointWithPressureAndTime(Math.round(e.getX()/scale), Math.round(e.getY()/scale),pressure );
            //            t.PenPressed(new PointWithPressureAndTime(Math.round(e.getX()/scale), Math.round(e.getY()/scale),0 ), false);

            if (lastPressure > 0 || pressure > 0)
                tablet.penPressedSimulated(new ManagedIsoPointSimulated(Math.round(e.getX() / scale),
                        Math.round(e.getY() / scale), pressure, true, 1, 1));
            lastPressure = pressure;
        }
    }

    public static BioSign _instance = null;

    private static final long serialVersionUID = 1L;

    private static float scale = 0.5f;

    // size of the tablets
    // private static final int STU520_WIDTH = 800;
    // private static final int STU520_HEIGHT = 480;

    public enum Button {
        OK, CLEAR, CANCEL, AIRMODE, NEXT, PREV
    }

    private ArrayList<ManagedIsoPoint> scalePoints = new ArrayList<ManagedIsoPoint>();

    public void clearScaledPoints() {
        scalePoints.clear();
    }

    public boolean addScaledPoint(ManagedIsoPoint p) {
        return addScaledPoint(p, false);
    }

    boolean lastInside = false;

    public boolean addScaledPoint(ManagedIsoPoint pOrig, boolean excludeScale) {
        ManagedIsoPoint p = new ManagedIsoPoint(pOrig.getX(), pOrig.getY(), pOrig.getPressure());
        Point point = new Point((int) Math.round(p.getX()), (int) Math.round(p.getY()));
        Rectangle rect = null;
        if (DeviceConfig.getSignatureArea() == null) {
            rect = tablet.getDeviceConfig().getActiveAreaForBackground();
        } else {

            //         point.translate(-tablet.getDeviceConfig().getActiveAreaForBackground().x, -tablet.getDeviceConfig().getActiveAreaForBackground().y);
            rect = DeviceConfig.getSignatureArea();
        }
        if (rect == null || rect.contains(point)) {
            lastInside = true;
            //      new Point(Math.round(p.x), (int) Math.round(p.y)))) {
            if (!excludeScale) {
                p.setX(Math.round(p.getX() * scale));
                p.setY(Math.round(p.getY() * scale));
                //            p.setLocation(p.getX()*scale, p.getY()*scale);

            }
            scalePoints.add(p);
            repaint();
            return true;
        } else {
            if (lastInside) {
                scalePoints.add(new ManagedIsoPoint(0, 0, 0));
                pOrig.setPressure(0);
                lastInside = false;
                return true;
            }

            lastInside = false;
        }
        return false;
    }

    @Override
    public void paint(Graphics g) {
        System.out.println("BioSign Paint");
        super.paint(g);
        //      bkImage = justButtons.getScaledInstance(
        //            Math.round(allInOne.getWidth() * scale),
        //            Math.round(allInOne.getHeight() * scale),
        //            Image.SCALE_SMOOTH);

        if (bkImage != null)

        {
            if (tablet != null && tablet.getDeviceConfig() != null) {
                DeviceConfig config = tablet.getDeviceConfig();
                Image scaledImage = config.getScaledImage(scale);
                if (scaledImage != null) {
                    //               BufferedImage image = config.getImageBean().getScaledImage(scale);
                    //               Image bi = image.getScaledInstance(Math.round(image.getWidth()*scale), Math.round(image.getHeight()*scale), BufferedImage.SCALE_DEFAULT);
                    g.drawImage(scaledImage, Math.round(
                            (-config.getImageBean().getOffset().x + config.getActiveAreaForBackground().x) * scale),
                            Math.round(
                                    (-config.getImageBean().getOffset().y + config.getActiveAreaForBackground().y)
                                            * scale),
                            null);

                }

            }
            g.drawImage(bkImage, 0, 0, null);
            if (tablet != null && tablet.getDeviceConfig() != null) {
                DeviceConfig config = tablet.getDeviceConfig();
                Graphics2D g2d = (Graphics2D) g;

                boolean isAirModeEnabled = true;
                boolean isAirModeActive = tablet.getDeviceConfig().isAirModeSupported() && tablet.isAirModeActive();
                g.setColor(new Color(88, 88, 88, 130));
                if (isAirModeEnabled && isAirModeActive) {
                    if (config.getOkButton() != null)
                        g2d.fill(new Rectangle2D.Float(config.getOkButton().x * scale,
                                config.getOkButton().y * scale, config.getOkButton().width * scale,
                                config.getOkButton().height * scale));

                    if (config.getRetryButton() != null)
                        g2d.fill(new Rectangle2D.Float(config.getRetryButton().x * scale,
                                config.getRetryButton().y * scale, config.getRetryButton().width * scale,
                                config.getRetryButton().height * scale));

                } else {
                    g.setColor(Color.black);
                    Stroke orig = g2d.getStroke();
                    g2d.setStroke(new BasicStroke(1.5f));//
                    Rectangle sigArea = DeviceConfig.getSignatureArea();
                    if (sigArea != null)
                        g2d.draw(new Rectangle2D.Float(sigArea.x * scale, sigArea.y * scale, sigArea.width * scale,
                                sigArea.height * scale));
                    g.setColor(new Color(88, 88, 88, 130));
                    g2d.setStroke(orig);
                }
                //            if (config.getCancelButton()!=null)
                //               g2d.fill(new Rectangle2D.Float(config.getCancelButton().x*scale, config.getCancelButton().y*scale, config.getCancelButton().width*scale, config.getCancelButton().height*scale));

                //            else {
                if (config.getNextButton() != null
                        && (!isAirModeActive || tablet.getDeviceConfig().actualPage == totalPage))
                    g2d.fill(new Rectangle2D.Float(config.getNextButton().x * scale,
                            config.getNextButton().y * scale, config.getNextButton().width * scale,
                            config.getNextButton().height * scale));
                if (config.getPrevButton() != null
                        && (!isAirModeActive || tablet.getDeviceConfig().actualPage == 1))
                    g2d.fill(new Rectangle2D.Float(config.getPrevButton().x * scale,
                            config.getPrevButton().y * scale, config.getPrevButton().width * scale,
                            config.getPrevButton().height * scale));
                //            }

                if (!isAirModeEnabled && config.getAirModeButton() != null) {
                    g2d.fill(new Rectangle2D.Float(config.getAirModeButton().x * scale,
                            config.getAirModeButton().y * scale, config.getAirModeButton().width * scale,
                            config.getAirModeButton().height * scale));
                }
                if (isAirModeActive) {
                    g2d.setStroke(new BasicStroke(2));
                    g.setColor(Color.GREEN);
                    g2d.draw(new Rectangle2D.Float(config.getAirModeButton().x * scale,
                            config.getAirModeButton().y * scale, config.getAirModeButton().width * scale,
                            config.getAirModeButton().height * scale));
                }
                if (config.pagesRectangle != null) {
                    String testo = "Pagina " + BioSign._instance.tablet.getDeviceConfig().actualPage + "/"
                            + BioSign._instance.totalPage;
                    g.drawImage(
                            ImageUtils.getImageFromText(testo,
                                    new Dimension(Math.round(config.pagesRectangle.width * scale),
                                            Math.round(config.pagesRectangle.height * scale)),
                                    null),
                            Math.round(config.pagesRectangle.x * scale),
                            Math.round(config.pagesRectangle.y * scale), null);
                }

            }

        }
        if (!scalePoints.isEmpty()) {
            //      if (tablet.getDeviceConfig().getImageBean() != null)
            //         g.drawImage(tablet.getDeviceConfig().getImageBean().getImage(), tablet.getDeviceConfig().getImageBean().getOffset().x, tablet.getDeviceConfig().getImageBean().getOffset().y, null);
            ImageRenderer.drawPoints(scalePoints, (Graphics2D) g, Color.BLACK, new Point(0, 0),
                    Math.max(1, (3 * scale)), tablet.getMaxPressure() * scale);

        }

    }

    public static boolean IS_DUAL_SCREEN = false;

    public BioSign() throws IOException {

        JSObjectWrapper.call("log", new Object[] { "intiTablet" });

        _instance = this;

        if (!initTablet()) {
            if (Device.isDEBUG)
                showError(new Exception("Cannot connect to any device"));
            _instance = null;
            //         return;
            throw new IOException("Cannot connect to any Device");
        }

        if (tablet.getDeviceConfig().isAirModeSupported()) {
            this.addMouseListener(this);
            this.addMouseMotionListener(this);
        }
        this.setFocusable(true);
        this.setRequestFocusEnabled(true);
        scale = DeviceManager._instance.getWidth() / (float) tablet.getDimension().getWidth();

        this.setLayout(new BorderLayout());

    }

    private boolean initTablet() {

        tablet = checkTablet();
        if (tablet == null)
            return false;
        System.out.println("Using " + tablet.getTabletDescription());

        tablet.init();
        return true;

    }

    private BaseDeviceHandler checkTablet() {
        BaseDeviceHandler ret = DeviceHandlerServiceProvider.getInstance().getConnecteDeviceHandler();
        if (ret != null)
            return ret;
        if (Device.IS_MOUSE_ALLOWED)
            return new MouseHandlerImpl();
        else {
            return new DummyHandlerImpl();
        }

    }

    double vp = 0;

    public void pressAirModeButton() {

        tablet.toggleAirMode();
    }

    public void pressOkButton() {
        if (!save())
            return;

        tablet.getDeviceConfig().clearCache(tablet.getDeviceConfig().actualPage);
        tablet.clear();

        close();
        for (IDeviceListener list : DeviceManager._instance.listeners) {
            list.accept(Signature.outputSdi, Signature.image, DeviceManager._instance);
        }
        if (Device.isDEBUG) {
            DeviceManager._instance.startCapture(false);
        }
    }

    public void pressClearButton() {
        System.out.println("pressClearButton");
        long start = System.nanoTime();
        tablet.clear();
        long cleared = System.nanoTime();
        System.out.println("tablet clear in " + ((cleared - start) / 1000000) + "ms");
        //      loadImage();
        repaint();
        long loadedImage = System.nanoTime();
        System.out.println("tablet reloadedImage in " + ((loadedImage - cleared) / 1000000) + "ms");
        for (IDeviceListener list : DeviceManager._instance.listeners) {
            list.retry(DeviceManager._instance);
        }
    }

    public void pressCancelButton() {
        //      System.out.println("cancelSign");
        tablet.clear();
        close();

        for (IDeviceListener list : DeviceManager._instance.listeners) {
            list.cancel(DeviceManager._instance);
        }
        JSObjectWrapper.call("cancelSign", null);
        if (Device.isDEBUG) {

            DeviceManager._instance.startCapture(!tablet.getForceAirMode());
        }
    }

    // private static byte[] transformIntTo4Bytes(int int_0) {
    // return new byte[] { (byte) ((int_0 & -16777216) >> 24),
    // (byte) ((int_0 & 16711680) >> 16),
    // (byte) ((int_0 & 65280) >> 8), (byte) int_0 };
    // }
    //
    // private byte[] transformIntTo2Bytes(short short_0) {
    // return new byte[] { (byte) (((int) short_0 & 65280) >> 8),
    // (byte) short_0 };
    // }

    public BaseDeviceHandler tablet = null;// = new WacomStuHandlerImpl();

    private Boolean save() {

        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
            public Boolean run() {
                try {
                    JSObjectWrapper.call("log", new Object[] { "save sign : " + tablet.isEmpty() });

                    if (tablet.isEmpty())
                        return false;
                    if (!tablet.isEmpty()) {

                        if (Signature.isBio)
                            Signature.outputSdi = CmsEncryptor.getBiometricData();
                        else
                            Signature.outputSdi = "";

                        //                  BufferedImage bufferedImage = tablet
                        //                        .getSignatureImage();

                        BufferedImage bufferedImage = tablet.getSignatureImage();
                        ByteArrayOutputStream out = new ByteArrayOutputStream();
                        ImageIO.write(bufferedImage, "png", out);
                        if (tablet.getDeviceConfig().scaledSignRectangle != null) {
                            Point r = ((Point) tablet.getDeviceConfig().scaledSignRectangle.getLocation().clone());
                            //                           r.translate(-tablet.getDeviceConfig().getActiveAreaForBackground().x,-tablet.getDeviceConfig().getActiveAreaForBackground().y);
                            Device.signatureBeans
                                    .add(new SignatureBean(bufferedImage, r, tablet.getDeviceConfig().actualPage));
                        }
                        byte[] image = out.toByteArray();
                        byte[] base64Image = Base64.encode(image);
                        Signature.image = new String(base64Image);

                        JSObjectWrapper.call("log", new Object[] { "SDI : " + Signature.outputSdi });
                        //                  IOUtils.write(image, new FileOutputStream(new File(
                        //                        "c:\\imageFromTablet.png")));
                        JSObjectWrapper.call("signAcquired", new Object[] { Signature.outputSdi, Signature.image });

                    }
                    tablet.getDeviceConfig().clearCache(tablet.getDeviceConfig().actualPage);
                    //               tablet.clear();
                    return true;

                } catch (Throwable e) {

                    JSObjectWrapper.call("log", new Object[] { exToStr(e) });
                    return false;
                }
            }
        });

    }

    private String exToStr(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        t.printStackTrace(pw);
        return sw.toString(); // stack trace as a string
    }

    private Image bkImage = null;

    public int totalPage = -1;

    //   Image loadingImage=null;

    public void loadImage() {

        try {

            tablet.setLoading(true, true);
            //         System.out.println("repaint");
            ////         repaint();
            //         JSObjectWrapper.call("log",
            //               new Object[] { "WebSigning: loadImage on path "
            //                     + Device.signWithButtons });

            Image overlay = tablet.getDeviceConfig().getButtonsImage();
            //         overlay.getGraphics().clearRect(tablet.get, y, width, height);
            //         Image overlay = tablet.getDeviceConfig().image;
            //         ImageIO.write((RenderedImage)overlay, "png", new File("/tmp/nuovoTest.png"));
            ImageBean image = tablet.getDeviceConfig().getPdfCroppedImage(tablet.getDeviceConfig().actualPage);
            //               .getDeviceConfig());
            int w = Math.max(image == null ? 0 : image.getImage().getWidth(), overlay.getWidth(null));
            int h = Math.max(image == null ? 0 : image.getImage().getHeight(), overlay.getHeight(null));
            BufferedImage justButtons = new BufferedImage(w, h,
                    tablet.getDeviceConfig().isAlphaSupported() ? BufferedImage.TYPE_INT_ARGB
                            : BufferedImage.TYPE_INT_ARGB);

            Graphics gJustButton = justButtons.getGraphics();
            BufferedImage allInOne = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

            Graphics gAllInOne = allInOne.getGraphics();

            tablet.getDeviceConfig().setImageBean(image);
            //         g.clearRect(tablet.getDeviceConfig().get, y, width, height);
            if (image != null) //usare la pdfArea
                gAllInOne.drawImage(image.getImage(),
                        -image.getOffset().x + tablet.getDeviceConfig().getActiveAreaForBackground().x,
                        -image.getOffset().y + tablet.getDeviceConfig().getActiveAreaForBackground().y, null);

            gAllInOne.drawImage(overlay, 0, 0, null);

            if (!tablet.getDeviceConfig().isButtonImageFixed()) {

                if (DeviceManager._instance.getSize().width != overlay.getWidth(null)
                        || DeviceManager._instance.getSize().height != overlay.getHeight(null)) {
                    overlay = overlay.getScaledInstance(DeviceManager._instance.getSize().width,
                            DeviceManager._instance.getSize().height, BufferedImage.SCALE_SMOOTH);
                    System.out.println("Resizing buttons image");
                }
            }

            gJustButton.drawImage(overlay, 0, 0, null);
            //         if (tablet.getDeviceConfig().isAirModeSupported())
            tablet.setBackgroundImage(justButtons);
            //         else
            //            tablet.setBackgroundImage(allInOne);

            scale = DeviceManager._instance.getWidth() / (float) tablet.getDimension().getWidth();

            bkImage = ImageUtils.scaleImage(justButtons, scale);

        } catch (Exception e) {
            e.printStackTrace();
            // throw new InvalidOperationException(e.getMessage());
        } finally {

            tablet.setLoading(false, false);
            this.repaint();

        }

    }

    public void close() {
        if (tablet != null)
            tablet.stop();

        setVisible(false);
    }

    public static void showError(Throwable e) {
        e.printStackTrace();
        if (_instance != null)
            JOptionPane.showMessageDialog(_instance, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }

    public void acquireNext(boolean forceAirMode) {
        try {
            if (tablet == null || tablet instanceof DummyHandlerImpl) {
                JSObjectWrapper.call("noDevice", null);
                return;
            }
            tablet.clear();
            tablet.setForceAirMode(forceAirMode);
            //         if (forceAirMode)
            //            tablet.toggleAirMode();
            //         if (!forceAirMode)
            //            tablet.toggleAirMode();
            //         tablet.toggleAirMode();

            tablet.getDeviceConfig().loadTemplate(Device.TAG);
            loadImage();

            setVisible(true);

            if (Device.isDEBUG)
                tablet.setEnableDocView(true);
            tablet.acquireNext();

            _instance.repaint();
        } catch (Exception ex) {
            if (ex.getMessage() != null && ex.getMessage().equals("Device is not connected"))
                showError(ex);
            else
                ex.printStackTrace();
        }

    }

    public void destroy() {

        // TODO Auto-generated method stub
        if (tablet != null)
            tablet.destroy();
    }

    public void pressNextButton(boolean forceRepaint) {

        tablet.getDeviceConfig().actualPage++;
        if (tablet.getDeviceConfig().actualPage > totalPage) {
            tablet.getDeviceConfig().actualPage--;
            return;
        }
        tablet.setLoading(true, forceRepaint);
        DeviceManager._instance.setPdfB64Image(
                tablet.getDeviceConfig().baseImageUrl + tablet.getDeviceConfig().actualPage,
                tablet.getDeviceConfig().signPointWidth, tablet.getDeviceConfig().actualPage, totalPage, false);
        loadImage();
        // TODO Auto-generated method stub

    }

    public void pressPrevButton(boolean forceRepaint) {
        tablet.getDeviceConfig().actualPage--;
        if (tablet.getDeviceConfig().actualPage < 1) {
            tablet.getDeviceConfig().actualPage++;
            return;
        }
        tablet.setLoading(true, forceRepaint);
        DeviceManager._instance.setPdfB64Image(
                tablet.getDeviceConfig().baseImageUrl + tablet.getDeviceConfig().actualPage,
                tablet.getDeviceConfig().signPointWidth, tablet.getDeviceConfig().actualPage, totalPage, false);
        loadImage();
        // TODO Auto-generated method stub

    }

}