Package org.joget.workflow.util

Source Code of org.joget.workflow.util.XpdlImageUtil$CustomX509TrustManager

package org.joget.workflow.util;

import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.X509Certificate;
import javax.imageio.ImageIO;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.joget.commons.util.DynamicDataSourceManager;
import org.joget.commons.util.LogUtil;
import org.joget.commons.util.SetupManager;
import org.joget.workflow.model.WorkflowProcess;
import org.joget.workflow.model.service.WorkflowManager;
import org.springframework.context.ApplicationContext;
import org.springframework.core.task.TaskExecutor;

public class XpdlImageUtil {
   
    public static final String IMAGE_FOLDER = "app_xpdlImages";
    public static final String IMAGE_EXTENSION = ".jpg";
    public static final String THUMBNAIL_PREFIX = "thumb-";
    public static final int THUMBNAIL_SIZE = 400;

    public static String getXpdlImagePath(String processDefId) {
        ApplicationContext appContext = WorkflowUtil.getApplicationContext();
        WorkflowManager workflowManager = (WorkflowManager) appContext.getBean("workflowManager");
        WorkflowProcess process = workflowManager.getProcess(processDefId);

        File path = new File(SetupManager.getBaseDirectory(), IMAGE_FOLDER + File.separator + process.getPackageId() + File.separator);
        return path.getAbsolutePath();
    }

    public static File getXpdlImage(String designerwebBaseUrl, String processDefId) {
        File file = new File(getXpdlImagePath(processDefId), processDefId + IMAGE_EXTENSION);
        if (!file.exists()) {
            generateXpdlImage(designerwebBaseUrl, processDefId);
            file = new File(getXpdlImagePath(processDefId), processDefId + IMAGE_EXTENSION);
        }
        return file;
    }

    public static File getXpdlThumbnail(String designerwebBaseUrl, String processDefId) {
        File file = new File(getXpdlImagePath(processDefId), THUMBNAIL_PREFIX + processDefId + IMAGE_EXTENSION);
        if (!file.exists()) {
            generateXpdlImage(designerwebBaseUrl, processDefId);
            file = new File(getXpdlImagePath(processDefId), THUMBNAIL_PREFIX + processDefId + IMAGE_EXTENSION);
        }
        return file;
    }

    public static void generateXpdlImage(final String designerwebBaseUrl, final String processDefId) {
        generateXpdlImage(designerwebBaseUrl, processDefId, false);
    }

    public static void generateXpdlImage(final String designerwebBaseUrl, final String processDefId, boolean asynchronous) {
        String profile = DynamicDataSourceManager.getCurrentProfile();
       
        TaskExecutor executor = (TaskExecutor) WorkflowUtil.getApplicationContext().getBean("xpdlImageExecutor");
        executor.execute(new XpdlImageTask(profile, designerwebBaseUrl, processDefId));
    }

