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/11/13 18:37:48 UTC

svn commit: r1883397 - in /pdfbox/trunk/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java

Author: msahyoun
Date: Fri Nov 13 18:37:47 2020
New Revision: 1883397

URL: http://svn.apache.org/viewvc?rev=1883397&view=rev
Log:
PDFBOX-3683: handle setting/getting of value if /Opt exists and In Unison flag is false

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java?rev=1883397&r1=1883396&r2=1883397&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java Fri Nov 13 18:37:47 2020
@@ -132,7 +132,24 @@ public abstract class PDButton extends P
         COSBase value = getInheritableAttribute(COSName.V);
         if (value instanceof COSName)
         {
-            return ((COSName)value).getName();
+            String stringValue = ((COSName)value).getName();
+            List<String> exportValues = getExportValues();
+            if (exportValues.size() > 0)
+            {
+                try
+                {
+                    int idx = Integer.parseInt(stringValue, 10);
+                    if (idx >= 0 && idx < exportValues.size())
+                    {
+                        return exportValues.get(idx);
+                    }
+                }
+                catch (NumberFormatException nfe)
+                {
+                    return stringValue;
+                }
+            }
+            return stringValue;
         }
         else
         {
@@ -168,6 +185,30 @@ public abstract class PDButton extends P
         
         applyChange();
     }
+
+    /**
+     * Set the selected option given its index, and try to update the visual appearance.
+     * 
+     * NOTE: this method is only usable if there are export values and used for 
+     * radio buttons with FLAG_RADIOS_IN_UNISON not set.
+     * 
+     * @param index index of option to be selected
+     * @throws IOException if the value could not be set
+     * @throws IllegalArgumentException if the index provided is not a valid index.
+     */
+    public void setValue(int index) throws IOException
+    {
+        if (getExportValues().isEmpty() || index < 0 || index >= getExportValues().size())
+        {
+            throw new IllegalArgumentException("index '" + index
+                    + "' is not a valid index for the field " + getFullyQualifiedName()
+                    + ", valid indizes are from 0 to " + (getExportValues().size() - 1));
+        }
+
+        updateByValue(String.valueOf(index));
+                
+        applyChange();
+    }
     
     
     /**

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java?rev=1883397&r1=1883396&r2=1883397&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java Fri Nov 13 18:37:47 2020
@@ -16,14 +16,19 @@
  */
 package org.apache.pdfbox.pdmodel.interactive.form;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
 import java.io.IOException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
+import org.apache.pdfbox.Loader;
 import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
@@ -33,48 +38,19 @@ import org.apache.pdfbox.pdmodel.interac
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceEntry;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
 
+import org.junit.Test;
+
 /**
  * This will test the functionality of Radio Buttons in PDFBox.
  */
-public class TestRadioButtons extends TestCase
+public class TestRadioButtons
 {
-    
-    /**
-     * Constructor.
-     *
-     * @param name The name of the test to run.
-     */
-    public TestRadioButtons( String name )
-    {
-        super( name );
-    }
-
-    /**
-     * This will get the suite of test that this class holds.
-     *
-     * @return All of the tests that this class holds.
-     */
-    public static Test suite()
-    {
-        return new TestSuite( TestRadioButtons.class );
-    }
-
-    /**
-     * infamous main method.
-     *
-     * @param args The command line arguments.
-     */
-    public static void main( String[] args )
-    {
-        String[] arg = {TestRadioButtons.class.getName() };
-        junit.textui.TestRunner.main( arg );
-    }
-
     /**
      * This will test the radio button PDModel.
      *
      * @throws IOException If there is an error creating the field.
      */
+    @Test
     public void testRadioButtonPDModel() throws IOException
     {
         try (PDDocument doc = new PDDocument())
@@ -152,4 +128,147 @@ public class TestRadioButtons extends Te
             assertEquals(radioButton.getExportValues(), new ArrayList<>());
         }
     }
