You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ms...@apache.org on 2020/10/04 15:59:41 UTC

svn commit: r1882236 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form: AppearanceGeneratorHelper.java PDAcroForm.java ScriptingHandler.java

Author: msahyoun
Date: Sun Oct  4 15:59:40 2020
New Revision: 1882236

URL: http://svn.apache.org/viewvc?rev=1882236&view=rev
Log:
PDFBOX-4977: provide format action support capability for AcroForm field

Added:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/ScriptingHandler.java
Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java?rev=1882236&r1=1882235&r2=1882236&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/AppearanceGeneratorHelper.java Sun Oct  4 15:59:40 2020
@@ -34,6 +34,7 @@ import org.apache.pdfbox.pdmodel.PDResou
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.font.PDFont;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
 import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceCharacteristicsDictionary;
@@ -155,7 +156,6 @@ class AppearanceGeneratorHelper
         }
     }
     
-    
     /**
      * This is the public method for setting the appearance stream.
      *
@@ -164,7 +164,7 @@ class AppearanceGeneratorHelper
      */
     public void setAppearanceValue(String apValue) throws IOException
     {
-        value = apValue;
+        value = getFormattedValue(apValue);
 
         // Treat multiline field values in single lines as single lime values.
         // This is in line with how Adobe Reader behaves when enetring text
@@ -196,55 +196,69 @@ class AppearanceGeneratorHelper
                 continue;
             }
 
-            PDFormFieldAdditionalActions actions = field.getActions();
-
-            // in case all tests fail the field will be formatted by acrobat
-            // when it is opened. See FreedomExpressions.pdf for an example of this.  
-            if (actions == null || actions.getF() == null ||
-                widget.getCOSObject().getDictionaryObject(COSName.AP) != null)
+            PDAppearanceDictionary appearanceDict = widget.getAppearance();
+            if (appearanceDict == null)
             {
-                PDAppearanceDictionary appearanceDict = widget.getAppearance();
-                if (appearanceDict == null)
-                {
-                    appearanceDict = new PDAppearanceDictionary();
-                    widget.setAppearance(appearanceDict);
-                }
-
-                PDAppearanceEntry appearance = appearanceDict.getNormalAppearance();
-                // TODO support appearances other than "normal"
-                
-                PDAppearanceStream appearanceStream;
-                if (isValidAppearanceStream(appearance))
-                {
-                    appearanceStream = appearance.getAppearanceStream();
-                }
-                else
-                {
-                    appearanceStream = prepareNormalAppearanceStream(widget);
+                appearanceDict = new PDAppearanceDictionary();
+                widget.setAppearance(appearanceDict);
+            }
 
-                    appearanceDict.setNormalAppearance(appearanceStream);
-                    // TODO support appearances other than "normal"
-                }
+            PDAppearanceEntry appearance = appearanceDict.getNormalAppearance();
+            // TODO support appearances other than "normal"
                 
-                /*
-                 * Adobe Acrobat always recreates the complete appearance stream if there is an appearance characteristics
-                 * entry (the widget dictionaries MK entry). In addition if there is no content yet also create the appearance
-                 * stream from the entries.
-                 * 
-                 */
-                if (widget.getAppearanceCharacteristics() != null || appearanceStream.getContentStream().getLength() == 0)
-                {
-                    initializeAppearanceContent(widget, appearanceStream);
-                }
+            PDAppearanceStream appearanceStream;
+            if (isValidAppearanceStream(appearance))
+            {
+                appearanceStream = appearance.getAppearanceStream();
+            }
+            else
+            {
+                appearanceStream = prepareNormalAppearanceStream(widget);
+                appearanceDict.setNormalAppearance(appearanceStream);
+                // TODO support appearances other than "normal"
+            }
                 
-                setAppearanceContent(widget, appearanceStream);
+            /*
+             * Adobe Acrobat always recreates the complete appearance stream if there is an appearance characteristics
+             * entry (the widget dictionaries MK entry). In addition if there is no content yet also create the appearance
+             * stream from the entries.
+             * 
+             */
+            if (widget.getAppearanceCharacteristics() != null || appearanceStream.getContentStream().getLength() == 0)
+            {
+                initializeAppearanceContent(widget, appearanceStream);
             }
+                
+            setAppearanceContent(widget, appearanceStream);
+            
             
             // restore the field level appearance
             defaultAppearance =  acroFormAppearance;
         }
     }
 
+    private String getFormattedValue(String apValue)
+    {
+        // format the field value for the appearance if there is scripting support and the field
+        // has a format event
+        PDFormFieldAdditionalActions actions = field.getActions();
+
+        if (actions != null && actions.getF() != null)
+        {
+            if (field.getAcroForm().getScriptingHandler() != null)
+            {
+                ScriptingHandler scriptingHandler = field.getAcroForm().getScriptingHandler();
+                return scriptingHandler.format((PDActionJavaScript) field.getActions().getF(), apValue);
+            }
+            else
+            {
+                LOG.info("Field contains a formatting action but no SriptingHandler has been supplied - formatted value might be incorrect");
+                return apValue;
+            }
+        }
+        return apValue;
+    }
+
     private static boolean isValidAppearanceStream(PDAppearanceEntry appearance)
     {
         if (appearance == null)

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java?rev=1882236&r1=1882235&r2=1882236&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDAcroForm.java Sun Oct  4 15:59:40 2020
@@ -72,6 +72,8 @@ public final class PDAcroForm implements
     
     private Map<String, PDField> fieldCache;
 
+    private ScriptingHandler scriptingHandler;
+
     /**
      * Constructor.
      *
@@ -703,6 +705,26 @@ public final class PDAcroForm implements
     }
 
     /**
+     * Set a handler to support JavaScript actions in the form.
+     * 
+     * @return scriptingHandler
+     */
+    public ScriptingHandler getScriptingHandler()
+    {
+        return scriptingHandler;
+    }
+
+    /**
+     * Set a handler to support JavaScript actions in the form.
+     * 
+     * @param scriptingHandler
+     */
+    public void setScriptingHandler(ScriptingHandler scriptingHandler)
+    {
+        this.scriptingHandler = scriptingHandler;
+    }
+
+    /**
      * Set the AppendOnly bit.
      *
      * @param appendOnly The value for AppendOnly.

Added: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/ScriptingHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/ScriptingHandler.java?rev=1882236&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/ScriptingHandler.java (added)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/ScriptingHandler.java Sun Oct  4 15:59:40 2020
@@ -0,0 +1,56 @@
+package org.apache.pdfbox.pdmodel.interactive.form;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
+
+public interface ScriptingHandler {
+    /**
+     * Handle the fields keyboard event action.
+     * 
+     * @param javaScriptAction the keyboard event action script
+     * @param value the current field value
+     * @return the resulting field value
+     */
+    public String keyboard(PDActionJavaScript javaScriptAction, String value);
+
+    /**
+     * Handle the fields format event action.
+     * 
+     * @param javaScriptAction the format event action script
+     * @param value the current field value
+     * @return the formatted field value
+     */
+    public String format(PDActionJavaScript javaScriptAction, String value);
+
+    /**
+     * Handle the fields validate event action.
+     * 
+     * @param javaScriptAction the validate event action script
+     * @param value the current field value
+     * @return the result of the validity check
+     */
+    public boolean validate(PDActionJavaScript javaScriptAction, String value);
+
+    /**
+     * Handle the fields calculate event action.
+     * 
+     * @param javaScriptAction the calculate event action script
+     * @param value the current field value
+     * @return the result of the field calculation
+     */    
+    public String calculate(PDActionJavaScript javaScriptAction, String value);
+}