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.File; import java.io.FileOutputStream; import java.io.InputStream; import javax.imageio.ImageIO; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.NameValuePair; import org.apache.commons.httpclient.methods.PostMethod; 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; public class XpdlImageUtil { public static final String IMAGE_FOLDER = "xpdlImages"; public static final String IMAGE_EXTENSION = ".jpg"; public static final String THUMBNAIL_PREFIX = "thumb-"; public static final int THUMBNAIL_SIZE = 200; public static String getXpdlImagePath(String processDefId) { ApplicationContext appContext = WorkflowUtil.getApplicationContext(); WorkflowManager workflowManager = (WorkflowManager) appContext.getBean("workflowManager"); WorkflowProcess process = workflowManager.getProcess(processDefId); return SetupManager.getBaseDirectory() + IMAGE_FOLDER + File.separator + process.getPackageId() + File.separator; } 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) throws Exception { 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) { final String baseDir = getXpdlImagePath(processDefId); ApplicationContext appContext = WorkflowUtil.getApplicationContext(); WorkflowManager workflowManager = (WorkflowManager) appContext.getBean("workflowManager"); final WorkflowProcess process = workflowManager.getProcess(processDefId); final byte[] xpdlBytes = workflowManager.getPackageContent(process.getPackageId(), process.getVersion()); Thread thread = new Thread(new Runnable() { public void run() { FileOutputStream fos = null; try { String fileName = processDefId + IMAGE_EXTENSION; File file = new File(baseDir); file.mkdirs(); file = new File(baseDir + fileName); fos = new FileOutputStream(file); HttpClient httpClient = new HttpClient(); String url = designerwebBaseUrl + "/wflow-designerweb/viewer/viewer.jsp?processId=" + process.getEncodedId(); 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"); httpClient.executeMethod(post); InputStream is = post.getResponseBodyAsStream(); byte[] buffer = new byte[1024]; int byteReaded = is.read(buffer); while (byteReaded != -1) { fos.write(buffer, 0, byteReaded); byteReaded = is.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, ""); } } } }); if (asynchronous) { thread.start(); } else { thread.run(); } } 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(path + processDefId + IMAGE_EXTENSION); 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(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, ""); } } } }