+
+    /**
+     * PDFBOX-3656 Radio button field with FLAG_RADIOS_IN_UNISON false
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testPDFBox3656NotInUnison() throws IOException
+    {
+
+        String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12848122/SF1199AEG%20%28Complete%29.pdf";
+
+        try (PDDocument testPdf = Loader.loadPDF(new URL(sourceUrl).openStream()))
+        {
+            PDAcroForm acroForm = testPdf.getDocumentCatalog().getAcroForm();
+            PDRadioButton field = (PDRadioButton) acroForm.getField("Checking/Savings");
+            assertFalse("the radio buttons can be selected individually although having the same ON value", field.isRadiosInUnison());
+        }
+    }
+
+    /**
+     * PDFBOX-3656 Set by value
+     * 
+     * There are 6 radio buttons where 3 share the same common values but they are not set in unison
+     * Setting by the first export value shall only select the first radio button
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testPDFBox3656ByValidExportValue() throws IOException
+    {
+        String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12848122/SF1199AEG%20%28Complete%29.pdf";
+
+        try (PDDocument testPdf = Loader.loadPDF(new URL(sourceUrl).openStream()))
+        {
+            PDAcroForm acroForm = testPdf.getDocumentCatalog().getAcroForm();
+            PDRadioButton field = (PDRadioButton) acroForm.getField("Checking/Savings");
+            // check defaults
+            assertFalse("the radio buttons can be selected individually although having the same ON value", field.isRadiosInUnison());
+            assertEquals("initially no option shall be selected", "Off", field.getValue());
+            // set the field to a valid export value
+            field.setValue("Checking");
+            assertEquals("setting by the export value should also return that", "Checking", field.getValue());
+        }
+    }
+
+    /**
+     * PDFBOX-3656 Set by invalid export value
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testPDFBox3656ByInvalidExportValue() throws IOException
+    {
+        String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12848122/SF1199AEG%20%28Complete%29.pdf";
+
+        try (PDDocument testPdf = Loader.loadPDF(new URL(sourceUrl).openStream()))
+        {
+            PDAcroForm acroForm = testPdf.getDocumentCatalog().getAcroForm();
+            PDRadioButton field = (PDRadioButton) acroForm.getField("Checking/Savings");
+            // check defaults
+            assertFalse("the radio buttons can be selected individually although having the same ON value", field.isRadiosInUnison());
+            assertEquals("initially no option shall be selected", "Off", field.getValue());
+
+            // set the field to an invalid value shall throw
+            Exception exception = assertThrows(IllegalArgumentException.class, () -> {
+                field.setValue("Invalid");
+            });
+
+            // compare the messages
+            String expectedMessage = "value 'Invalid' is not a valid option for the field Checking/Savings, valid values are: [Checking, Savings] and Off";
+	        String actualMessage = exception.getMessage();
+	 
+            assertTrue(actualMessage.contains(expectedMessage));
+
+            assertEquals("no option shall be selected", "Off", field.getValue());
+            assertTrue("no export values are selected", field.getSelectedExportValues().isEmpty());
+        }
+    }
+
+    /**
+     * PDFBOX-3656 Set by a valid index
+     * 
+     * There are 6 radio buttons where 3 share the same common values but they are not set in unison
+     * Setting by the index shall only select the corresponding radio button
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testPDFBox3656ByValidIndex() throws IOException
+    {
+        String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12848122/SF1199AEG%20%28Complete%29.pdf";
+
+        try (PDDocument testPdf = Loader.loadPDF(new URL(sourceUrl).openStream()))
+        {
+            PDAcroForm acroForm = testPdf.getDocumentCatalog().getAcroForm();
+            PDRadioButton field = (PDRadioButton) acroForm.getField("Checking/Savings");
+            // check defaults
+            assertFalse("the radio buttons can be selected individually although having the same ON value", field.isRadiosInUnison());
+            assertEquals("initially no option shall be selected", "Off", field.getValue());
+            // set the field to a valid index
+            field.setValue(4);
+            assertEquals("setting by the index value should return the corresponding export", "Checking", field.getValue());
+        }
+    }
+
+    /**
+     * PDFBOX-3656 Set by an invalid index
+     * 
+     * There are 6 radio buttons where 3 share the same common values but they are not set in unison
+     * Setting by the index shall only select the corresponding radio button
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testPDFBox3656ByInvalidIndex() throws IOException
+    {
+
+        String sourceUrl = "https://issues.apache.org/jira/secure/attachment/12848122/SF1199AEG%20%28Complete%29.pdf";
+
+        try (PDDocument testPdf = Loader.loadPDF(new URL(sourceUrl).openStream()))
+        {
+            PDAcroForm acroForm = testPdf.getDocumentCatalog().getAcroForm();
+            PDRadioButton field = (PDRadioButton) acroForm.getField("Checking/Savings");
+            // check defaults
+            assertFalse("the radio buttons can be selected individually although having the same ON value", field.isRadiosInUnison());
+            assertEquals("initially no option shall be selected", "Off", field.getValue());
+
+            // set the field to an invalid index shall throw
+            Exception exception = assertThrows(IllegalArgumentException.class, () -> {
+                field.setValue(6);
+            });
+
+            // compare the messages
+            String expectedMessage = "index '6' is not a valid index for the field Checking/Savings, valid indizes are from 0 to 5";
+	        String actualMessage = exception.getMessage();
+	 
+            assertTrue(actualMessage.contains(expectedMessage));
+
+            assertEquals("no option shall be selected", "Off", field.getValue());
+            assertTrue("no export values are selected", field.getSelectedExportValues().isEmpty());
+        }
+    }
 }
\ No newline at end of file