    public static void createXpdlImage(String designerwebBaseUrl, String processDefId) {
        String baseDir = getXpdlImagePath(processDefId);
        ApplicationContext appContext = WorkflowUtil.getApplicationContext();
        WorkflowManager workflowManager = (WorkflowManager) appContext.getBean("workflowManager");
        WorkflowProcess process = workflowManager.getProcess(processDefId);
        byte[] xpdlBytes = workflowManager.getPackageContent(process.getPackageId(), process.getVersion());
           
        FileOutputStream fos = null;
        try {
            String fileName = processDefId + IMAGE_EXTENSION;
            File file = new File(baseDir);
            file.mkdirs();
            file = new File(baseDir, fileName);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            String url = designerwebBaseUrl + "/viewer/viewer.jsp?processId=" + process.getEncodedId();
            URL urlObj = new URL(url);
            if ("https".equals(urlObj.getProtocol())) {
                // add support for self-signed SSL
                String protocolPrefix = "custom";
                String protocol = protocolPrefix + "https";
                url = protocolPrefix + url;
                Protocol customHttps = new Protocol(protocol, new CustomSSLProtocolSocketFactory(), urlObj.getPort());
                Protocol.registerProtocol(protocol, customHttps);
            }

            HttpClient httpClient = new HttpClient();
            PostMethod post = new PostMethod(url);
            NameValuePair[] data = {
                new NameValuePair("xpdl", new String(xpdlBytes, "UTF-8")),
                new NameValuePair("packageId", process.getPackageId()),
                new NameValuePair("processId", processDefId)
            };
            post.setRequestBody(data);
            post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

            // execute request
            httpClient.executeMethod(post);

            InputStream is = post.getResponseBodyAsStream();

            byte[] buffer = new byte[1024];
            int byteReaded = is.read(buffer);
            while (byteReaded != -1) {
                bos.write(buffer, 0, byteReaded);
                byteReaded = is.read(buffer);
            }
            bos.flush();

            // output to file
            byte[] contents = bos.toByteArray();
            ByteArrayInputStream bis = new ByteArrayInputStream(contents);
            fos = new FileOutputStream(file);
            buffer = new byte[1024];
            byteReaded = bis.read(buffer);
            while (byteReaded != -1) {
                fos.write(buffer, 0, byteReaded);
                byteReaded = bis.read(buffer);
            }
            fos.flush();

            createThumbnail(baseDir, processDefId);
        } catch (Exception ex) {
            LogUtil.error(XpdlImageUtil.class.getName(), ex, "Error generating xpdl image [processDefId=" + processDefId + "]");
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (Exception ex) {
                LogUtil.error(XpdlImageUtil.class.getName(), ex, "");
            }
        }
    }
   
    public static void createThumbnail(String path, String processDefId) {
        int thumbWidth = THUMBNAIL_SIZE;
        int thumbHeight = THUMBNAIL_SIZE;

        BufferedOutputStream out = null;

        try{
            Image image = Toolkit.getDefaultToolkit().getImage(new File(path, processDefId + IMAGE_EXTENSION).getAbsolutePath());
            MediaTracker mediaTracker = new MediaTracker(new Container());
            mediaTracker.addImage(image, 0);
            mediaTracker.waitForID(0);

            double thumbRatio = (double) thumbWidth / (double) thumbHeight;
            int imageWidth = image.getWidth(null);
            int imageHeight = image.getHeight(null);
            double imageRatio = (double) imageWidth / (double) imageHeight;
            if (thumbRatio < imageRatio) {
                thumbHeight = (int) (thumbWidth / imageRatio);
            } else {
                thumbWidth = (int) (thumbHeight * imageRatio);
            }

            BufferedImage thumbImage = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = thumbImage.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            graphics2D.drawImage(image, 0, 0, thumbWidth, thumbHeight, null);

            out = new BufferedOutputStream(new FileOutputStream(new File(path, THUMBNAIL_PREFIX + processDefId + IMAGE_EXTENSION)));
            ImageIO.write(thumbImage, "jpeg", out);

            out.flush();
        } catch (Exception ex) {
            LogUtil.error(XpdlImageUtil.class.getName(), ex, "Error generating xpdl thumbnail [processDefId=" + processDefId + "]");
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (Exception ex) {
                LogUtil.error(XpdlImageUtil.class.getName(), ex, "");
            }
        }
    }
   
    /**
     * TrustManager that accepts self-signed certificates.
     */
    static class CustomX509TrustManager implements X509TrustManager {
        private X509TrustManager standardTrustManager = null;

        /**
         * Constructor for CustomX509TrustManager.
         */
        public CustomX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
            super();
            TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            factory.init(keystore);
            TrustManager[] trustmanagers = factory.getTrustManagers();
            if (trustmanagers.length == 0) {
                throw new NoSuchAlgorithmException("no trust manager found");
            }
            for (TrustManager tm: trustmanagers) {
                if (tm instanceof X509TrustManager) {
                    this.standardTrustManager = (X509TrustManager)trustmanagers[0];
                    break;
                }
            }
            if (this.standardTrustManager == null) {
                throw new NoSuchAlgorithmException("no trust manager found");
            }
        }

