org.pdfsam.console.business.pdf.handlers.SlideShowCmdExecutor.java Source code

Java tutorial

Introduction

Here is the source code for org.pdfsam.console.business.pdf.handlers.SlideShowCmdExecutor.java

Source

/*
 * Created on 06-Mar-2008
 * Copyright (C) 2008 by Andrea Vacondio.
 *
 *
 * This library is provided under dual licenses.
 * You may choose the terms of the Lesser General Public License version 2.1 or the General Public License version 2
 * License at your discretion.
 * 
 * 
 * This library 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;
 * version 2.1 of the License.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * 
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms of the 
 * GNU General Public License as published by the Free Software Foundation; 
 * either version 2 of the License.
 * 
 * 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 General Public License along with this program; 
 * if not, write to the Free Software Foundation, Inc., 
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.pdfsam.console.business.pdf.handlers;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.pdfsam.console.business.ConsoleServicesFacade;
import org.pdfsam.console.business.dto.Transition;
import org.pdfsam.console.business.dto.WorkDoneDataModel;
import org.pdfsam.console.business.dto.commands.AbstractParsedCommand;
import org.pdfsam.console.business.dto.commands.SlideShowParsedCommand;
import org.pdfsam.console.business.pdf.handlers.interfaces.AbstractCmdExecutor;
import org.pdfsam.console.exceptions.console.ConsoleException;
import org.pdfsam.console.exceptions.console.SlideShowException;
import org.pdfsam.console.utils.FileUtility;
import org.pdfsam.console.utils.PdfUtility;
import org.pdfsam.console.utils.perfix.PrefixParser;

import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfTransition;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;

/**
 * Command executor for the slideshow command
 * @author Andrea Vacondio
 */
public class SlideShowCmdExecutor extends AbstractCmdExecutor {

    private static final Logger LOG = Logger.getLogger(SlideShowCmdExecutor.class.getPackage().getName());

    private Hashtable transitionsMappingMap = null;
    private PdfReader pdfReader = null;
    private PdfStamper pdfStamper = null;

