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 2015/01/13 20:59:34 UTC
svn commit: r1651462 - in /pdfbox/trunk/pdfbox/src:
main/java/org/apache/pdfbox/pdmodel/interactive/form/
test/java/org/apache/pdfbox/pdmodel/interactive/form/
Author: msahyoun
Date: Tue Jan 13 19:59:34 2015
New Revision: 1651462
URL: http://svn.apache.org/r1651462
Log:
PDFBOX-2516 support export value and display value for choice field options
Added:
pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java (with props)
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDChoice.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDListBox.java
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDChoice.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDChoice.java?rev=1651462&r1=1651461&r2=1651462&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDChoice.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDChoice.java Tue Jan 13 19:59:34 2015
@@ -43,6 +43,16 @@ public abstract class PDChoice extends P
private static final int FLAG_MULTI_SELECT = 1 << 21;
private static final int FLAG_DO_NOT_SPELL_CHECK = 1 << 22;
private static final int FLAG_COMMIT_ON_SEL_CHANGE = 1 << 26;
+
+ /**
+ * @see PDFieldTreeNode#PDFieldTreeNode(PDAcroForm)
+ *
+ * @param theAcroForm The acroform.
+ */
+ protected PDChoice(PDAcroForm theAcroForm)
+ {
+ super( theAcroForm );
+ }
/**
* Constructor.
@@ -58,35 +68,75 @@ public abstract class PDChoice extends P
/**
* This will get the option values "Opt".
- *
- * @return COSArray containing all options.
+ *
+ * <p>
+ * For a choice field the options array can either be an array
+ * of text strings or an array of a two-element arrays.<br/>
+ * The method always only returns either the text strings or,
+ * in case of two-element arrays, an array of the first element of
+ * the two-element arrays
+ * </p>
+ * <p>
+ * Use {@link #getOptionsExportValues()} and {@link #getOptionsDisplayValues()}
+ * to get the entries of two-element arrays.
+ * </p>
+ *
+ * @return List containing the export values.
*/
public List<String> getOptions()
{
- COSBase value = getDictionary().getDictionaryObject(COSName.V);
- if (value instanceof COSString)
+ COSBase values = getDictionary().getDictionaryObject(COSName.OPT);
+ if (values instanceof COSString)
{
List<String> array = new ArrayList<String>();
- array.add(((COSString) value).getString());
+ array.add(((COSString) values).getString());
return array;
}
- else if (value instanceof COSArray)
+ else if (values instanceof COSArray)
{
- return COSArrayList.convertCOSStringCOSArrayToList((COSArray)value);
+ // test if there is a single text or a two-element array
+ COSBase entry = ((COSArray) values).get(0);
+ if (entry instanceof COSString)
+ {
+ return COSArrayList.convertCOSStringCOSArrayToList((COSArray)values);
+ }
+ else
+ {
+ List<String> exportValues = new ArrayList<String>();
+ int numItems = ((COSArray) values).size();
+ for (int i=0;i<numItems;i++)
+ {
+ COSArray pair = (COSArray) ((COSArray) values).get(i);
+ COSString displayValue = (COSString) pair.get(0);
+ exportValues.add(displayValue.getString());
+ }
+ return exportValues;
+ }
+
}
return Collections.<String>emptyList();
}
/**
- * This will set the options.
+ * This will set the display values - the 'Opt' key.
+ *
+ * <p>
+ * The Opt array specifies the list of options in the choice field either
+ * as an array of text strings representing the display value
+ * or as an array of a two-element array where the
+ * first element is the export value and the second the display value.
+ * </p>
+ * <p>
+ * To set both the export and the display value use {@link #setOptions(List, List)}
+ * </p>
*
- * @param values COSArray containing all possible options.
+ * @param displayValues List containing all possible options.
*/
- public void setOptions(List<String> values)
+ public void setOptions(List<String> displayValues)
{
- if (values != null)
+ if (displayValues != null)
{
- getDictionary().setItem(COSName.OPT, COSArrayList.convertStringListToCOSStringCOSArray(values));
+ getDictionary().setItem(COSName.OPT, COSArrayList.convertStringListToCOSStringCOSArray(displayValues));
}
else
{
@@ -95,6 +145,116 @@ public abstract class PDChoice extends P
}
/**
+ * This will set the display and export values - the 'Opt' key.
+ *
+ * <p>
+ * This will set both, the export value and the display value
+ * of the choice field. If either one of the parameters is null or an
+ * empty list is supplied the options will
+ * be removed.
+ * </p>
+ * <p>
+ * An {@link IllegalArgumentException} will be thrown if the
+ * number of items in the list differ.
+ * </p>
+ *
+ * @see #setOptions(List)
+ * @param exportValues List containing all possible export values.
+ * @param displayValues List containing all possible display values.
+ */
+ public void setOptions(List<String> exportValues, List<String> displayValues)
+ {
+ if (exportValues == null || displayValues == null || exportValues.size() == 0 || displayValues.size() == 0)
+ {
+ getDictionary().removeItem(COSName.OPT);
+ }
+ else if (exportValues != null && displayValues != null && exportValues.size() > 0 && displayValues.size() > 0)
+ {
+ if (exportValues.size() != displayValues.size())
+ {
+ throw new IllegalArgumentException(
+ "The number of entries for exportValue and displayValue shall be the same.");
+ }
+ else
+ {
+ COSArray options = new COSArray();
+ for (int i = 0; i<exportValues.size(); i++)
+ {
+ COSArray entry = new COSArray();
+ entry.add(new COSString(exportValues.get(i)));
+ entry.add(new COSString(displayValues.get(i)));
+ options.add(entry);
+ }
+ getDictionary().setItem(COSName.OPT, options);
+ }
+ }
+ }
+
+ /**
+ * This will get the display values from the options.
+ *
+ * <p>
+ * For options with an array of text strings the display value and export value
+ * are the same.<br/>
+ * For options with an array of two-element arrays the display value is the
+ * second entry in the two-element array.
+ * </p>
+ *
+ * @return List containing all the display values.
+ */
+ public List<String> getOptionsDisplayValues()
+ {
+ COSBase values = getDictionary().getDictionaryObject(COSName.OPT);
+ if (values instanceof COSString)
+ {
+ List<String> array = new ArrayList<String>();
+ array.add(((COSString) values).getString());
+ return array;
+ }
+ else if (values instanceof COSArray)
+ {
+ // test if there is a single text or a two-element array
+ COSBase entry = ((COSArray) values).get(0);
+ if (entry instanceof COSString)
+ {
+ return COSArrayList.convertCOSStringCOSArrayToList((COSArray)values);
+ }
+ else
+ {
+ List<String> displayValues = new ArrayList<String>();
+ int numItems = ((COSArray) values).size();
+ for (int i=0;i<numItems;i++)
+ {
+ COSArray pair = (COSArray) ((COSArray) values).get(i);
+ COSString displayValue = (COSString) pair.get(1);
+ displayValues.add(displayValue.getString());
+ }
+ return displayValues;
+ }
+
+ }
+ return Collections.<String>emptyList();
+ }
+
+ /**
+ * This will get the export values from the options.
+ *
+ * <p>
+ * For options with an array of text strings the display value and export value
+ * are the same.<br/>
+ * For options with an array of two-element arrays the export value is the
+ * first entry in the two-element array.
+ * </p>
+ *
+ * @return List containing all export values.
+ */
+ public List<String> getOptionsExportValues()
+ {
+ return getOptions();
+ }
+
+
+ /**
* This will get the indices of the selected options "I".
*
* @return COSArray containing the indices of all selected options.
@@ -316,7 +476,7 @@ public abstract class PDChoice extends P
return indexSelected;
}
- // TODO the implementation below is not inline
+ // TODO the implementation below is not in line
// with the specification nor does it allow multiple selections
// deactivating for now as it's not part of the public API
//
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDListBox.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDListBox.java?rev=1651462&r1=1651461&r2=1651462&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDListBox.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/form/PDListBox.java Tue Jan 13 19:59:34 2015
@@ -26,6 +26,17 @@ import org.apache.pdfbox.cos.COSName;
*/
public final class PDListBox extends PDChoice
{
+
+ /**
+ * @see PDFieldTreeNode#PDFieldTreeNode(PDAcroForm)
+ *
+ * @param theAcroForm The acroform.
+ */
+ protected PDListBox(PDAcroForm theAcroForm)
+ {
+ super( theAcroForm );
+ }
+
/**
* Constructor.
*
Added: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java?rev=1651462&view=auto
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java (added)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java Tue Jan 13 19:59:34 2015
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+package org.apache.pdfbox.pdmodel.interactive.form;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+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.COSName;
+import org.apache.pdfbox.pdmodel.PDDocument;
+
+/**
+ * This will test the functionality of choice fields in PDFBox.
+ *
+ * @author Maruan Sahyoun
+ */
+public class TestListBox extends TestCase
+{
+
+ /**
+ * Constructor.
+ *
+ * @param name The name of the test to run.
+ */
+ public TestListBox( 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( TestListBox.class );
+ }
+
+ /**
+ * infamous main method.
+ *
+ * @param args The command line arguments.
+ */
+ public static void main( String[] args )
+ {
+ String[] arg = {TestListBox.class.getName() };
+ junit.textui.TestRunner.main( arg );
+ }
+
+ /**
+ * This will test the radio button PDModel.
+ *
+ * @throws IOException If there is an error creating the field.
+ */
+ public void testChoicePDModel() throws IOException
+ {
+ PDDocument doc = null;
+ try
+ {
+ doc = new PDDocument();
+ PDAcroForm form = new PDAcroForm( doc );
+ PDChoice choice = new PDListBox(form);
+
+ // test that there are no nulls returned for an empty field
+ // only specific methods are tested here
+ // assertNotNull(choice.getDefaultValue());
+ assertNotNull(choice.getOptions());
+ assertNotNull(choice.getValue());
+
+ // define display and export values as the choice field can hold a pair
+ List<String> exportValues = new ArrayList<String>();
+ exportValues.add("export01");
+ exportValues.add("export02");
+
+ List<String> displayValues = new ArrayList<String>();
+ displayValues.add("display01");
+ displayValues.add("display02");
+
+ // test with exportValue being set
+
+ // setting/getting option values - the dictionaries Opt entry
+ choice.setOptions(exportValues);
+ assertEquals(exportValues,choice.getOptionsDisplayValues());
+ assertEquals(exportValues,choice.getOptionsExportValues());
+
+ COSArray optItem = (COSArray) choice.getDictionary().getItem(COSName.OPT);
+
+ // assert that the values have been correctly set
+ assertNotNull(choice.getDictionary().getItem(COSName.OPT));
+ assertEquals(optItem.size(),2);
+ assertEquals(exportValues.get(0), optItem.getString(0));
+
+ // assert that the values can be retrieved correctly
+ List<String> retrievedOptions = choice.getOptions();
+ assertEquals(retrievedOptions.size(),2);
+ assertEquals(retrievedOptions, exportValues);
+
+ // assert that the Opt entry is removed
+ choice.setOptions(null);
+ assertNull(choice.getDictionary().getItem(COSName.OPT));
+ // if there is no Opt entry an empty List shall be returned
+ assertEquals(choice.getOptions(), Collections.<String>emptyList());
+
+ // test with exportValue and displayValue being set
+
+ // setting display and export value
+ choice.setOptions(exportValues, displayValues);
+ assertEquals(displayValues,choice.getOptionsDisplayValues());
+ assertEquals(exportValues,choice.getOptionsExportValues());
+
+ // assert that the Opt entry is removed
+ choice.setOptions(null, displayValues);
+ assertNull(choice.getDictionary().getItem(COSName.OPT));
+ // if there is no Opt entry an empty List shall be returned
+ assertEquals(choice.getOptions(), Collections.<String>emptyList());
+ assertEquals(choice.getOptionsDisplayValues(), Collections.<String>emptyList());
+ assertEquals(choice.getOptionsExportValues(), Collections.<String>emptyList());
+
+ // test that an IllegalArgumentException is thrown when export and display
+ // value lists have different sizes
+ exportValues.remove(1);
+
+ try
+ {
+ choice.setOptions(exportValues, displayValues);
+ fail( "Missing exception" );
+ }
+ catch( IllegalArgumentException e )
+ {
+ assertEquals(
+ "The number of entries for exportValue and displayValue shall be the same.",
+ e.getMessage() );
+ }
+ }
+ finally
+ {
+ if( doc != null )
+ {
+ doc.close();
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/interactive/form/TestListBox.java
------------------------------------------------------------------------------
svn:mime-type = text/plain