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

📄 xmpnodeutils.java

📁 flash xmp sdk,flash官方SDK
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// =================================================================================================// 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.Calendar;import java.util.Iterator;import com.adobe.xmp.XMPConst;import com.adobe.xmp.XMPDateTime;import com.adobe.xmp.XMPDateTimeFactory;import com.adobe.xmp.XMPError;import com.adobe.xmp.XMPException;import com.adobe.xmp.XMPMetaFactory;import com.adobe.xmp.XMPUtils;import com.adobe.xmp.impl.xpath.XMPPath;import com.adobe.xmp.impl.xpath.XMPPathSegment;import com.adobe.xmp.options.AliasOptions;import com.adobe.xmp.options.PropertyOptions;/** * Utilities for <code>XMPNode</code>. *  * @since   Aug 28, 2006 */public class XMPNodeUtils implements XMPConst{	/** */	static final int CLT_NO_VALUES = 0;	/** */	static final int CLT_SPECIFIC_MATCH = 1;	/** */	static final int CLT_SINGLE_GENERIC = 2;	/** */	static final int CLT_MULTIPLE_GENERIC = 3;	/** */	static final int CLT_XDEFAULT = 4;	/** */	static final int CLT_FIRST_ITEM = 5;	/**	 * Private Constructor	 */	private XMPNodeUtils()	{		// EMPTY	}		/**	 * Find or create a schema node if <code>createNodes</code> is false and	 *  	 * @param tree the root of the xmp tree. 	 * @param namespaceURI a namespace	 * @param createNodes a flag indicating if the node shall be created if not found.	 * 		  <em>Note:</em> The namespace must be registered prior to this call.	 * 	 * @return Returns the schema node if found, <code>null</code> otherwise.	 * 		   Note: If <code>createNodes</code> is <code>true</code>, it is <b>always</b>	 * 		   returned a valid node. 	 * @throws XMPException An exception is only thrown if an error occurred, not if a	 *         		node was not found.	 */	static XMPNode findSchemaNode(XMPNode tree, String namespaceURI,			boolean createNodes)			throws XMPException	{		return findSchemaNode(tree, namespaceURI, null, createNodes);	}			/**	 * Find or create a schema node if <code>createNodes</code> is true.	 *  	 * @param tree the root of the xmp tree. 	 * @param namespaceURI a namespace	 * @param suggestedPrefix If a prefix is suggested, the namespace is allowed to be registered.	 * @param createNodes a flag indicating if the node shall be created if not found.	 * 		  <em>Note:</em> The namespace must be registered prior to this call.	 * 	 * @return Returns the schema node if found, <code>null</code> otherwise.	 * 		   Note: If <code>createNodes</code> is <code>true</code>, it is <b>always</b>	 * 		   returned a valid node. 	 * @throws XMPException An exception is only thrown if an error occurred, not if a	 *         		node was not found.	 */	static XMPNode findSchemaNode(XMPNode tree, String namespaceURI, String suggestedPrefix,			boolean createNodes)			throws XMPException	{		assert tree.getParent() == null; // make sure that its the root		XMPNode schemaNode = tree.findChildByName(namespaceURI);				if (schemaNode == null  &&  createNodes)		{			schemaNode = new XMPNode(namespaceURI, 				new PropertyOptions()					.setSchemaNode(true));			schemaNode.setImplicit(true);						// only previously registered schema namespaces are allowed in the XMP tree.			String prefix = XMPMetaFactory.getSchemaRegistry().getNamespacePrefix(namespaceURI);			if (prefix == null)			{					if (suggestedPrefix != null  &&  suggestedPrefix.length() != 0)				{					prefix = XMPMetaFactory.getSchemaRegistry().registerNamespace(namespaceURI,							suggestedPrefix);				}				else				{					throw new XMPException("Unregistered schema namespace URI",							XMPError.BADSCHEMA);				}				}								schemaNode.setValue(prefix);				tree.addChild(schemaNode);		}				return schemaNode;	}		/**	 * Find or create a child node under a given parent node. If the parent node is no 	 * Returns the found or created child node.	 * 	 * @param parent	 *            the parent node	 * @param childName	 *            the node name to find	 * @param createNodes	 *            flag, if new nodes shall be created.	 * @return Returns the found or created node or <code>null</code>.	 * @throws XMPException Thrown if 	 */	static XMPNode findChildNode(XMPNode parent, String childName, boolean createNodes)			throws XMPException	{		if (!parent.getOptions().isSchemaNode() && !parent.getOptions().isStruct())		{			if (!parent.isImplicit())			{				throw new XMPException("Named children only allowed for schemas and structs",						XMPError.BADXPATH);			}				else if (parent.getOptions().isArray())			{				throw new XMPException("Named children not allowed for arrays",						XMPError.BADXPATH);			}			else if (createNodes)			{					parent.getOptions().setStruct(true);			}			}					XMPNode childNode = parent.findChildByName(childName); 				if (childNode == null  &&  createNodes)		{			PropertyOptions options = new PropertyOptions();			childNode = new XMPNode(childName, options);			childNode.setImplicit(true);			parent.addChild(childNode);		}				assert childNode != null ||  !createNodes;			return childNode;	}	/**	 * Follow an expanded path expression to find or create a node.	 * 	 * @param xmpTree the node to begin the search. 	 * @param xpath the complete xpath	 * @param createNodes flag if nodes shall be created 	 * 			(when called by <code>setProperty()</code>)	 * @param leafOptions the options for the created leaf nodes (only when	 *			<code>createNodes == true</code>).	 * @return Returns the node if found or created or <code>null</code>.	 * @throws XMPException An exception is only thrown if an error occurred, 	 * 			not if a node was not found.	 */	static XMPNode findNode(XMPNode xmpTree, XMPPath xpath, boolean createNodes,		PropertyOptions leafOptions) throws XMPException	{		// check if xpath is set.		if (xpath == null  ||  xpath.size() == 0)		{			throw new XMPException("Empty XMPPath", XMPError.BADXPATH);		}		// Root of implicitly created subtree to possible delete it later. 		// Valid only if leaf is new.		XMPNode rootImplicitNode = null; 		XMPNode currNode = null;				// resolve schema step		currNode = findSchemaNode(xmpTree,			xpath.getSegment(XMPPath.STEP_SCHEMA).getName(), createNodes);		if (currNode == null) 		{			return null;		}		else if (currNode.isImplicit())		{			currNode.setImplicit(false);	// Clear the implicit node bit.			rootImplicitNode = currNode;	// Save the top most implicit node.		}		// Now follow the remaining steps of the original XMPPath.		try		{			for (int i = 1; i < xpath.size(); i++)			{				currNode = followXPathStep(currNode, xpath.getSegment(i), createNodes);				if (currNode == null) 				{					if (createNodes)					{							// delete implicitly created nodes						deleteNode(rootImplicitNode);					}						return null;				}				else if (currNode.isImplicit())				{					// clear the implicit node flag					currNode.setImplicit(false);					// if node is an ALIAS (can be only in root step, auto-create array 					// when the path has been resolved from a not simple alias type					if (i == 1  &&  						xpath.getSegment(i).isAlias()  &&						xpath.getSegment(i).getAliasForm() != 0)					{						currNode.getOptions().setOption(xpath.getSegment(i).getAliasForm(), true);					}					// "CheckImplicitStruct" in C++					else if (i < xpath.size() - 1  &&						xpath.getSegment(i).getKind() == XMPPath.STRUCT_FIELD_STEP  &&							!currNode.getOptions().isCompositeProperty())					{						currNode.getOptions().setStruct(true);					}															if (rootImplicitNode == null)					{						rootImplicitNode = currNode;	// Save the top most implicit node.					}				}			}		}		catch (XMPException e)		{			// if new notes have been created prior to the error, delete them			if (rootImplicitNode != null)			{				deleteNode(rootImplicitNode);			}			throw e;		}						if (rootImplicitNode != null)		{			// set options only if a node has been successful created			currNode.getOptions().mergeWith(leafOptions);			currNode.setOptions(currNode.getOptions());		}				return currNode;	}	/**	 * Deletes the the given node and its children from its parent.	 * Takes care about adjusting the flags.	 * @param node the top-most node to delete.	 */	static void deleteNode(XMPNode node)	{		XMPNode parent = node.getParent();				if (node.getOptions().isQualifier())		{			// root is qualifier			parent.removeQualifier(node);		}		else		{			// root is NO qualifier			parent.removeChild(node);		}				// delete empty Schema nodes		if (!parent.hasChildren()  &&  parent.getOptions().isSchemaNode())		{			parent.getParent().removeChild(parent);		}	}	/**	 * This is setting the value of a leaf node.	 * 	 * @param node an XMPNode	 * @param value a value	 */	static void setNodeValue(XMPNode node, Object value)	{		String strValue = serializeNodeValue(value);		if (!(node.getOptions().isQualifier()  &&  XML_LANG.equals(node.getName()))) 		{				node.setValue(strValue);		}		else		{			node.setValue(Utils.normalizeLangValue(strValue));		}	}			/**	 * Verifies the PropertyOptions for consistancy and updates them as needed. 	 * If options are <code>null</code> they are created with default values.	 *  	 * @param options the <code>PropertyOptions</code>	 * @param itemValue the node value to set	 * @return Returns the updated options.	 * @throws XMPException If the options are not consistant. 	 */	static PropertyOptions verifySetOptions(PropertyOptions options, Object itemValue)			throws XMPException	{		// create empty and fix existing options		if (options == null)		{			// set default options			options = new PropertyOptions();		}				if (options.isArrayAltText())		{			options.setArrayAlternate(true);		}			if (options.isArrayAlternate())		{			options.setArrayOrdered(true);		}			if (options.isArrayOrdered())		{			options.setArray(true);		}			if (options.isCompositeProperty() && itemValue != null && itemValue.toString().length() > 0)		{			throw new XMPException("Structs and arrays can't have values",				XMPError.BADOPTIONS);		}			options.assertConsistency(options.getOptions());				return options;	}	/**	 * Converts the node value to String, apply special conversions for defined	 * types in XMP.	 * 	 * @param value	 *            the node value to set	 * @return Returns the String representation of the node value.	 */	static String serializeNodeValue(Object value)	{		String strValue;		if (value == null)		{			strValue = null;		}		else if (value instanceof Boolean)		{			strValue = XMPUtils.convertFromBoolean(((Boolean) value).booleanValue());		}		else if (value instanceof Integer)		{			strValue = XMPUtils.convertFromInteger(((Integer) value).intValue());		}		else if (value instanceof Long)		{			strValue = XMPUtils.convertFromLong(((Long) value).longValue());		}		else if (value instanceof Double)		{			strValue = XMPUtils.convertFromDouble(((Double) value).doubleValue());		}		else if (value instanceof XMPDateTime)		{			strValue = XMPUtils.convertFromDate((XMPDateTime) value);		}		else if (value instanceof Calendar)		{			XMPDateTime dt = XMPDateTimeFactory.createFromCalendar((Calendar) value);			strValue = XMPUtils.convertFromDate(dt);		}		else if (value instanceof byte[])		{			strValue = XMPUtils.encodeBase64((byte[]) value);		}		else		{			strValue = value.toString();		}			return strValue != null ? Utils.removeControlChars(strValue) : null;	}			/** 	 * After processing by ExpandXPath, a step can be of these forms:	 * <ul>	 * 	<li>qualName - A top level property or struct field.	 * <li>[index] - An element of an array.	 * <li>[last()] - The last element of an array.	 * <li>[qualName="value"] - An element in an array of structs, chosen by a field value.	 * <li>[?qualName="value"] - An element in an array, chosen by a qualifier value.	 * <li>?qualName - A general qualifier.	 * </ul>	 * Find the appropriate child node, resolving aliases, and optionally creating nodes.	 * 	 * @param parentNode the node to start to start from 	 * @param nextStep the xpath segment 	 * @param createNodes 	 * @return returns the found or created XMPPath node 	 * @throws XMPException 	 */	private static XMPNode followXPathStep(				XMPNode parentNode, 				XMPPathSegment nextStep,				boolean createNodes) throws XMPException	{		XMPNode nextNode = null;		int index = 0;		int stepKind = nextStep.getKind();				if (stepKind == XMPPath.STRUCT_FIELD_STEP)		{			nextNode = findChildNode(parentNode, nextStep.getName(), createNodes);

⌨️ 快捷键说明

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