org.squale.squaleweb.applicationlayer.action.export.ppt.PPTData.java Source code

Java tutorial

Introduction

Here is the source code for org.squale.squaleweb.applicationlayer.action.export.ppt.PPTData.java

Source

/**
 * 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);
        }
    }
}