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

📄 xmpnormalizer.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.HashMap;import java.util.Iterator;import java.util.Map;import com.adobe.xmp.XMPConst;import com.adobe.xmp.XMPDateTime;import com.adobe.xmp.XMPError;import com.adobe.xmp.XMPException;import com.adobe.xmp.XMPMeta;import com.adobe.xmp.XMPMetaFactory;import com.adobe.xmp.XMPUtils;import com.adobe.xmp.impl.xpath.XMPPath;import com.adobe.xmp.impl.xpath.XMPPathParser;import com.adobe.xmp.options.ParseOptions;import com.adobe.xmp.options.PropertyOptions;import com.adobe.xmp.properties.XMPAliasInfo;/** * @since   Aug 18, 2006 */public class XMPNormalizer{	/** caches the correct dc-property array forms */	private static Map dcArrayForms;	/** init char tables */	static	{		initDCArrays();	}			/**	 * Hidden constructor	 */	private XMPNormalizer()	{		// EMPTY	}		/**	 * Normalizes a raw parsed XMPMeta-Object	 * @param xmp the raw metadata object	 * @param options the parsing options	 * @return Returns the normalized metadata object	 * @throws XMPException Collects all severe processing errors. 	 */	static XMPMeta process(XMPMetaImpl xmp, ParseOptions options) throws XMPException 	{		XMPNode tree = xmp.getRoot();		touchUpDataModel(xmp);		moveExplicitAliases(tree, options);				tweakOldXMP(tree);				deleteEmptySchemas(tree);				return xmp;	}			/**	 * Tweak old XMP: Move an instance ID from rdf:about to the	 * <em>xmpMM:InstanceID</em> property. An old instance ID usually looks	 * like &quot;uuid:bac965c4-9d87-11d9-9a30-000d936b79c4&quot;, plus InDesign	 * 3.0 wrote them like &quot;bac965c4-9d87-11d9-9a30-000d936b79c4&quot;. If	 * the name looks like a UUID simply move it to <em>xmpMM:InstanceID</em>,	 * don't worry about any existing <em>xmpMM:InstanceID</em>. Both will	 * only be present when a newer file with the <em>xmpMM:InstanceID</em>	 * property is updated by an old app that uses <em>rdf:about</em>.	 * 	 * @param tree the root of the metadata tree	 * @throws XMPException Thrown if tweaking fails. 	 */	private static void tweakOldXMP(XMPNode tree) throws XMPException	{		if (tree.getName() != null  &&  tree.getName().length() >= Utils.UUID_LENGTH)		{			String nameStr = tree.getName().toLowerCase();			if (nameStr.startsWith("uuid:"))			{				nameStr = nameStr.substring(5);			}						if (Utils.checkUUIDFormat(nameStr))			{					// move UUID to xmpMM:InstanceID and remove it from the root node				XMPPath path = XMPPathParser.expandXPath(XMPConst.NS_XMP_MM, "InstanceID");				XMPNode idNode = XMPNodeUtils.findNode (tree, path, true, null);				if (idNode != null)				{					idNode.setOptions(null);	// Clobber any existing xmpMM:InstanceID.					idNode.setValue("uuid:" + nameStr);					idNode.removeChildren();					idNode.removeQualifiers();							tree.setName(null);				}				else				{						throw new XMPException("Failure creating xmpMM:InstanceID",							XMPError.INTERNALFAILURE);				}				}		}			}		/**	 * Visit all schemas to do general fixes and handle special cases.	 * 	 * @param xmp the metadata object implementation	 * @throws XMPException Thrown if the normalisation fails.	 */	private static void touchUpDataModel(XMPMetaImpl xmp) throws XMPException	{		// make sure the DC schema is existing, because it might be needed within the normalization		// if not touched it will be removed by removeEmptySchemas		XMPNodeUtils.findSchemaNode(xmp.getRoot(), XMPConst.NS_DC, true);				// Do the special case fixes within each schema.		for (Iterator it = xmp.getRoot().iterateChildren(); it.hasNext();)		{			XMPNode currSchema = (XMPNode) it.next();			if (XMPConst.NS_DC.equals(currSchema.getName()))			{				normalizeDCArrays(currSchema);			}			else if (XMPConst.NS_EXIF.equals(currSchema.getName()))			{				// Do a special case fix for exif:GPSTimeStamp.				fixGPSTimeStamp(currSchema);				XMPNode arrayNode = XMPNodeUtils.findChildNode(currSchema, "exif:UserComment",						false);				if (arrayNode != null)				{					repairAltText(arrayNode);				}			}			else if (XMPConst.NS_DM.equals(currSchema.getName()))			{				// Do a special case migration of xmpDM:copyright to				// dc:rights['x-default'].				XMPNode dmCopyright = XMPNodeUtils.findChildNode(currSchema, "xmpDM:copyright",						false);				if (dmCopyright != null)				{					migrateAudioCopyright(xmp, dmCopyright);				}			}			else if (XMPConst.NS_XMP_RIGHTS.equals(currSchema.getName()))			{				XMPNode arrayNode = XMPNodeUtils.findChildNode(currSchema, "xapRights:UsageTerms",						false);							if (arrayNode != null)				{						repairAltText(arrayNode);				}				}		}	}		/**	 * Undo the denormalization performed by the XMP used in Acrobat 5.<br> 	 * If a Dublin Core array had only one item, it was serialized as a simple	 * property. <br>	 * The <code>xml:lang</code> attribute was dropped from an	 * <code>alt-text</code> item if the language was <code>x-default</code>.	 * 	 * @param dcSchema the DC schema node	 * @throws XMPException Thrown if normalization fails	 */	private static void normalizeDCArrays(XMPNode dcSchema) throws XMPException	{		for (int i = 1; i <= dcSchema.getChildrenLength(); i++)		{			XMPNode currProp = dcSchema.getChild(i);						PropertyOptions arrayForm = (PropertyOptions) dcArrayForms.get(currProp.getName());			if (arrayForm == null)			{				continue;			}			else if (currProp.getOptions().isSimple())			{					// create a new array and add the current property as child, 				// if it was formerly simple 				XMPNode newArray = new XMPNode(currProp.getName(), arrayForm);				currProp.setName(XMPConst.ARRAY_ITEM_NAME);				newArray.addChild(currProp);				dcSchema.replaceChild(i, newArray);					// fix language alternatives				if (arrayForm.isArrayAltText()  &&  !currProp.getOptions().getHasLanguage())				{					XMPNode newLang = new XMPNode(XMPConst.XML_LANG, XMPConst.X_DEFAULT, null);					currProp.addQualifier(newLang);				}			}			else			{				// clear array options and add corrected array form if it has been an array before				currProp.getOptions().setOption(					PropertyOptions.ARRAY  |					PropertyOptions.ARRAY_ORDERED  |					PropertyOptions.ARRAY_ALTERNATE  |					PropertyOptions.ARRAY_ALT_TEXT,  					false);				currProp.getOptions().mergeWith(arrayForm);								if (arrayForm.isArrayAltText())				{					// applying for "dc:description", "dc:rights", "dc:title"					repairAltText(currProp);				}			}				}	}		/**	 * Make sure that the array is well-formed AltText. Each item must be simple	 * and have an "xml:lang" qualifier. If repairs are needed, keep simple	 * non-empty items by adding the "xml:lang" with value "x-repair".	 * @param arrayNode the property node of the array to repair.	 * @throws XMPException Forwards unexpected exceptions.	 */	private static void repairAltText(XMPNode arrayNode) throws XMPException	{		if (arrayNode == null  ||  			!arrayNode.getOptions().isArray())		{			// Already OK or not even an array.			return;			}		// fix options		arrayNode.getOptions().setArrayOrdered(true).setArrayAlternate(true).setArrayAltText(true);				for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)		{			XMPNode currChild = (XMPNode) it.next();			if (currChild.getOptions().isCompositeProperty())			{				// Delete non-simple children.				it.remove();			} 			else if (!currChild.getOptions().getHasLanguage())			{				String childValue = currChild.getValue();				if (childValue == null  ||  childValue.length() == 0)				{					// Delete empty valued children that have no xml:lang.					it.remove();				}				else				{					// Add an xml:lang qualifier with the value "x-repair".					XMPNode repairLang = new XMPNode(XMPConst.XML_LANG, "x-repair", null);					currChild.addQualifier(repairLang);				}			}		}			}		/**	 * Visit all of the top level nodes looking for aliases. If there is	 * no base, transplant the alias subtree. If there is a base and strict	 * aliasing is on, make sure the alias and base subtrees match.	 * 	 * @param tree the root of the metadata tree	 * @param options th parsing options	 * @throws XMPException Forwards XMP errors	 */	private static void moveExplicitAliases(XMPNode tree, ParseOptions options)			throws XMPException	{		if (!tree.getHasAliases())		{			return;		}		tree.setHasAliases(false);				boolean strictAliasing = options.getStrictAliasing();		for (Iterator schemaIt = tree.getUnmodifiableChildren().iterator(); schemaIt.hasNext();)		{			XMPNode currSchema = (XMPNode) schemaIt.next();			if (!currSchema.getHasAliases())			{				continue;			}						for (Iterator propertyIt = currSchema.iterateChildren(); propertyIt.hasNext();)			{				XMPNode currProp = (XMPNode) propertyIt.next();								if (!currProp.isAlias())				{					continue;				}								currProp.setAlias(false);					// Find the base path, look for the base schema and root node.				XMPAliasInfo info = XMPMetaFactory.getSchemaRegistry()						.findAlias(currProp.getName());				if (info != null)				{						// find or create schema					XMPNode baseSchema = XMPNodeUtils.findSchemaNode(tree, info							.getNamespace(), null, true);					baseSchema.setImplicit(false);										XMPNode baseNode = XMPNodeUtils							.findChildNode(baseSchema, 								info.getPrefix() + info.getPropName(), false);					if (baseNode == null)					{						if (info.getAliasForm().isSimple())						{							// A top-to-top alias, transplant the property.							// change the alias property name to the base name							String qname = info.getPrefix() + info.getPropName();							currProp.setName(qname);							baseSchema.addChild(currProp);							// remove the alias property							propertyIt.remove();						}						else						{							// An alias to an array item, 							// create the array and transplant the property.							baseNode = new XMPNode(info.getPrefix() + info.getPropName(), info

⌨️ 快捷键说明

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