        /**
         * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
         */
        public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
            standardTrustManager.checkClientTrusted(certificates,authType);
        }

        /**
         * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
         */
        public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException {
            if ((certificates != null) && (certificates.length == 1)) {
                try {
                    certificates[0].checkValidity();
                } catch (CertificateExpiredException e) {
                    // accept expired certs
                }
            } else {
                standardTrustManager.checkServerTrusted(certificates,authType);
            }
        }

        /**
         * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
         */
        public X509Certificate[] getAcceptedIssuers() {
            return this.standardTrustManager.getAcceptedIssuers();
        }
    }

    /**
     * Used to create SSL links that accept self-signed certificates.
     */
    static class CustomSSLProtocolSocketFactory implements ProtocolSocketFactory {

        private SSLContext sslcontext = null;

        /**
         * Constructor for CustomSSLProtocolSocketFactory.
         */
        public CustomSSLProtocolSocketFactory() {
            super();
        }

        private SSLContext createCustomSSLContext() {
            try {
                SSLContext context = SSLContext.getInstance("TLS");
                context.init(
                  null,
                  new TrustManager[] {new CustomX509TrustManager(null)},
                  null);
                return context;
            } catch (Exception e) {
                throw new HttpClientError(e.toString());
            }
        }

        private SSLContext getSSLContext() {
            if (this.sslcontext == null) {
                this.sslcontext = createCustomSSLContext();
            }
            return this.sslcontext;
        }

        /**
         * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
         */
        public Socket createSocket(
            String host,
            int port,
            InetAddress clientHost,
            int clientPort)
            throws IOException, UnknownHostException {

            return getSSLContext().getSocketFactory().createSocket(
                host,
                port,
                clientHost,
                clientPort
            );
        }

        /**
         * Attempts to get a new socket connection to the given host within the given time limit.
         * <p>
         * To circumvent the limitations of older JREs that do not support connect timeout a
         * controller thread is executed. The controller thread attempts to create a new socket
         * within the given limit of time. If socket constructor does not return until the
         * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
         * </p>
        
         * @param host the host name/IP
         * @param port the port on the host
         * @param clientHost the local host name/IP to bind the socket to
         * @param clientPort the port on the local machine
         * @param params {@link HttpConnectionParams Http connection parameters}
         *
         * @return Socket a new socket
         *
         * @throws IOException if an I/O error occurs while creating the socket
         * @throws UnknownHostException if the IP address of the host cannot be
         * determined
         */
        public Socket createSocket(
            final String host,
            final int port,
            final InetAddress localAddress,
            final int localPort,
            final HttpConnectionParams params
        ) throws IOException, UnknownHostException, ConnectTimeoutException {
            if (params == null) {
                throw new IllegalArgumentException("Parameters may not be null");
            }
            int timeout = params.getConnectionTimeout();
            SocketFactory socketfactory = getSSLContext().getSocketFactory();
            if (timeout == 0) {
                return socketfactory.createSocket(host, port, localAddress, localPort);
            } else {
                Socket socket = socketfactory.createSocket();
                SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
                SocketAddress remoteaddr = new InetSocketAddress(host, port);
                socket.bind(localaddr);
                socket.connect(remoteaddr, timeout);
                return socket;
            }
        }

        /**
         * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
         */
        public Socket createSocket(String host, int port)
            throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(
                host,
                port
            );
        }

        /**
         * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
         */
        public Socket createSocket(
            Socket socket,
            String host,
            int port,
            boolean autoClose)
            throws IOException, UnknownHostException {
            return getSSLContext().getSocketFactory().createSocket(
                socket,
                host,
                port,
                autoClose
            );
        }

        public boolean equals(Object obj) {
            return ((obj != null) && obj.getClass().equals(CustomSSLProtocolSocketFactory.class));
        }

        public int hashCode() {
            return CustomSSLProtocolSocketFactory.class.hashCode();
        }

    }   
}
TOP

Related Classes of org.joget.workflow.util.XpdlImageUtil$CustomX509TrustManager

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.