iText 5 itextpdf.jar Source Code

itextpdf.jar is a component in iText 5 Java library to provide core functionalities. iText Java library allows you to generate and manage PDF documents.

The Source Code files are provided at iText GitHub site.

You can compile it to generate your JAR file, using pom.xml as the build configuration file.

The source code of itextpdf-5.5.14.jar is provided below:

✍: FYIcenter.com

com/itextpdf/xmp/impl/XMPIteratorImpl.java

//Copyright (c) 2006, Adobe Systems Incorporated
//All rights reserved.
//
//        Redistribution and use in source and binary forms, with or without
//        modification, are permitted provided that the following conditions are met:
//        1. Redistributions of source code must retain the above copyright
//        notice, this list of conditions and the following disclaimer.
//        2. Redistributions in binary form must reproduce the above copyright
//        notice, this list of conditions and the following disclaimer in the
//        documentation and/or other materials provided with the distribution.
//        3. All advertising materials mentioning features or use of this software
//        must display the following acknowledgement:
//        This product includes software developed by the Adobe Systems Incorporated.
//        4. Neither the name of the Adobe Systems Incorporated nor the
//        names of its contributors may be used to endorse or promote products
//        derived from this software without specific prior written permission.
//
//        THIS SOFTWARE IS PROVIDED BY ADOBE SYSTEMS INCORPORATED ''AS IS'' AND ANY
//        EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//        WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//        DISCLAIMED. IN NO EVENT SHALL ADOBE SYSTEMS INCORPORATED BE LIABLE FOR ANY
//        DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//        (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//        LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//        ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//        (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//        SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//        http://www.adobe.com/devnet/xmp/library/eula-xmp-library-java.html


package com.itextpdf.xmp.impl;

import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;

import com.itextpdf.xmp.XMPError;
import com.itextpdf.xmp.XMPException;
import com.itextpdf.xmp.XMPIterator;
import com.itextpdf.xmp.XMPMetaFactory;
import com.itextpdf.xmp.impl.xpath.XMPPath;
import com.itextpdf.xmp.impl.xpath.XMPPathParser;
import com.itextpdf.xmp.options.IteratorOptions;
import com.itextpdf.xmp.options.PropertyOptions;
import com.itextpdf.xmp.properties.XMPPropertyInfo;


/**
 * The <code>XMPIterator</code> implementation.
 * Iterates the XMP Tree according to a set of options.
 * During the iteration the XMPMeta-object must not be changed.
 * Calls to <code>skipSubtree()</code> / <code>skipSiblings()</code> will affect the iteration.
 *  
 * @since   29.06.2006
 */
public class XMPIteratorImpl implements XMPIterator
{
	/** stores the iterator options */
	private IteratorOptions options;
	/** the base namespace of the property path, will be changed during the iteration */ 
	private String baseNS = null;
	/** flag to indicate that skipSiblings() has been called. */
	protected boolean skipSiblings = false;
	/** flag to indicate that skipSiblings() has been called. */
	protected boolean skipSubtree = false;
	/** the node iterator doing the work */
	private Iterator nodeIterator = null;
	
	
	/**
	 * Constructor with optionsl initial values. If <code>propName</code> is provided, 
	 * <code>schemaNS</code> has also be provided.
	 * @param xmp the iterated metadata object.
	 * @param schemaNS the iteration is reduced to this schema (optional) 
	 * @param propPath the iteration is redurce to this property within the <code>schemaNS</code>
	 * @param options advanced iteration options, see {@link IteratorOptions}
	 * @throws XMPException If the node defined by the paramters is not existing. 
	 */
	public XMPIteratorImpl(XMPMetaImpl xmp, String schemaNS, String propPath,
			IteratorOptions options) throws XMPException
	{
		// make sure that options is defined at least with defaults
		this.options = options != null ? options : new IteratorOptions();
		
		// the start node of the iteration depending on the schema and property filter
		XMPNode startNode = null;
		String initialPath = null;
		boolean baseSchema = schemaNS != null  &&  schemaNS.length() > 0; 
		boolean baseProperty = propPath != null  &&  propPath.length() > 0; 
		
		if (!baseSchema  &&  !baseProperty)
		{
			// complete tree will be iterated
			startNode = xmp.getRoot();
		}
		else if (baseSchema  &&  baseProperty)
		{
			// Schema and property node provided
			XMPPath path = XMPPathParser.expandXPath(schemaNS, propPath);
			
			// base path is the prop path without the property leaf
			XMPPath basePath = new XMPPath();
			for (int i = 0; i < path.size() - 1; i++)
			{
				basePath.add(path.getSegment(i));
			}
			
			startNode = XMPNodeUtils.findNode(xmp.getRoot(), path, false, null);
			baseNS = schemaNS;
			initialPath = basePath.toString();
		}
		else if (baseSchema  &&  !baseProperty)
		{
			// Only Schema provided
			startNode = XMPNodeUtils.findSchemaNode(xmp.getRoot(), schemaNS, false);
		}
		else // !baseSchema  &&  baseProperty
		{
			// No schema but property provided -> error
			throw new XMPException("Schema namespace URI is required", XMPError.BADSCHEMA);
		}			

		
		// create iterator
		if (startNode != null)
		{
			if (!this.options.isJustChildren())
			{	
				nodeIterator = new NodeIterator(startNode, initialPath, 1);
			}
			else
			{
				nodeIterator = new NodeIteratorChildren(startNode, initialPath);
			}
		}
		else
		{
			// create null iterator
			nodeIterator = Collections.EMPTY_LIST.iterator();
		}
	}


