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/15 10:03:21 UTC

svn commit: r1883436 - in /pdfbox/branches/2.0/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: Sun Nov 15 10:03:21 2020
New Revision: 1883436

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

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

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java?rev=1883436&r1=1883435&r2=1883436&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDButton.java Sun Nov 15 10:03:21 2020
@@ -146,7 +146,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.isEmpty())
+            {
+                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
         {
@@ -183,6 +200,31 @@ 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/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java?rev=1883436&r1=1883435&r2=1883436&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestRadioButtons.java Sun Nov 15 10:03:21 2020
@@ -16,65 +16,42 @@
  */
 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.assertTrue;
+import static org.junit.Assert.fail;
+
 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.cos.COSArray;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.io.IOUtils;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
 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
     {
         PDDocument doc = null;
@@ -139,12 +116,12 @@ public class TestRadioButtons extends Te
 
             // assert that the values have been correctly set
             assertNotNull(radioButton.getCOSObject().getItem(COSName.OPT));
-            assertEquals(optItem.size(),2);
+            assertEquals(2, optItem.size());
             assertEquals(options.get(0), optItem.getString(0));
             
             // assert that the values can be retrieved correctly
             List<String> retrievedOptions = radioButton.getExportValues();
-            assertEquals(retrievedOptions.size(),2);
+            assertEquals(2, retrievedOptions.size());
             assertEquals(retrievedOptions, options);
 
             // assert that the Opt entry is removed
@@ -155,10 +132,181 @@ public class TestRadioButtons extends Te
         }
         finally
         {
-            if( doc != null )
             {
-                doc.close();
+                IOUtils.closeQuietly(doc);
+            }
+        }
+    }
+
+    /**
+     * 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";
+
+        PDDocument testPdf = null;
+        try
+        {
+            testPdf = PDDocument.load(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());
+        }
+        finally
+        {
+            IOUtils.closeQuietly(testPdf);
+        }
+    }
+
+    /**
+     * 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";
+
+        PDDocument testPdf = null;
+        try
+        {
+            testPdf = PDDocument.load(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());
+        }
+        finally
+        {
+            IOUtils.closeQuietly(testPdf);
+        }
+    }
+
+    /**
+     * 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";
+
+        PDDocument testPdf = null;
+        try
+        {
+            testPdf = PDDocument.load(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());
+
+            try {
+                field.setValue("Invalid");
+                fail("Expected an IndexOutOfBoundsException to be thrown");
+            } catch (Exception ex) {
+                // 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 = ex.getMessage();
+                assertTrue(actualMessage.contains(expectedMessage));
             }
+
+            assertEquals("no option shall be selected", "Off", field.getValue());
+            assertTrue("no export values are selected", field.getSelectedExportValues().isEmpty());
+        }
+        finally
+        {
+            IOUtils.closeQuietly(testPdf);
+        }
+    }
+
+    /**
+     * 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";
+
+        PDDocument testPdf = null;
+        try
+        {
+            testPdf = PDDocument.load(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());
+        }
+        finally
+        {
+            IOUtils.closeQuietly(testPdf);
         }
     }
+
+    /**
+     * 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";
+
+        PDDocument testPdf = null;
+        try
+        {
+            testPdf = PDDocument.load(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());
+
+            try {
+                field.setValue(6);
+                fail("Expected an IndexOutOfBoundsException to be thrown");
+            } catch (Exception ex) {
+                // 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 = ex.getMessage();
+                assertTrue(actualMessage.contains(expectedMessage));
+            }
+
+            assertEquals("no option shall be selected", "Off", field.getValue());
+            assertTrue("no export values are selected", field.getSelectedExportValues().isEmpty());
+        }
+        finally
+        {
+            IOUtils.closeQuietly(testPdf);
+        }
+   }
 }
\ No newline at end of file