All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.intarsys.pdf.app.action.ActionTools Maven / Gradle / Ivy

Go to download

This is a fork of http://sourceforge.net/projects/jpodlib/ as development seems to be frozen. We're providing some bug fixes along with deployments to maven.

There is a newer version: 2.0
Show newest version
/*
 * Copyright (c) 2007, intarsys consulting GmbH
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * - Neither the name of intarsys nor the names of its contributors may be used
 *   to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package de.intarsys.pdf.app.action;

import de.intarsys.pdf.cds.CDSNameTreeNode;
import de.intarsys.pdf.cds.CDSTreeEntry;
import de.intarsys.pdf.cos.COSCatalog;
import de.intarsys.pdf.cos.COSDictionary;
import de.intarsys.pdf.cos.COSDocument;
import de.intarsys.pdf.cos.COSName;
import de.intarsys.pdf.cos.COSObject;
import de.intarsys.pdf.pd.IAdditionalActionSupport;
import de.intarsys.pdf.pd.PDAcroFormField;
import de.intarsys.pdf.pd.PDAction;
import de.intarsys.pdf.pd.PDActionGoTo;
import de.intarsys.pdf.pd.PDAdditionalActions;
import de.intarsys.pdf.pd.PDAnnotation;
import de.intarsys.pdf.pd.PDDocument;
import de.intarsys.pdf.pd.PDPage;
import de.intarsys.pdf.pd.PDWidgetAnnotation;
import de.intarsys.tools.attribute.Attribute;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Tool class for {@link PDAction} related tasks.
 */
public class ActionTools {

    private ActionTools() {
    }

    /**
     * Handle type for disable/enable action processing
     */
    public static class ActionDisablement {
        protected COSName actionType;
    }

    /**
     * The key where we can find the static JavaScripts in the document catalog.
     */
    public static final COSName DK_JavaScript = COSName.constant("JavaScript"); //$NON-NLS-1$

    /**
     * The logger.
     */
    private static final Logger Log = PACKAGE.Log;

    private static final Attribute ATTR_DISABLEDACTIONS = new Attribute("disabledActions");