	/**
	 * @see XMPIterator#skipSubtree()
	 */
	public void skipSubtree()
	{
		this.skipSubtree = true;
	}

	
	/**
	 * @see XMPIterator#skipSiblings()
	 */
	public void skipSiblings()
	{
		skipSubtree();
		this.skipSiblings = true;
	}
	

	/**
	 * @see java.util.Iterator#hasNext()
	 */
	public boolean hasNext()
	{
		return nodeIterator.hasNext();
	}

	
	/**
	 * @see java.util.Iterator#next()
	 */
	public Object next()
	{
		return nodeIterator.next();
	}

	
	/**
	 * @see java.util.Iterator#remove()
	 */
	public void remove()
	{
		throw new UnsupportedOperationException("The XMPIterator does not support remove().");
	}
	
	
	/**
	 * @return Exposes the options for inner class.
	 */
	protected IteratorOptions getOptions()
	{
		return options;
	}

	
	/**
	 * @return Exposes the options for inner class.
	 */
	protected String getBaseNS()
	{
		return baseNS;
	}

	
	/**
	 * @param baseNS sets the baseNS from the inner class.
	 */
	protected void setBaseNS(String baseNS)
	{
		this.baseNS = baseNS;
	}
	
	
	
	
	
	
	/**
	 * The <code>XMPIterator</code> implementation.
	 * It first returns the node itself, then recursivly the children and qualifier of the node.
	 * 
	 * @since   29.06.2006
	 */
	private class NodeIterator implements Iterator
	{
		/** iteration state */
		protected static final int ITERATE_NODE = 0;
		/** iteration state */
		protected static final int ITERATE_CHILDREN = 1;
		/** iteration state */
		protected static final int ITERATE_QUALIFIER = 2;
		
		/** the state of the iteration */
		private int state = ITERATE_NODE; 
		/** the currently visited node */
		private XMPNode visitedNode;
		/** the recursively accumulated path */
		private String path;
		/** the iterator that goes through the children and qualifier list */
		private Iterator childrenIterator = null;
		/** index of node with parent, only interesting for arrays */
		private int index = 0;
		/** the iterator for each child */
		private Iterator subIterator = Collections.EMPTY_LIST.iterator();
		/** the cached <code>PropertyInfo</code> to return */
		private XMPPropertyInfo returnProperty = null;

		
		/**
		 * Default constructor
		 */
		public NodeIterator()
		{
			// EMPTY
		}
		
		
		/**
		 * Constructor for the node iterator.
		 * @param visitedNode the currently visited node
		 * @param parentPath the accumulated path of the node
		 * @param index the index within the parent node (only for arrays)
		 */
		public NodeIterator(XMPNode visitedNode, String parentPath, int index)
		{
			this.visitedNode = visitedNode;
			this.state = NodeIterator.ITERATE_NODE;
			if (visitedNode.getOptions().isSchemaNode())
			{	
				setBaseNS(visitedNode.getName());
			}

			// for all but the root node and schema nodes
			path = accumulatePath(visitedNode, parentPath, index);
		}

		
		/**
		 * Prepares the next node to return if not already done. 
		 * 
		 * @see Iterator#hasNext()
		 */
		public boolean hasNext()
		{
			if (returnProperty != null)
			{
				// hasNext has been called before
				return true;
			}
			
			// find next node
			if (state == ITERATE_NODE)
			{
				return reportNode();
			}
			else if (state == ITERATE_CHILDREN)
			{
				if (childrenIterator == null)
				{
					childrenIterator = visitedNode.iterateChildren();
				}
				
				boolean hasNext = iterateChildren(childrenIterator);
				
				if (!hasNext  &&  visitedNode.hasQualifier()  &&  !getOptions().isOmitQualifiers()) 
				{
					state = ITERATE_QUALIFIER;
					childrenIterator = null;
					hasNext = hasNext();
				}
				return hasNext;
			}
			else
			{
				if (childrenIterator == null)
				{
					childrenIterator = visitedNode.iterateQualifier();
				}
				
				return iterateChildren(childrenIterator);
			}
		}


		/**
		 * Sets the returnProperty as next item or recurses into <code>hasNext()</code>.
		 * @return Returns if there is a next item to return. 
		 */
		protected boolean reportNode()
		{
			state = ITERATE_CHILDREN;
			if (visitedNode.getParent() != null  &&
				(!getOptions().isJustLeafnodes()  ||  !visitedNode.hasChildren()))
			{	
				returnProperty = createPropertyInfo(visitedNode, getBaseNS(), path);
				return true;
			}
			else
			{
				return hasNext();
			}
		}


		/**
		 * Handles the iteration of the children or qualfier
		 * @param iterator an iterator
		 * @return Returns if there are more elements available.
		 */
		private boolean iterateChildren(Iterator iterator)
		{
			if (skipSiblings)
			{
				// setSkipSiblings(false);
				skipSiblings = false;
				subIterator = Collections.EMPTY_LIST.iterator();
			}
			
			// create sub iterator for every child,
			// if its the first child visited or the former child is finished 
			if ((!subIterator.hasNext())  &&  iterator.hasNext())
			{
				XMPNode child = (XMPNode) iterator.next();
				index++;
				subIterator = new NodeIterator(child, path, index);
			}
			
			if (subIterator.hasNext())
			{
				returnProperty = (XMPPropertyInfo) subIterator.next();
				return true;
			}
			else
			{
				return false;
			}
		}
	
		
		/**
		 * Calls hasNext() and returnes the prepared node. Afterwards its set to null.
		 * The existance of returnProperty indicates if there is a next node, otherwise
		 * an exceptio is thrown.
		 * 
		 * @see Iterator#next()
		 */
		public Object next()
		{
			if (hasNext())
			{
				XMPPropertyInfo result = returnProperty; 
				returnProperty = null;
				return result;
			}
			else
			{
				throw new NoSuchElementException("There are no more nodes to return");
			}
		}
	
		
		/**
		 * Not supported.
		 * @see Iterator#remove()
		 */
		public void remove()
		{
			throw new UnsupportedOperationException();
		}
		
		
		/**
		 * @param currNode the node that will be added to the path.
		 * @param parentPath the path up to this node.
		 * @param currentIndex the current array index if an arrey is traversed
		 * @return Returns the updated path.
		 */
		protected String accumulatePath(XMPNode currNode, String parentPath, int currentIndex)
		{
			String separator;
			String segmentName;
			if (currNode.getParent() == null  ||  currNode.getOptions().isSchemaNode())
			{
				return null;
			}
			else if (currNode.getParent().getOptions().isArray())
			{
				separator = "";
				segmentName = "[" + String.valueOf(currentIndex) + "]";
			}
			else
			{	
				separator = "/";
				segmentName = currNode.getName();
			}
			
			
			if (parentPath == null  ||  parentPath.length() == 0)
			{
				return segmentName;
			}
			else if (getOptions().isJustLeafname())
			{
				return !segmentName.startsWith("?") ? 
					segmentName :
					segmentName.substring(1); // qualifier
			}
			else 
			{
				return parentPath + separator + segmentName;
			}
		}
			
		
		/**
		 * Creates a property info object from an <code>XMPNode</code>.
		 * @param node an <code>XMPNode</code>
		 * @param baseNS the base namespace to report
		 * @param path the full property path
		 * @return Returns a <code>XMPProperty</code>-object that serves representation of the node.
		 */
		protected XMPPropertyInfo createPropertyInfo(final XMPNode node, final String baseNS,
				final String path)
		{
			final String value = node.getOptions().isSchemaNode() ? null : node.getValue();
			
			return new XMPPropertyInfo()
			{
				public String getNamespace()
				{
					if (!node.getOptions().isSchemaNode())
					{	
						// determine namespace of leaf node
						QName qname = new QName(node.getName());
						return XMPMetaFactory.getSchemaRegistry().getNamespaceURI(qname.getPrefix());
					}
					else
					{
						return baseNS;
					}	
				}
	
				public String getPath()
				{
					return path;
				}
				
				public String getValue()
				{
					return value;
				}
	
				public PropertyOptions getOptions()
				{
					return node.getOptions();
				}

				public String getLanguage()
				{
					// the language is not reported
					return null;
				}
			};
		}


		/**
		 * @return the childrenIterator
		 */
		protected  Iterator getChildrenIterator()
		{
			return childrenIterator;
		}


		/**
		 * @param childrenIterator the childrenIterator to set
		 */
		protected void setChildrenIterator(Iterator childrenIterator)
		{
			this.childrenIterator = childrenIterator;
		}

		
		/**
		 * @return Returns the returnProperty.
		 */
		protected XMPPropertyInfo getReturnProperty()
		{
			return returnProperty;
		}
		

		/**
		 * @param returnProperty the returnProperty to set
		 */
		protected  void setReturnProperty(XMPPropertyInfo returnProperty)
		{
			this.returnProperty = returnProperty;
		}
	}
	
	
	/**
	 * This iterator is derived from the default <code>NodeIterator</code>,
	 * and is only used for the option {@link IteratorOptions#JUST_CHILDREN}.
	 * 
	 * @since 02.10.2006
	 */
	private class NodeIteratorChildren extends NodeIterator
	{
		/** */
		private String parentPath;
		/** */
		private Iterator childrenIterator;
		/** */
		private int index = 0;
		
		
		/**
		 * Constructor 
		 * @param parentNode the node which children shall be iterated. 
		 * @param parentPath the full path of the former node without the leaf node.
		 */
		public NodeIteratorChildren(XMPNode parentNode, String parentPath)
		{
			if (parentNode.getOptions().isSchemaNode())
			{	
				setBaseNS(parentNode.getName());
			}
			this.parentPath = accumulatePath(parentNode, parentPath, 1);

			childrenIterator = parentNode.iterateChildren();
		}
		
		
		/**
		 * Prepares the next node to return if not already done. 
		 * 
		 * @see Iterator#hasNext()
		 */
		public boolean hasNext()
		{
			if (getReturnProperty() != null)
			{
				// hasNext has been called before
				return true;
			}
			else if (skipSiblings)
			{
				return false;
			}
			else if (childrenIterator.hasNext())
			{
				XMPNode child = (XMPNode) childrenIterator.next();
				index++;
				
				String path = null;
				if (child.getOptions().isSchemaNode())
				{	
					setBaseNS(child.getName());
				}
				else if (child.getParent() != null)
				{
					// for all but the root node and schema nodes
					path = accumulatePath(child, parentPath, index);
				}

				// report next property, skip not-leaf nodes in case options is set
				if (!getOptions().isJustLeafnodes()  ||  !child.hasChildren())
				{	
					setReturnProperty(createPropertyInfo(child, getBaseNS(), path));
					return true;
				}
				else
				{
					return hasNext();
				}
			}
			else
			{
				return false;
			}
		}		
	}
}

com/itextpdf/xmp/impl/XMPIteratorImpl.java

 

Or download all of them as a single archive file:

File name: itextpdf-5.5.14-fyi.zip
File size: 2163839 bytes
Release date: 2009-10-09
Download 

 

iText-2.1.6.jar - iText, a JAVA-PDF library

iText layout.jar Source Code

Download and Install iText Java Library

⇑⇑ iText for PDF Generation

2021-07-03, 113114👍, 0💬