package com.tom_roush.pdfbox.pdmodel.interactive.form;
import com.tom_roush.pdfbox.cos.COSArray;
import com.tom_roush.pdfbox.cos.COSBase;
import com.tom_roush.pdfbox.cos.COSString;
import com.tom_roush.pdfbox.pdmodel.common.COSArrayList;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* A set of utility methods to help with common AcroForm form and field related functions.
*/
public final class FieldUtils
{
/**
* An implementation of a basic key value pair.
*
* This implementation is used to help sorting the content of
* field option entries with an array of two-element arrays as
* used by choice fields.
*
*/
static class KeyValue
{
private final String key;
private final String value;
KeyValue(final String theKey, final String theValue)
{
this.key = theKey;
this.value = theValue;
}
public String getKey()
{
return this.key;
}
public String getValue()
{
return this.value;
}
@Override
public String toString()
{
return "(" + this.key + ", " + this.value + ")";
}
}
/**
* Comparator to sort KeyValue by key.
*/
static class KeyValueKeyComparator implements Serializable, Comparator<KeyValue>
{
private static final long serialVersionUID = 6715364290007167694L;
@Override
public int compare(KeyValue o1, KeyValue o2)
{
return o1.key.compareTo(o2.key);
}
}
/**
* Comparator to sort KeyValue by value.
*/
static class KeyValueValueComparator implements Serializable, Comparator<KeyValue>
{
private static final long serialVersionUID = -3984095679894798265L;
@Override
public int compare(KeyValue o1, KeyValue o2)
{
return o1.value.compareTo(o2.value);
}
}
/**
* Constructor.
*/
private FieldUtils()
{
}
/**
* Return two related lists as a single list with key value pairs.
*
* @param key the key elements
* @param value the value elements
* @return a sorted list of KeyValue elements.
*/
static List<KeyValue> toKeyValueList(List<String> key, List<String> value)
{
List<KeyValue> list = new ArrayList<KeyValue>();
for(int i =0; i<key.size(); i++)
{
list.add(new FieldUtils.KeyValue(key.get(i),value.get(i)));
}
return list;
}
/**
* Sort two related lists simultaneously by the elements in the key parameter.
*
* @param pairs a list of KeyValue elements
*/
static void sortByValue(List<KeyValue> pairs)
{
Collections.sort(pairs, new FieldUtils.KeyValueValueComparator());
}
/**
* Sort two related lists simultaneously by the elements in the value parameter.
*
* @param pairs a list of KeyValue elements
*/
static void sortByKey(List<KeyValue> pairs)
{
Collections.sort(pairs, new FieldUtils.KeyValueKeyComparator());
}
/**
* Return either one of a list which can have two-element arrays entries.
* <p>
* Some entries in a dictionary can either be an array of elements
* or an array of two-element arrays. This method will either return
* the elements in the array or in case of two-element arrays, the element
* designated by the pair index
* </p>
* <p>
* An {@link IllegalArgumentException} will be thrown if the items contain
* two-element arrays and the index is not 0 or 1.
* </p>
*
* @param items the array of elements or two-element arrays
* @param pairIdx the index into the two-element array
* @return a List of single elements
*/
static List<String> getPairableItems(COSBase items, int pairIdx)
{
if (pairIdx < 0 || pairIdx > 1)
{
throw new IllegalArgumentException("Only 0 and 1 are allowed as an index into two-element arrays");
}
if (items instanceof COSString)
{
List<String> array = new ArrayList<String>();
array.add(((COSString) items).getString());
return array;
}
else if (items instanceof COSArray)
{
// test if there is a single text or a two-element array
COSBase entry = ((COSArray) items).get(0);
if (entry instanceof COSString)
{
return COSArrayList.convertCOSStringCOSArrayToList((COSArray)items);
}
else
{
return getItemsFromPair(items, pairIdx);
}
}
return Collections.emptyList();
}
/**
* Return either one of a list of two-element arrays entries.
*
* @param items the array of elements or two-element arrays
* @param pairIdx the index into the two-element array
* @return a List of single elements
*/
private static List<String> getItemsFromPair(COSBase items, int pairIdx)
{
List<String> exportValues = new ArrayList<String>();
int numItems = ((COSArray) items).size();
for (int i=0;i<numItems;i++)
{
COSArray pair = (COSArray) ((COSArray) items).get(i);
COSString displayValue = (COSString) pair.get(pairIdx);
exportValues.add(displayValue.getString());
}
return exportValues;
}
}