    public void execute(AbstractParsedCommand parsedCommand) throws ConsoleException {

        if ((parsedCommand != null) && (parsedCommand instanceof SlideShowParsedCommand)) {

            SlideShowParsedCommand inputCommand = (SlideShowParsedCommand) parsedCommand;
            PrefixParser prefixParser;
            setPercentageOfWorkDone(0);
            Transitions transitions = new Transitions();
            transitions.setDefaultTransition(inputCommand.getDefaultTransition());
            transitions.setTransitions(inputCommand.getTransitions());
            transitions = parseXmlInput(inputCommand.getInputXmlFile(), transitions);
            try {
                prefixParser = new PrefixParser(inputCommand.getOutputFilesPrefix(),
                        inputCommand.getInputFile().getFile().getName());
                File tmpFile = FileUtility.generateTmpFile(inputCommand.getOutputFile());

                pdfReader = PdfUtility.readerFor(inputCommand.getInputFile());
                pdfReader.removeUnusedObjects();
                pdfReader.consolidateNamedDestinations();

                //version
                LOG.debug("Creating a new document.");
                Character pdfVersion = inputCommand.getOutputPdfVersion();
                if (pdfVersion != null) {
                    pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(tmpFile),
                            inputCommand.getOutputPdfVersion().charValue());
                } else {
                    pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(tmpFile),
                            pdfReader.getPdfVersion());
                }

                //creator
                HashMap meta = pdfReader.getInfo();
                meta.put("Creator", ConsoleServicesFacade.CREATOR);

                //compression
                setCompressionSettingOnStamper(inputCommand, pdfStamper);
                pdfStamper.setMoreInfo(meta);

                //fullscreen
                if (inputCommand.isFullScreen()) {
                    pdfStamper.setViewerPreferences(PdfWriter.PageModeFullScreen);
                }

                //sets transitions
                if (transitions.getDefaultTransition() == null) {
                    setTransitionsWithoutDefault(transitions);
                } else {
                    int totalPages = pdfReader.getNumberOfPages();
                    setTransitionsWithDefault(transitions, totalPages);
                }

                pdfStamper.close();
                pdfReader.close();

                File outFile = new File(inputCommand.getOutputFile(), prefixParser.generateFileName());
                FileUtility.renameTemporaryFile(tmpFile, outFile, inputCommand.isOverwrite());
                LOG.debug("File " + outFile.getCanonicalPath() + " created.");
                LOG.info("Slide show options set.");
            } catch (Exception e) {
                throw new SlideShowException(e);
            } finally {
                setWorkCompleted();
            }
        } else {
            throw new ConsoleException(ConsoleException.ERR_BAD_COMMAND);
        }
    }

    /**
     * sets the transitions on the stamper setting the default value if no transition has been set for the page.
     * @param defaultTransition
     * @param totalPages
     * @param transitions
     */
    private void setTransitionsWithDefault(Transitions transitions, int totalPages) {
        LOG.debug("Setting transitions with a default value.");
        Transition[] trans = transitions.getTransitions();

        Hashtable transitionsMap = new Hashtable(0);
        if (trans != null) {
            transitionsMap = new Hashtable(trans.length);
            for (int i = 0; i < trans.length; i++) {
                transitionsMap.put(new Integer(trans[i].getPageNumber()), trans[i]);
            }
        }

        for (int j = 1; j <= totalPages; j++) {
            Object rawTransition = transitionsMap.get(new Integer(j));
            if (rawTransition != null) {
                Transition transition = (Transition) rawTransition;
                pdfStamper.setDuration(transition.getDuration(), transition.getPageNumber());
                pdfStamper.setTransition(new PdfTransition(getITextTransition(transition.getTransition()),
                        transition.getTransitionDuration()), transition.getPageNumber());
            } else {
                pdfStamper.setDuration(transitions.getDefaultTransition().getDuration(), j);
                pdfStamper.setTransition(
                        new PdfTransition(getITextTransition(transitions.getDefaultTransition().getTransition()),
                                transitions.getDefaultTransition().getTransitionDuration()),
                        j);
            }
            setPercentageOfWorkDone(((j) * WorkDoneDataModel.MAX_PERGENTAGE) / totalPages);
        }
    }

    /**
     * sets the transitions on the stamper when no default transition is set
     * @param defaultTransition
     * @param transitions
     */
    private void setTransitionsWithoutDefault(Transitions transitions) {
        LOG.debug("Setting transitions without a default value.");
        Transition[] trans = transitions.getTransitions();
        if (trans != null && trans.length > 0) {
            for (int i = 0; i < trans.length; i++) {
                pdfStamper.setDuration(trans[i].getDuration(), trans[i].getPageNumber());
                pdfStamper.setTransition(new PdfTransition(getITextTransition(trans[i].getTransition()),
                        trans[i].getTransitionDuration()), trans[i].getPageNumber());
                setPercentageOfWorkDone(((i + 1) * WorkDoneDataModel.MAX_PERGENTAGE) / trans.length);
            }
        } else {
            LOG.warn("No transition to set.");
        }
    }

    /**
     * Maps a pdfsam transition to a iText transition.
     * If an error occur the PdfTransition.BLINDH is the default transition.
     * @param transition
     * @return
     */
    private int getITextTransition(String transition) {
        int retVal = PdfTransition.BLINDH;
        if (transitionsMappingMap == null) {
            transitionsMappingMap = new Hashtable(20);
            transitionsMappingMap.put(Transition.T_BLINDH, new Integer(PdfTransition.BLINDH));
            transitionsMappingMap.put(Transition.T_BLINDV, new Integer(PdfTransition.BLINDV));
            transitionsMappingMap.put(Transition.T_BTWIPE, new Integer(PdfTransition.BTWIPE));
            transitionsMappingMap.put(Transition.T_DGLITTER, new Integer(PdfTransition.DGLITTER));
            transitionsMappingMap.put(Transition.T_DISSOLVE, new Integer(PdfTransition.DISSOLVE));
            transitionsMappingMap.put(Transition.T_INBOX, new Integer(PdfTransition.INBOX));
            transitionsMappingMap.put(Transition.T_LRGLITTER, new Integer(PdfTransition.LRGLITTER));
            transitionsMappingMap.put(Transition.T_LRWIPE, new Integer(PdfTransition.LRWIPE));
            transitionsMappingMap.put(Transition.T_OUTBOX, new Integer(PdfTransition.OUTBOX));
            transitionsMappingMap.put(Transition.T_RLWIPE, new Integer(PdfTransition.RLWIPE));
            transitionsMappingMap.put(Transition.T_SPLITHIN, new Integer(PdfTransition.SPLITHIN));
            transitionsMappingMap.put(Transition.T_SPLITHOUT, new Integer(PdfTransition.SPLITHOUT));
            transitionsMappingMap.put(Transition.T_SPLITVIN, new Integer(PdfTransition.SPLITVIN));
            transitionsMappingMap.put(Transition.T_SPLITVOUT, new Integer(PdfTransition.SPLITVOUT));
            transitionsMappingMap.put(Transition.T_TBGLITTER, new Integer(PdfTransition.TBGLITTER));
            transitionsMappingMap.put(Transition.T_TBWIPE, new Integer(PdfTransition.TBWIPE));
        }
        Object iTextTransition = transitionsMappingMap.get(transition);
        if (iTextTransition != null) {
            retVal = ((Integer) iTextTransition).intValue();
        }
        return retVal;
    }

    /**
     * Parse the input xml file adding the informations to the Transitions object
     * @param inputFile
     * @param transitions
     * @return
     */
    private Transitions parseXmlInput(File inputFile, Transitions transitions) throws SlideShowException {
        Transitions retVal = transitions;
        if (inputFile != null) {
            try {
                LOG.debug("Parsing xml transitions file " + inputFile.getAbsolutePath());
                SAXReader reader = new SAXReader();
                Document document = reader.read(inputFile);
                Node rootNode = document.selectSingleNode("/transitions");
                if (rootNode != null) {
                    Node defType = rootNode.selectSingleNode("@defaulttype");
                    Node defTransDur = rootNode.selectSingleNode("@defaulttduration");
                    Node defDur = rootNode.selectSingleNode("@defaultduration");
                    if (defType != null && defTransDur != null && defDur != null) {
                        if (transitions.getDefaultTransition() != null) {
                            throw new SlideShowException(SlideShowException.ERR_DEFAULT_TRANSITION_ALREADY_SET);
                        } else {
                            transitions.setDefaultTransition(new Transition(Transition.EVERY_PAGE,
                                    new Integer(defTransDur.getText().trim()).intValue(), defType.getText().trim(),
                                    new Integer(defDur.getText().trim()).intValue()));
                        }
                    }
                    List transitionsList = document.selectNodes("/transitions/transition");
                    for (int i = 0; transitionsList != null && i < transitionsList.size(); i++) {
                        Node transitionNode = (Node) transitionsList.get(i);
                        Node type = transitionNode.selectSingleNode("@type");
                        Node transDuration = transitionNode.selectSingleNode("@tduration");
                        Node duration = transitionNode.selectSingleNode("@duration");
                        Node page = transitionNode.selectSingleNode("@pagenumber");
                        if (type != null && transDuration != null && duration != null && page != null) {
                            transitions.addTransition(new Transition(new Integer(page.getText().trim()).intValue(),
                                    new Integer(transDuration.getText().trim()).intValue(), type.getText().trim(),
                                    new Integer(duration.getText().trim()).intValue()));
                        } else {
                            throw new SlideShowException(SlideShowException.ERR_READING_TRANSITION,
                                    new String[] { i + "" });
                        }
                    }
                } else {
                    throw new SlideShowException(SlideShowException.ERR_READING_XML_TRANSITIONS_FILE);
                }
            } catch (Exception e) {
                throw new SlideShowException(SlideShowException.ERR_READING_XML_TRANSITIONS_FILE, e);
            }
        }
        return retVal;
    }

    public void clean() {
        closePdfReader(pdfReader);
        closePdfStamper(pdfStamper);
    }

    /**
     * Model for the transitions set
     * @author Andrea Vacondio
     *
     */
    private static class Transitions {

        private Transition defaultTransition;
        private List transitions;

        public Transitions() {
            this.defaultTransition = null;
            this.transitions = null;
        }

        /**
         * @return the defaultTransition
         */
        public Transition getDefaultTransition() {
            return defaultTransition;
        }

        /**
         * @param defaultTransition the defaultTransition to set
         */
        public void setDefaultTransition(Transition defaultTransition) {
            this.defaultTransition = defaultTransition;
        }

        /**
         * @return the transitions
         */
        public Transition[] getTransitions() {
            Transition[] retVal = null;
            if (transitions != null) {
                retVal = (Transition[]) transitions.toArray(new Transition[transitions.size()]);
            }
            return retVal;
        }

        /**
         * @param transitions the transitions to set. If transitions is null nothing happen.
         */
        public void setTransitions(Transition[] transitions) {
            if (transitions != null) {
                this.transitions = Arrays.asList(transitions);
            }
        }

        /**
         * add the transition to the list if not null
         * @param transition
         * @return
         */
        public boolean addTransition(Transition transition) {
            boolean retVal = false;
            if (transition != null) {
                if (transitions == null) {
                    this.transitions = new ArrayList();
                }
                retVal = this.transitions.add(transition);
            }
            return retVal;
        }
    }
}