public static AssertImplementation ( IXmpMeta xmp ) : void | ||
xmp | IXmpMeta | the XMP object |
Результат | void |
/// <seealso cref= XMPUtils#appendProperties(XMPMeta, XMPMeta, boolean, boolean) </seealso> /// <param name="source"> The source XMP object. </param> /// <param name="destination"> The destination XMP object. </param> /// <param name="doAllProperties"> Do internal properties in addition to external properties. </param> /// <param name="replaceOldValues"> Replace the values of existing properties. </param> /// <param name="deleteEmptyValues"> Delete destination values if source property is empty. </param> /// <exception cref="XmpException"> Forwards the Exceptions from the metadata processing </exception> public static void AppendProperties(IXmpMeta source, IXmpMeta destination, bool doAllProperties, bool replaceOldValues, bool deleteEmptyValues) { ParameterAsserts.AssertImplementation(source); ParameterAsserts.AssertImplementation(destination); XmpMetaImpl src = (XmpMetaImpl)source; XmpMetaImpl dest = (XmpMetaImpl)destination; for (IEnumerator it = src.Root.IterateChildren(); it.MoveNext();) { XmpNode sourceSchema = (XmpNode)it.Current; if (sourceSchema == null) { continue; } // Make sure we have a destination schema node XmpNode destSchema = XmpNodeUtils.FindSchemaNode(dest.Root, sourceSchema.Name, false); bool createdSchema = false; if (destSchema == null) { PropertyOptions propertyOptions = new PropertyOptions(); propertyOptions.SchemaNode = true; destSchema = new XmpNode(sourceSchema.Name, sourceSchema.Value, propertyOptions); dest.Root.AddChild(destSchema); createdSchema = true; } // Process the source schema's children. for (IEnumerator ic = sourceSchema.IterateChildren(); ic.MoveNext();) { XmpNode sourceProp = (XmpNode)ic.Current; if (sourceProp == null) { continue; } if (doAllProperties || !Utils.IsInternalProperty(sourceSchema.Name, sourceProp.Name)) { AppendSubtree(dest, sourceProp, destSchema, replaceOldValues, deleteEmptyValues); } } if (!destSchema.HasChildren() && (createdSchema || deleteEmptyValues)) { // Don't create an empty schema / remove empty schema. dest.Root.RemoveChild(destSchema); } } }
/// <summary> /// see {@link XMPUtils#separateArrayItems(XMPMeta, String, String, String, /// PropertyOptions, boolean)} /// </summary> /// <param name="xmp"> /// The XMP object containing the array to be updated. </param> /// <param name="schemaNs"> /// The schema namespace URI for the array. Must not be null or /// the empty string. </param> /// <param name="arrayName"> /// The name of the array. May be a general path expression, must /// not be null or the empty string. Each item in the array must /// be a simple string value. </param> /// <param name="catedStr"> /// The string to be separated into the array items. </param> /// <param name="arrayOptions"> /// Option flags to control the separation. </param> /// <param name="preserveCommas"> /// Flag if commas shall be preserved /// </param> /// <exception cref="XmpException"> /// Forwards the Exceptions from the metadata processing </exception> public static void SeparateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string catedStr, PropertyOptions arrayOptions, bool preserveCommas) { ParameterAsserts.AssertSchemaNs(schemaNs); ParameterAsserts.AssertArrayName(arrayName); if (catedStr == null) { throw new XmpException("Parameter must not be null", XmpError.BADPARAM); } ParameterAsserts.AssertImplementation(xmp); XmpMetaImpl xmpImpl = (XmpMetaImpl)xmp; // Keep a zero value, has special meaning below. XmpNode arrayNode = SeparateFindCreateArray(schemaNs, arrayName, arrayOptions, xmpImpl); // Extract the item values one at a time, until the whole input string is done. int charKind = UCK_NORMAL; char ch = (char)0; int itemEnd = 0; int endPos = catedStr.Length; while (itemEnd < endPos) { string itemValue; int itemStart; // Skip any leading spaces and separation characters. Always skip commas here. // They can be kept when within a value, but not when alone between values. for (itemStart = itemEnd; itemStart < endPos; itemStart++) { ch = catedStr[itemStart]; charKind = ClassifyCharacter(ch); if (charKind == UCK_NORMAL || charKind == UCK_QUOTE) { break; } } if (itemStart >= endPos) { break; } int nextKind; if (charKind != UCK_QUOTE) { // This is not a quoted value. Scan for the end, create an array // item from the substring. for (itemEnd = itemStart; itemEnd < endPos; itemEnd++) { ch = catedStr[itemEnd]; charKind = ClassifyCharacter(ch); if (charKind == UCK_NORMAL || charKind == UCK_QUOTE || (charKind == UCK_COMMA && preserveCommas)) { continue; } if (charKind != UCK_SPACE) { break; } if ((itemEnd + 1) < endPos) { ch = catedStr[itemEnd + 1]; nextKind = ClassifyCharacter(ch); if (nextKind == UCK_NORMAL || nextKind == UCK_QUOTE || (nextKind == UCK_COMMA && preserveCommas)) { continue; } } // Anything left? break; // Have multiple spaces, or a space followed by a // separator. } itemValue = catedStr.Substring(itemStart, itemEnd - itemStart); } else { // Accumulate quoted values into a local string, undoubling // internal quotes that // match the surrounding quotes. Do not undouble "unmatching" // quotes. char openQuote = ch; char closeQuote = GetClosingQuote(openQuote); itemStart++; // Skip the opening quote; itemValue = ""; for (itemEnd = itemStart; itemEnd < endPos; itemEnd++) { ch = catedStr[itemEnd]; charKind = ClassifyCharacter(ch); if (charKind != UCK_QUOTE || !IsSurroundingQuote(ch, openQuote, closeQuote)) { // This is not a matching quote, just append it to the // item value. itemValue += ch; } else { // This is a "matching" quote. Is it doubled, or the // final closing quote? // Tolerate various edge cases like undoubled opening // (non-closing) quotes, // or end of input. char nextChar; if ((itemEnd + 1) < endPos) { nextChar = catedStr[itemEnd + 1]; nextKind = ClassifyCharacter(nextChar); } else { nextKind = UCK_SEMICOLON; nextChar = (char)0x3B; } if (ch == nextChar) { // This is doubled, copy it and skip the double. itemValue += ch; // Loop will add in charSize. itemEnd++; } else if (!IsClosingingQuote(ch, openQuote, closeQuote)) { // This is an undoubled, non-closing quote, copy it. itemValue += ch; } else { // This is an undoubled closing quote, skip it and // exit the loop. itemEnd++; break; } } } } // Add the separated item to the array. // Keep a matching old value in case it had separators. int foundIndex = -1; for (int oldChild = 1; oldChild <= arrayNode.ChildrenLength; oldChild++) { if (itemValue.Equals(arrayNode.GetChild(oldChild).Value)) { foundIndex = oldChild; break; } } if (foundIndex < 0) { XmpNode newItem = new XmpNode(ARRAY_ITEM_NAME, itemValue, null); arrayNode.AddChild(newItem); } } }
/// <seealso cref= XMPUtils#removeProperties(XMPMeta, String, String, boolean, boolean) /// </seealso> /// <param name="xmp"> /// The XMP object containing the properties to be removed. /// </param> /// <param name="schemaNs"> /// Optional schema namespace URI for the properties to be /// removed. /// </param> /// <param name="propName"> /// Optional path expression for the property to be removed. /// </param> /// <param name="doAllProperties"> /// Option flag to control the deletion: do internal properties in /// addition to external properties. </param> /// <param name="includeAliases"> /// Option flag to control the deletion: Include aliases in the /// "named schema" case above. </param> /// <exception cref="XmpException"> If metadata processing fails </exception> public static void RemoveProperties(IXmpMeta xmp, string schemaNs, string propName, bool doAllProperties, bool includeAliases) { ParameterAsserts.AssertImplementation(xmp); XmpMetaImpl xmpImpl = (XmpMetaImpl)xmp; if (!string.IsNullOrEmpty(propName)) { // Remove just the one indicated property. This might be an alias, // the named schema might not actually exist. So don't lookup the // schema node. if (string.IsNullOrEmpty(schemaNs)) { throw new XmpException("Property name requires schema namespace", XmpError.BADPARAM); } XmpPath expPath = XmpPathParser.ExpandXPath(schemaNs, propName); XmpNode propNode = XmpNodeUtils.FindNode(xmpImpl.Root, expPath, false, null); if (propNode != null) { if (doAllProperties || !Utils.IsInternalProperty(expPath.GetSegment((int)XmpPath.STEP_SCHEMA).Name, expPath.GetSegment((int)XmpPath.STEP_ROOT_PROP).Name)) { XmpNode parent = propNode.Parent; parent.RemoveChild(propNode); if (parent.Options.SchemaNode && !parent.HasChildren()) { // remove empty schema node parent.Parent.RemoveChild(parent); } } } } else if (!string.IsNullOrEmpty(schemaNs)) { // Remove all properties from the named schema. Optionally include // aliases, in which case // there might not be an actual schema node. // XMP_NodePtrPos schemaPos; XmpNode schemaNode = XmpNodeUtils.FindSchemaNode(xmpImpl.Root, schemaNs, false); if (schemaNode != null) { if (RemoveSchemaChildren(schemaNode, doAllProperties)) { xmpImpl.Root.RemoveChild(schemaNode); } } if (includeAliases) { // We're removing the aliases also. Look them up by their // namespace prefix. // But that takes more code and the extra speed isn't worth it. // Lookup the XMP node // from the alias, to make sure the actual exists. IXmpAliasInfo[] aliases = XmpMetaFactory.SchemaRegistry.FindAliases(schemaNs); for (int i = 0; i < aliases.Length; i++) { IXmpAliasInfo info = aliases[i]; XmpPath path = XmpPathParser.ExpandXPath(info.Namespace, info.PropName); XmpNode actualProp = XmpNodeUtils.FindNode(xmpImpl.Root, path, false, null); if (actualProp != null) { XmpNode parent = actualProp.Parent; parent.RemoveChild(actualProp); } } } } else { // Remove all appropriate properties from all schema. In this case // we don't have to be // concerned with aliases, they are handled implicitly from the // actual properties. ArrayList schemasToRemove = new ArrayList(); for (IEnumerator it = xmpImpl.Root.IterateChildren(); it.MoveNext();) { XmpNode schema = (XmpNode)it.Current; if (schema == null) { continue; } if (RemoveSchemaChildren(schema, doAllProperties)) { schemasToRemove.Add(schema); } } foreach (XmpNode xmpNode in schemasToRemove) { xmpImpl.Root.Children.Remove(xmpNode); } schemasToRemove.Clear(); } }
/// <seealso cref= XMPUtils#catenateArrayItems(XMPMeta, String, String, String, String, /// boolean) /// </seealso> /// <param name="xmp"> /// The XMP object containing the array to be catenated. </param> /// <param name="schemaNs"> /// The schema namespace URI for the array. Must not be null or /// the empty string. </param> /// <param name="arrayName"> /// The name of the array. May be a general path expression, must /// not be null or the empty string. Each item in the array must /// be a simple string value. </param> /// <param name="separator"> /// The string to be used to separate the items in the catenated /// string. Defaults to "; ", ASCII semicolon and space /// (U+003B, U+0020). </param> /// <param name="quotes"> /// The characters to be used as quotes around array items that /// contain a separator. Defaults to '"' </param> /// <param name="allowCommas"> /// Option flag to control the catenation. </param> /// <returns> Returns the string containing the catenated array items. </returns> /// <exception cref="XmpException"> /// Forwards the Exceptions from the metadata processing </exception> public static string CatenateArrayItems(IXmpMeta xmp, string schemaNs, string arrayName, string separator, string quotes, bool allowCommas) { ParameterAsserts.AssertSchemaNs(schemaNs); ParameterAsserts.AssertArrayName(arrayName); ParameterAsserts.AssertImplementation(xmp); if (string.IsNullOrEmpty(separator)) { separator = "; "; } if (string.IsNullOrEmpty(quotes)) { quotes = "\""; } XmpMetaImpl xmpImpl = (XmpMetaImpl)xmp; // Return an empty result if the array does not exist, // hurl if it isn't the right form. XmpPath arrayPath = XmpPathParser.ExpandXPath(schemaNs, arrayName); XmpNode arrayNode = XmpNodeUtils.FindNode(xmpImpl.Root, arrayPath, false, null); if (arrayNode == null) { return(""); } if (!arrayNode.Options.Array || arrayNode.Options.ArrayAlternate) { throw new XmpException("Named property must be non-alternate array", XmpError.BADPARAM); } // Make sure the separator is OK. CheckSeparator(separator); // Make sure the open and close quotes are a legitimate pair. char openQuote = quotes[0]; char closeQuote = CheckQuotes(quotes, openQuote); // Build the result, quoting the array items, adding separators. // Hurl if any item isn't simple. StringBuilder catinatedString = new StringBuilder(); for (IEnumerator it = arrayNode.IterateChildren(); it.MoveNext();) { XmpNode currItem = (XmpNode)it.Current; if (currItem == null) { continue; } if (currItem.Options.CompositeProperty) { throw new XmpException("Array items must be simple", XmpError.BADPARAM); } string str = ApplyQuotes(currItem.Value, openQuote, closeQuote, allowCommas); catinatedString.Append(str); if (it.MoveNext()) { catinatedString.Append(separator); } } return(catinatedString.ToString()); }