Java tutorial
/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale 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 any later version. * * Squale 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 Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.squaleweb.applicationlayer.action.export.ppt; import java.awt.Color; import java.awt.Graphics; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.swing.ImageIcon; import javax.swing.JEditorPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.poi.hslf.HSLFSlideShow; import org.apache.poi.hslf.model.Line; import org.apache.poi.hslf.model.MasterSheet; import org.apache.poi.hslf.model.Picture; import org.apache.poi.hslf.model.Slide; import org.apache.poi.hslf.model.Table; import org.apache.poi.hslf.model.TableCell; import org.apache.poi.hslf.model.TextBox; import org.apache.poi.hslf.usermodel.RichTextRun; import org.apache.poi.hslf.usermodel.SlideShow; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.squale.squalecommon.util.xml.ParsingHandler; import org.squale.squalecommon.util.xml.XmlResolver; import org.squale.squaleweb.resources.WebMessages; /** * General data to create ppt documents */ public class PPTData { /** DTD location */ public static final String DTD_LOCATION = "/org/squale/squaleweb/resources/ppt/dtd/ppt_mapping-1.0.dtd"; /** Public id of mapping file */ public static final String PUBLIC_ID = "-//Squale//DTD PPT Mapping 1.0//EN"; /** Default font name for text box in ppt */ protected static final String DEFAULT_FONT_NAME = "Arial"; /** Default font size for text box in ppt */ protected static final int DEFAULT_FONT_SIZE = 10; /** Default font color for text box in ppt */ protected static final Color DEFAULT_FONT_COLOR = Color.BLACK; /** Default backgroud color for cell in ppt */ protected static final Color DEFAULT_BACKGROUND_COLOR = Color.WHITE; /** Log */ private static Log LOGGER = LogFactory.getLog(PPTData.class); /** Mapping indicating settings */ protected Document mapping; /** Presentation to modify */ protected SlideShow presentation; /** Slides of model to use */ protected Slide[] modelSlides; /** request */ protected HttpServletRequest request; /** Errors while parsing mapping file */ protected StringBuffer errors = new StringBuffer(); /** * Getter for presentation attribute * * @return presentation */ public SlideShow getPresentation() { return presentation; } /** * Create a document with mapping file * * @param mappingStream stream of mapping file * @throws PPTGeneratorException if error while parsing mapping file */ public void setMapping(InputStream mappingStream) throws PPTGeneratorException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setValidating(true); try { DocumentBuilder db = dbf.newDocumentBuilder(); db.setEntityResolver(new XmlResolver(PUBLIC_ID, DTD_LOCATION)); db.setErrorHandler(new ParsingHandler(LOGGER, errors)); mapping = db.parse(mappingStream); if (errors.length() > 0) { handleException("export.audit_report.mapping.error", new String[] { errors.toString() }); } } catch (ParserConfigurationException e) { handleException("export.audit_report.mapping.error", new String[] { e.getMessage() }); } catch (SAXException e) { handleException("export.audit_report.mapping.error", new String[] { e.getMessage() }); } catch (IOException e) { handleException("export.audit_report.mapping.error", new String[] { e.getMessage() }); } } /** * Set the presentation attribute * * @param pPresentationStream new presentation * @throws PPTGeneratorException if error creating ppt */ public void setPresentation(InputStream pPresentationStream) throws PPTGeneratorException { try { this.presentation = new SlideShow(pPresentationStream); } catch (IOException ioe) { handleException("export.audit_report.presentation.error.format"); } } /** * Getter for modelSlides attribute * * @return slides of model */ public Slide[] getModelSlides() { return modelSlides; } /** * Set modelSlides attribute * * @param pModelStream the model * @throws PPTGeneratorException if error occured while getting slides */ public void setModel(InputStream pModelStream) throws PPTGeneratorException { try { SlideShow model = new SlideShow(new HSLFSlideShow(pModelStream)); modelSlides = model.getSlides(); } catch (IOException ioe) { handleException("export.audit_report.model.error.format"); } } /** * Launched an PPTGeneratorException * * @param pKey key for exception message * @throws PPTGeneratorException error launched */ private void handleException(String pKey) throws PPTGeneratorException { throw new PPTGeneratorException(WebMessages.getString(request, pKey)); } /** * Launched an PPTGeneratorException * * @param pKey key for exception message * @param pArgs message parameters * @throws PPTGeneratorException error launched */ private void handleException(String pKey, String[] pArgs) throws PPTGeneratorException { throw new PPTGeneratorException((String) WebMessages.getString(request.getLocale(), pKey, pArgs)); } /** * Modify the presentation in function of mapping description * * @throws PPTGeneratorException if error occured while generating ppt */ public void modifyPresentation() throws PPTGeneratorException { // Parse mapping // Get class name with root tag Element root = mapping.getDocumentElement(); // Get class name String classname = root.getAttribute("class"); Class dataClass = null; try { dataClass = Class.forName(classname); } catch (ClassNotFoundException e) { throw new PPTGeneratorException("class not found :" + classname); } // initalization Class[] argsForSet = new Class[] { Slide.class, Rectangle.class }; Class[] argsForAdd = new Class[] { MasterSheet.class }; NodeList nl = root.getElementsByTagName("*"); for (int i = 0; i < nl.getLength(); i++) { Node curChild = nl.item(i); String methodName = ((Element) curChild).getAttribute("methodName"); if (curChild.getNodeName().equals("add")) { int modelPage = Integer.parseInt(((Element) curChild).getAttribute("model")); addSlide(getMethod(dataClass, methodName, argsForAdd), modelPage); } else if (curChild.getNodeName().equals("set")) { int slide = Integer.parseInt(((Element) curChild).getAttribute("slide")); String where = ((Element) curChild).getAttribute("where"); setSlide(getMethod(dataClass, methodName, argsForSet), where, slide); } } } /** * Get a method * * @param dataClass utility class * @param methodName method to find * @param args method's arguments * @return corresponding method * @throws PPTGeneratorException if error */ private Method getMethod(Class dataClass, String methodName, Class[] args) throws PPTGeneratorException { Method methodToCall = null; try { methodToCall = dataClass.getMethod(methodName, args); } catch (SecurityException e) { handleException("export.audit_report.mapping.error.method.access", new String[] { methodName }); } catch (NoSuchMethodException e) { handleException("export.audit_report.mapping.error.method.not_found", new String[] { methodName }); } return methodToCall; } /** * Add slide at the end of the presentation * * @param methodToCall method to invoke to create slide * @param modelPage model to use * @throws PPTGeneratorException if error */ private void addSlide(Method methodToCall, int modelPage) throws PPTGeneratorException { if (modelPage > modelSlides.length || modelPage < 1) { handleException("export.audit_report.mapping.error.model_slide", new String[] { "" + modelPage }); } try { methodToCall.invoke(this, new Object[] { modelSlides[modelPage - 1].getMasterSheet() }); } catch (IllegalArgumentException e) { handleException("export.audit_report.mapping.error.method_args", new String[] { methodToCall.getName() }); } catch (IllegalAccessException e) { handleException("export.audit_report.mapping.error.method.access", new String[] { methodToCall.getName() }); } catch (InvocationTargetException e) { handleException("export.audit_report.mapping.error.method_exception", new String[] { methodToCall.getName(), e.getMessage() }); } } /** * Set a slide * * @param methodToCall method to invoke to create slide * @param where reference for setting * @param slide page number of slide to change * @throws PPTGeneratorException if error */ private void setSlide(Method methodToCall, String where, int slide) throws PPTGeneratorException { if (slide > presentation.getSlides().length || slide < 1) { handleException("export.audit_report.mapping.error.presentation_slide", new String[] { "" + slide }); } try { Slide slideToSet = getPresentation().getSlides()[slide - 1]; Rectangle whereRec = new Rectangle(); for (int i = 0; i < slideToSet.getShapes().length; i++) { if (slideToSet.getShapes()[i] instanceof TextBox && ((TextBox) slideToSet.getShapes()[i]).getText() != null && where.equalsIgnoreCase(((TextBox) slideToSet.getShapes()[i]).getText().trim())) { whereRec = slideToSet.getShapes()[i].getAnchor(); } } methodToCall.invoke(this, new Object[] { slideToSet, whereRec }); } catch (IllegalArgumentException e) { handleException("export.audit_report.mapping.error.method_args", new String[] { methodToCall.getName() }); } catch (IllegalAccessException e) { handleException("export.audit_report.mapping.error.method.access", new String[] { methodToCall.getName() }); } catch (InvocationTargetException e) { handleException("export.audit_report.mapping.error.method_exception", new String[] { methodToCall.getName(), e.getMessage() }); } } /** * Getter for errors propertie * * @return errors occured while parsing mapping file */ public StringBuffer getErrors() { return errors; } /** * Set properties of cell * * @param cell cell to set * @param text text of cell */ protected void setTabCell(TableCell cell, String text) { setTabCell(cell, text, DEFAULT_FONT_NAME, DEFAULT_FONT_SIZE, DEFAULT_BACKGROUND_COLOR); } /** * Set properties of a cell * * @param cell cell to set * @param text text of cell * @param fontName font name for text * @param fontSize font name for text * @param backgroundColor background color for cell */ protected void setTabCell(TableCell cell, String text, String fontName, int fontSize, Color backgroundColor) { setTabCell(cell, text, fontName, fontSize); cell.setFillColor(backgroundColor); } /** * Set properties of a cell * * @param cell cell to set * @param text text of cell * @param fontName font name for text * @param fontSize font name for text * @param bold if text in bold * @param fontColor color of text * @param backgroundColor background color for cell */ protected void setTabCell(TableCell cell, String text, String fontName, int fontSize, Color backgroundColor, boolean bold, Color fontColor) { setTabCell(cell, text, fontName, fontSize, bold, fontColor); cell.setFillColor(backgroundColor); } /** * Set properties of a cell * * @param cell cell to set * @param text text of cell * @param fontName font name for text * @param fontSize font name for text */ protected void setTabCell(TableCell cell, String text, String fontName, int fontSize) { cell.setText(text); RichTextRun rt = cell.getTextRun().getRichTextRuns()[0]; rt.setFontName(fontName); rt.setFontSize(fontSize); cell.setVerticalAlignment(TextBox.AnchorMiddle); cell.setMarginBottom(0); cell.setMarginTop(0); } /** * Set properties of a cell * * @param cell cell to set * @param text text of cell * @param fontName font name for text * @param fontSize font name for text * @param bold if text in bold * @param fontColor color of text */ protected void setTabCell(TableCell cell, String text, String fontName, int fontSize, boolean bold, Color fontColor) { cell.setText(text); RichTextRun rt = cell.getTextRun().getRichTextRuns()[0]; rt.setFontName(fontName); rt.setFontSize(fontSize); rt.setBold(bold); rt.setFontColor(fontColor); cell.setVerticalAlignment(TextBox.AnchorMiddle); } /** * Create a table with black border * * @param nbRows number of rows * @param nbCol number of columns * @return the table */ protected Table createTableWithBorder(int nbRows, int nbCol) { final int columnHeight = 10; Table table = new Table(nbRows, nbCol); // set table borders Line border = table.createBorder(); border.setLineColor(Color.black); border.setLineWidth(1.0); table.setAllBorders(border); // minimize height for all row for (int i = 0; i < nbRows; i++) { table.setRowHeight(i, columnHeight); } return table; } /** * Add a text box in the slide * * @param slide slide to set * @param text text to add * @param fontSize font size of the text * @param anchor place of text box * @param isBullet if text is a list */ protected void addTextBox(Slide slide, String text, int fontSize, Rectangle anchor, boolean isBullet) { TextBox txt = new TextBox(); txt.setText(text); txt.setAnchor(anchor); RichTextRun rt = txt.getTextRun().getRichTextRuns()[0]; rt.setFontSize(fontSize); rt.setBullet(isBullet); slide.addShape(txt); } /** * Add title in slide * * @param slide slide to set * @param title text of title */ protected void addTitle(Slide slide, String title) { TextBox titleBox = slide.addTitle(); titleBox.setText(title); } /** * Add title in slide * * @param slide slide to set * @param title text of title * @param fontSize size for font */ protected void addTitle(Slide slide, String title, int fontSize) { TextBox titleBox = slide.addTitle(); titleBox.setText(title); RichTextRun rt = titleBox.getTextRun().getRichTextRuns()[0]; rt.setFontSize(fontSize); } /** * Add graph in slide * * @param slideToSet slide to set * @param graph graph to add * @param anchor place to add graph * @throws IOException if error */ protected void addJFreeChart(Slide slideToSet, JFreeChart graph, Rectangle anchor) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); int width = anchor.width; int height = anchor.height; if (width <= 0) { width = getPresentation().getPageSize().width; } if (height <= 0) { height = getPresentation().getPageSize().height; } ChartUtilities.writeChartAsPNG(out, graph, width, height); addPicture(slideToSet, out.toByteArray(), anchor); } /** * Add a picture in a slide * * @param slideToSet slide to set * @param data image data * @param anchor place to add image * @throws IOException if error */ protected void addPicture(Slide slideToSet, byte[] data, Rectangle anchor) throws IOException { int idx = getPresentation().addPicture(data, Picture.PNG); Picture pict = new Picture(idx); pict.setAnchor(anchor); slideToSet.addShape(pict); } /** * Convert a html code to an image * * @param html html to convert * @return html converted to png * @throws IOException if error * @throws PPTGeneratorException */ protected byte[] htmlToImage(String html) throws IOException, PPTGeneratorException { try { JEditorPane editor = new JEditorPane(); editor.setContentType("text/html"); editor.setText(html); editor.setSize(editor.getPreferredSize()); editor.addNotify(); LOGGER.debug("Panel is built"); BufferedImage bufferSave = new BufferedImage(editor.getPreferredSize().width, editor.getPreferredSize().height, BufferedImage.TYPE_3BYTE_BGR); Graphics g = bufferSave.getGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, editor.getPreferredSize().width, editor.getPreferredSize().height); editor.paint(g); LOGGER.debug("graphics is drawn"); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(bufferSave, "png", out); return out.toByteArray(); } catch (HeadlessException e) { LOGGER.error("X Server no initialized or -Djava.awt.headless=true not set !"); throw new PPTGeneratorException("X Server no initialized or -Djava.awt.headless=true not set !"); } } /** * Add an image with a html code without change its dimension * * @param slideToSet slide to set * @param html html code * @param x horizontal position * @param y vertical position * @throws IOException if error * @throws PPTGeneratorException */ protected void addHtmlPicture(Slide slideToSet, String html, int x, int y) throws IOException, PPTGeneratorException { try { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); if (!ge.isHeadlessInstance()) { LOGGER.warn("Runtime is not configured for supporting graphiv manipulation !"); } JEditorPane editor = new JEditorPane(); editor.setContentType("text/html"); editor.setText(html); LOGGER.debug("Editor pane is built"); editor.setSize(editor.getPreferredSize()); editor.addNotify(); // Serveur X requis LOGGER.debug("Panel rendering is done"); BufferedImage bufferSave = new BufferedImage(editor.getPreferredSize().width, editor.getPreferredSize().height, BufferedImage.TYPE_3BYTE_BGR); Graphics g = bufferSave.getGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, editor.getPreferredSize().width, editor.getPreferredSize().height); editor.paint(g); LOGGER.debug("graphics is drawn"); ByteArrayOutputStream out = new ByteArrayOutputStream(); ImageIO.write(bufferSave, "png", out); LOGGER.debug("image is written"); addPicture(slideToSet, out.toByteArray(), new Rectangle(x, y, editor.getPreferredSize().width, editor.getPreferredSize().height)); LOGGER.debug("image is added"); } catch (HeadlessException e) { LOGGER.error("X Server no initialized or -Djava.awt.headless=true not set !"); throw new PPTGeneratorException("X Server no initialized or -Djava.awt.headless=true not set !"); } } private BufferedImage convertImgToBufferedImg(Image limage, String l) { if (limage instanceof BufferedImage) { return ((BufferedImage) limage); } else { Image lImage = new ImageIcon(limage).getImage(); BufferedImage bufferedimage = new BufferedImage(lImage.getWidth(null), lImage.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics gr = bufferedimage.createGraphics(); gr.drawImage(lImage, 0, 0, null); gr.dispose(); return (bufferedimage); } } }