org.apache.pdfbox.pdmodel.common.PDNumberTreeNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pdfbox Show documentation
Show all versions of pdfbox Show documentation
The Apache PDFBox library is an open source Java tool for working with PDF documents.
/*
* 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.common;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSInteger;
import org.apache.pdfbox.cos.COSName;
/**
* This class represents a PDF Number tree. See the PDF Reference 1.7 section
* 7.9.7 for more details.
*
* @author Ben Litchfield,
* @author Igor Podolskiy
*/
public class PDNumberTreeNode implements COSObjectable
{
private static final Log LOG = LogFactory.getLog( PDNumberTreeNode.class );
private final COSDictionary node;
private Class valueType = null;
/**
* Constructor.
*
* @param valueClass The PD Model type of object that is the value.
*/
public PDNumberTreeNode( Class valueClass )
{
node = new COSDictionary();
valueType = valueClass;
}
/**
* Constructor.
*
* @param dict The dictionary that holds the name information.
* @param valueClass The PD Model type of object that is the value.
*/
public PDNumberTreeNode( COSDictionary dict, Class valueClass )
{
node = dict;
valueType = valueClass;
}
/**
* Convert this standard java object to a COS object.
*
* @return The cos object that matches this Java object.
*/
@Override
public COSDictionary getCOSObject()
{
return node;
}
/**
* Return the children of this node. This list will contain PDNumberTreeNode objects.
*
* @return The list of children or null if there are no children.
*/
public List getKids()
{
List retval = null;
COSArray kids = (COSArray)node.getDictionaryObject( COSName.KIDS );
if( kids != null )
{
List pdObjects = new ArrayList();
for( int i=0; i(pdObjects,kids);
}
return retval;
}
/**
* Set the children of this number tree.
*
* @param kids The children of this number tree.
*/
public void setKids( List kids )
{
if (kids != null && !kids.isEmpty())
{
PDNumberTreeNode firstKid = kids.get(0);
PDNumberTreeNode lastKid = kids.get(kids.size() - 1);
Integer lowerLimit = firstKid.getLowerLimit();
this.setLowerLimit(lowerLimit);
Integer upperLimit = lastKid.getUpperLimit();
this.setUpperLimit(upperLimit);
}
else if ( node.getDictionaryObject( COSName.NUMS ) == null )
{
// Remove limits if there are no kids and no numbers set.
node.setItem( COSName.LIMITS, null);
}
node.setItem( COSName.KIDS, COSArrayList.converterToCOSArray( kids ) );
}
/**
* Returns the value corresponding to an index in the number tree.
*
* @param index The index in the number tree.
*
* @return The value corresponding to the index.
*
* @throws IOException If there is a problem creating the values.
*/
public Object getValue(Integer index) throws IOException
{
Map names = getNumbers();
if (names != null)
{
return names.get(index);
}
Object retval = null;
List kids = getKids();
if (kids != null)
{
for (int i = 0; i < kids.size() && retval == null; i++)
{
PDNumberTreeNode childNode = kids.get(i);
if (childNode.getLowerLimit().compareTo(index) <= 0 &&
childNode.getUpperLimit().compareTo(index) >= 0)
{
retval = childNode.getValue(index);
}
}
}
else
{
LOG.warn("NumberTreeNode does not have \"nums\" nor \"kids\" objects.");
}
return retval;
}
/**
* This will return a map of numbers. The key will be a java.lang.Integer, the value will
* depend on where this class is being used.
*
* @return A map of COS objects.
*
* @throws IOException If there is a problem creating the values.
*/
public Map getNumbers() throws IOException
{
Map indices = null;
COSBase numBase = node.getDictionaryObject(COSName.NUMS);
if (numBase instanceof COSArray)
{
COSArray namesArray = (COSArray) numBase;
indices = new HashMap();
for( int i=0; i numbers )
{
if( numbers == null )
{
node.setItem( COSName.NUMS, (COSObjectable)null );
node.setItem( COSName.LIMITS, (COSObjectable)null);
}
else
{
List keys = new ArrayList( numbers.keySet() );
Collections.sort( keys );
COSArray array = new COSArray();
for (Integer key : keys)
{
array.add( COSInteger.get( key ) );
COSObjectable obj = numbers.get( key );
array.add( obj );
}
Integer lower = null;
Integer upper = null;
if (!keys.isEmpty())
{
lower = keys.get( 0 );
upper = keys.get( keys.size()-1 );
}
setUpperLimit( upper );
setLowerLimit( lower );
node.setItem( COSName.NUMS, array );
}
}
/**
* Get the highest value for a key in the name map.
*
* @return The highest value for a key in the map.
*/
public Integer getUpperLimit()
{
Integer retval = null;
COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
if( arr != null && arr.get(0) != null )
{
retval = arr.getInt( 1 );
}
return retval;
}
/**
* Set the highest value for the key in the map.
*
* @param upper The new highest value for a key in the map.
*/
private void setUpperLimit( Integer upper )
{
COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
if( arr == null )
{
arr = new COSArray();
arr.add( null );
arr.add( null );
node.setItem( COSName.LIMITS, arr );
}
if ( upper != null)
{
arr.setInt( 1, upper);
}
else
{
arr.set( 1, null );
}
}
/**
* Get the lowest value for a key in the name map.
*
* @return The lowest value for a key in the map.
*/
public Integer getLowerLimit()
{
Integer retval = null;
COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
if( arr != null && arr.get(0) != null )
{
retval = arr.getInt( 0 );
}
return retval;
}
/**
* Set the lowest value for the key in the map.
*
* @param lower The new lowest value for a key in the map.
*/
private void setLowerLimit( Integer lower )
{
COSArray arr = (COSArray)node.getDictionaryObject( COSName.LIMITS );
if( arr == null )
{
arr = new COSArray();
arr.add( null );
arr.add( null );
node.setItem( COSName.LIMITS, arr );
}
if ( lower != null )
{
arr.setInt( 0, lower);
}
else
{
arr.set( 0, null );
}
}
}