    public static TriggerEvent annotationTriggerBlurred(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "blurred [" + annotation.toString() //$NON-NLS-1$
                                  + "]"); //$NON-NLS-1$
        }
        PDWidgetAnnotation widget = (PDWidgetAnnotation) annotation;
        PDAcroFormField field = widget.getAcroFormField();
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_Bl);
        trigger.setTarget(field.getLogicalRoot());
        trigger.setValue(field.getValueString());
        trigger.setTargetName(field.getQualifiedName());
        ActionTools.process(trigger, field);
        return trigger;
    }

    public static TriggerEvent annotationTriggerFocus(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "focus [" + annotation.toString() //$NON-NLS-1$
                                  + "]"); //$NON-NLS-1$
        }
        PDWidgetAnnotation widget = (PDWidgetAnnotation) annotation;
        PDAcroFormField field = widget.getAcroFormField();
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_Fo);
        trigger.setTarget(field.getLogicalRoot());
        trigger.setValue(field.getValueString());
        trigger.setTargetName(field.getQualifiedName());
        ActionTools.process(trigger, field);
        return trigger;
    }

    public static TriggerEvent annotationTriggerKeystroke(PDAnnotation annotation,
                                                          String change,
                                                          boolean willCommit,
                                                          int commitKey,
                                                          boolean modifier,
                                                          int selStart,
                                                          int selEnd,
                                                          boolean shift,
                                                          String value) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "keystroke [" + annotation.toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
        }
        PDWidgetAnnotation widget = (PDWidgetAnnotation) annotation;
        PDAcroFormField field = widget.getAcroFormField().getLogicalRoot();
        TriggerEvent trigger = new TriggerEvent(field.getDoc(), PDAdditionalActions.CN_trigger_K);
        trigger.setChange(change);
        trigger.setWillCommit(willCommit);
        trigger.setCommitKey(commitKey);
        trigger.setModifier(modifier);
        trigger.setSelStart(selStart);
        trigger.setSelEnd(selEnd);
        trigger.setShift(shift);
        trigger.setTarget(field.getLogicalRoot());
        trigger.setTargetName(field.getQualifiedName());
        trigger.setValue(value);
        ActionTools.process(trigger, field);
        return trigger;
    }

    public static TriggerEvent annotationTriggerMouseDown(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "mouse down [" //$NON-NLS-1$
                                  + annotation.toString() + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_D);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_D);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    public static TriggerEvent annotationTriggerMouseEnter(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "mouse enter [" //$NON-NLS-1$
                                  + annotation.toString() + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_E);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_E);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    public static TriggerEvent annotationTriggerMouseExit(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "mouse exit [" //$NON-NLS-1$
                                  + annotation.toString() + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_X);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_X);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    public static TriggerEvent annotationTriggerMouseUp(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "mouse up [" + annotation.toString() //$NON-NLS-1$
                                  + "]"); //$NON-NLS-1$
        }
        TriggerEvent trigger;
        COSDictionary cosAction = annotation.cosGetField(PDAnnotation.DK_A).asDictionary();
        if (cosAction != null) {
            trigger = new TriggerEvent(annotation.getDoc(), null);
            trigger.setTarget(getTriggerEventTarget(annotation));
            COSName cosType = cosAction.get(PDAction.DK_S).asName();
            ActionProcessor.get().process(trigger, cosType, cosAction);
        } else {
            PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_U);
            if (action == null) {
                // fast path
                return null;
            }
            trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_U);
            trigger.setTarget(getTriggerEventTarget(annotation));
            ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        }
        return trigger;
    }

    public static TriggerEvent annotationTriggerPageClose(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "page close [" //$NON-NLS-1$
                                  + annotation.toString() + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_PC);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_PC);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    public static TriggerEvent annotationTriggerPageInvisible(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "page invisible [" //$NON-NLS-1$
                                  + annotation.toString() + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_PI);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_PI);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    public static TriggerEvent annotationTriggerPageOpen(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "page open [" + annotation.toString() //$NON-NLS-1$
                                  + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_PO);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_PO);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    public static TriggerEvent annotationTriggerPageVisible(PDAnnotation annotation) {
        if (Log.isLoggable(Level.FINEST)) {
            Log.log(Level.FINEST, "page visible [" //$NON-NLS-1$
                                  + annotation.toString() + "]"); //$NON-NLS-1$
        }
        PDAction action = getAction(annotation, PDAdditionalActions.CN_trigger_PV);
        if (action == null) {
            // fast path
            return null;
        }
        TriggerEvent trigger = new TriggerEvent(annotation.getDoc(), PDAdditionalActions.CN_trigger_PV);
        trigger.setTarget(getTriggerEventTarget(annotation));
        ActionProcessor.get().process(trigger, action.cosGetActionType(), action.cosGetObject());
        return trigger;
    }

    /**
     * Set a flag with {@code doc} to signal that action processing for
     * the type {@code actionType} should be disabled. This flag is
     * honoured by the {@link StandardActionProcessor}.
     * 

* Specify {@code null} as the {@code actionType} to disable * processing of all actions. * * @param doc The document for which action processing is switched off. * @param actionType The type of actions no longer executed or {@code null} * for all action types. * @return A handle that is used for re-enabling the processing. This * ensures that action processing can't be reestablished by * malicious code (as long as you don't leak the handle). */ public static ActionDisablement disableActions(COSDocument doc, COSName actionType) { List disablements = (List) doc.getAttribute(ATTR_DISABLEDACTIONS); if (disablements == null) { disablements = new ArrayList(); doc.setAttribute(ATTR_DISABLEDACTIONS, disablements); } ActionDisablement disablement = new ActionDisablement(); disablement.actionType = actionType; disablements.add(disablement); return disablement; } public static void documentProcessModules(PDDocument doc) { COSCatalog catalog = doc.getCatalog(); if (catalog == null) { return; } COSDictionary names = catalog.cosGetNames(); if (names == null) { return; } final CDSNameTreeNode tree = CDSNameTreeNode.createFromCos(names.get(DK_JavaScript).asDictionary()); if (tree == null) { return; } for (Iterator it = tree.iterator(); it.hasNext(); ) { CDSTreeEntry entry = (CDSTreeEntry) it.next(); // ignore scripts generated by Adobe COSObject cosActionName = entry.getKey(); if (cosActionName != null && !cosActionName.isNull()) { String actionName = cosActionName.stringValue(); if (actionName.toUpperCase().startsWith("!ADBE::")) { //$NON-NLS-1$ continue; } } // execute script COSObject actionDefinition = entry.getValue(); TriggerEvent event = new TriggerEvent(doc, null); ActionProcessor.get().process(event, DK_JavaScript, actionDefinition); } } public static TriggerEvent documentTriggerClose(PDDocument doc) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "document close [" + doc.getName() + "]" //$NON-NLS-1$ //$NON-NLS-2$ ); } TriggerEvent trigger = new TriggerEvent(doc, PDAdditionalActions.CN_trigger_DC); trigger.setTarget(doc); ActionTools.process(trigger, doc); trigger = new TriggerEvent(doc, PDAdditionalActions.CN_trigger_WC); trigger.setTarget(doc); ActionTools.process(trigger, doc); return trigger; } public static TriggerEvent documentTriggerDidPrint(PDDocument doc) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "did print [" + doc.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } TriggerEvent trigger = new TriggerEvent(doc, PDAdditionalActions.CN_trigger_DP); trigger.setTarget(doc); ActionTools.process(trigger, doc); return trigger; } public static TriggerEvent documentTriggerDidSave(PDDocument doc) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "did save [" + doc.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } TriggerEvent trigger = new TriggerEvent(doc, PDAdditionalActions.CN_trigger_DS); trigger.setTarget(doc); ActionTools.process(trigger, doc); return trigger; } public static TriggerEvent documentTriggerOpen(PDDocument doc) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "document open [" + doc.getName() + "]" //$NON-NLS-1$ //$NON-NLS-2$ ); } TriggerEvent trigger = new TriggerEvent(doc, null); trigger.setTarget(doc); COSObject action = doc.getCatalog().cosGetOpenAction(); if (action.isNull()) { return null; } COSName cosType = null; if (action instanceof COSDictionary) { cosType = ((COSDictionary) action).get(PDAction.DK_S).asName(); } else { cosType = PDActionGoTo.CN_ActionType_GoTo; } ActionProcessor.get().process(trigger, cosType, action); return trigger; } public static TriggerEvent documentTriggerWillPrint(PDDocument doc) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "will print [" + doc.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } TriggerEvent trigger = new TriggerEvent(doc, PDAdditionalActions.CN_trigger_WP); trigger.setTarget(doc); ActionTools.process(trigger, doc); return trigger; } public static TriggerEvent documentTriggerWillSave(PDDocument doc) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "will save [" + doc.getName() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } TriggerEvent trigger = new TriggerEvent(doc, PDAdditionalActions.CN_trigger_WS); trigger.setTarget(doc); ActionTools.process(trigger, doc); return trigger; } /** * Remove a flag with {@code doc} to reestablish action processing * for the type {@code actionType}. This flag is honoured by the * {@link StandardActionProcessor}. *

* You must supply the handle from your call to "disableAction" in * {@code disablement}. * * @param doc The document for which action processing is switched off. * @param disablement The handle from "disableActions" */ public static void enableActions(COSDocument doc, ActionDisablement disablement) { List disablements = (List) doc.getAttribute(ATTR_DISABLEDACTIONS); if (disablements == null) { disablements = new ArrayList(); doc.setAttribute(ATTR_DISABLEDACTIONS, disablements); } disablements.remove(disablement); } public static TriggerEvent fieldTriggerCalculate(PDAcroFormField field, String value, PDAcroFormField source) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "calculate [" + field.toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } field = field.getLogicalRoot(); TriggerEvent trigger = new TriggerEvent(source, field.getDoc(), PDAdditionalActions.CN_trigger_C); trigger.setTarget(field); trigger.setValue(value); trigger.setTargetName(field.getQualifiedName()); ActionTools.process(trigger, field); return trigger; } /** * Format the value of the widget according to its formatting script. The * result of the formatting is not stored but only used as the input for the * widget appearance rendering. */ public static TriggerEvent fieldTriggerFormat(PDAcroFormField field, boolean willCommit, int commitKey, String value) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "format [" + field.toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } field = field.getLogicalRoot(); TriggerEvent trigger = new TriggerEvent(field.getDoc(), PDAdditionalActions.CN_trigger_F); trigger.setWillCommit(willCommit); trigger.setCommitKey(commitKey); trigger.setTarget(field.getLogicalRoot()); trigger.setTargetName(field.getQualifiedName()); trigger.setValue(value); ActionTools.process(trigger, field); return trigger; } public static TriggerEvent fieldTriggerValidate(PDAcroFormField field, String value) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "validate [" + field.toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } field = field.getLogicalRoot(); TriggerEvent trigger = new TriggerEvent(field.getDoc(), PDAdditionalActions.CN_trigger_V); trigger.setTarget(field.getLogicalRoot()); trigger.setTargetName(field.getQualifiedName()); trigger.setValue(value); ActionTools.process(trigger, field); return trigger; } protected static PDAction getAction(IAdditionalActionSupport actionSupport, COSName reason) { if (actionSupport == null) { return null; } PDAdditionalActions actions = actionSupport.getAdditionalActions(); if (actions == null) { return null; } return actions.getAction(reason); } protected static Object getTriggerEventTarget(PDAnnotation annotation) { if (annotation.isWidgetAnnotation()) { return ((PDWidgetAnnotation) annotation).getAcroFormField().getLogicalRoot(); } return annotation; } /** * {@code true} if execution of an action of type * {@code actionType} should be allowed. This flag is honoured by the * {@link StandardActionProcessor}. * * @param doc The document under inspection. * @param actionType The type of actions we want to execute. * @return {@code true} if execution of an action of type * {@code actionType} should be allowed. */ public static boolean isEnabled(COSDocument doc, COSName actionType) { List disablements = (List) doc.getAttribute(ATTR_DISABLEDACTIONS); if (disablements == null) { return true; } for (Iterator it = disablements.iterator(); it.hasNext(); ) { ActionDisablement disablement = (ActionDisablement) it.next(); if (disablement.actionType == null || disablement.actionType.equals(actionType)) { return false; } } return true; } public static TriggerEvent pageTriggerClose(PDPage page) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "close [" + page.toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } TriggerEvent trigger = new TriggerEvent(page.getDoc(), PDAdditionalActions.CN_trigger_C); trigger.setTarget(page); ActionTools.process(trigger, page); return trigger; } public static TriggerEvent pageTriggerOpen(PDPage page) { if (Log.isLoggable(Level.FINEST)) { Log.log(Level.FINEST, "open [" + page.toString() + "]"); //$NON-NLS-1$ //$NON-NLS-2$ } TriggerEvent trigger = new TriggerEvent(page.getDoc(), PDAdditionalActions.CN_trigger_O); trigger.setTarget(page); ActionTools.process(trigger, page); return trigger; } /** * Lookup a {@link PDAction} to be executed when {@code event} is * triggered. The action is looked up in the {@code actionSupport} * instance which defines the trigger - action association. * * @param event The event that causes an action to be processed. * @param actionSupport The target object whose action will be processed */ protected static void process(TriggerEvent event, IAdditionalActionSupport actionSupport) { if ((actionSupport == null) && event.getTarget() instanceof IAdditionalActionSupport) { actionSupport = (IAdditionalActionSupport) event.getTarget(); } if (actionSupport == null) { return; } PDAdditionalActions actions = actionSupport.getAdditionalActions(); if (actions == null) { return; } PDAction action = actions.getAction(event.getReason()); if (action == null) { return; } ActionProcessor.get().process(event, action.cosGetActionType(), action.cosGetObject()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy