⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmpiteratorimpl.java

📁 flash xmp sdk,flash官方SDK
💻 JAVA
字号:
// =================================================================================================// ADOBE SYSTEMS INCORPORATED// Copyright 2006-2007 Adobe Systems Incorporated// All Rights Reserved//// NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the terms// of the Adobe license agreement accompanying it.// =================================================================================================package com.adobe.xmp.impl;import java.util.Collections;import java.util.Iterator;import java.util.NoSuchElementException;import com.adobe.xmp.XMPError;import com.adobe.xmp.XMPException;import com.adobe.xmp.XMPIterator;import com.adobe.xmp.impl.xpath.XMPPath;import com.adobe.xmp.impl.xpath.XMPPathParser;import com.adobe.xmp.options.IteratorOptions;import com.adobe.xmp.options.PropertyOptions;import com.adobe.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 Object value = node.getOptions().isSchemaNode() ? null : node.getValue();						return new XMPPropertyInfo()			{				public String getNamespace()				{					return baseNS;				}					public String getPath()				{					return path;				}								public Object 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;			}		}			}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -