GetQualifier() public method

public GetQualifier ( int index ) : XmpNode
index int an index [1..size]
return XmpNode
示例#1
0
        /// <summary>
        /// Make sure the x-default item is first. Touch up &quot;single value&quot;
        /// arrays that have a default plus one real language. This case should have
        /// the same value for both items. Older Adobe apps were hardwired to only
        /// use the &quot;x-default&quot; item, so we copy that value to the other
        /// item.
        /// </summary>
        /// <param name="arrayNode">
        ///            an alt text array node </param>
        internal static void NormalizeLangArray(XmpNode arrayNode)
        {
            if (!arrayNode.Options.ArrayAltText)
            {
                return;
            }

            // check if node with x-default qual is first place
            for (int i = 2; i <= arrayNode.ChildrenLength; i++)
            {
                XmpNode child = arrayNode.GetChild(i);
                if (child.HasQualifier() && X_DEFAULT.Equals(child.GetQualifier(1).Value))
                {
                    // move node to first place
                    try {
                        arrayNode.RemoveChild(i);
                        arrayNode.AddChild(1, child);
                    }
                    catch (XmpException) {
                        // cannot occur, because same child is removed before
                        Debug.Assert(false);
                    }

                    if (i == 2)
                    {
                        arrayNode.GetChild(2).Value = child.Value;
                    }
                    break;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Looks for the appropriate language item in a text alternative array.item
        /// </summary>
        /// <param name="arrayNode">
        ///            an array node </param>
        /// <param name="language">
        ///            the requested language </param>
        /// <returns> Returns the index if the language has been found, -1 otherwise. </returns>
        /// <exception cref="XmpException"> </exception>
        internal static int LookupLanguageItem(XmpNode arrayNode, string language)
        {
            if (!arrayNode.Options.Array)
            {
                throw new XmpException("Language item must be used on array", XmpError.BADXPATH);
            }

            for (int index = 1; index <= arrayNode.ChildrenLength; index++)
            {
                XmpNode child = arrayNode.GetChild(index);
                if (!child.HasQualifier() || !XML_LANG.Equals(child.GetQualifier(1).Name))
                {
                    continue;
                }
                if (language.Equals(child.GetQualifier(1).Value))
                {
                    return(index);
                }
            }

            return(-1);
        }
示例#3
0
        /// <summary>
        /// Compares two nodes including its children and qualifier. </summary>
        /// <param name="leftNode"> an <code>XMPNode</code> </param>
        /// <param name="rightNode"> an <code>XMPNode</code> </param>
        /// <returns> Returns true if the nodes are equal, false otherwise. </returns>
        /// <exception cref="XmpException"> Forwards exceptions to the calling method. </exception>
        private static bool ItemValuesMatch(XmpNode leftNode, XmpNode rightNode) {
            PropertyOptions leftForm = leftNode.Options;
            PropertyOptions rightForm = rightNode.Options;

            if (leftForm.Equals(rightForm)) {
                return false;
            }

            if (leftForm.Options == 0) {
                // Simple nodes, check the values and xml:lang qualifiers.
                if (!leftNode.Value.Equals(rightNode.Value)) {
                    return false;
                }
                if (leftNode.Options.HasLanguage != rightNode.Options.HasLanguage) {
                    return false;
                }
                if (leftNode.Options.HasLanguage &&
                    !leftNode.GetQualifier(1).Value.Equals(rightNode.GetQualifier(1).Value)) {
                    return false;
                }
            }
            else if (leftForm.Struct) {
                // Struct nodes, see if all fields match, ignoring order.

                if (leftNode.ChildrenLength != rightNode.ChildrenLength) {
                    return false;
                }

                for (IEnumerator it = leftNode.IterateChildren(); it.MoveNext();) {
                    XmpNode leftField = (XmpNode) it.Current;
                    if (leftField == null)
                        continue;
                    XmpNode rightField = XmpNodeUtils.FindChildNode(rightNode, leftField.Name, false);
                    if (rightField == null || !ItemValuesMatch(leftField, rightField)) {
                        return false;
                    }
                }
            }
            else {
                // Array nodes, see if the "leftNode" values are present in the
                // "rightNode", ignoring order, duplicates,
                // and extra values in the rightNode-> The rightNode is the
                // destination for AppendProperties.

                Debug.Assert(leftForm.Array);

                for (IEnumerator il = leftNode.IterateChildren(); il.MoveNext();) {
                    XmpNode leftItem = (XmpNode) il.Current;
                    if (leftItem == null)
                        continue;

                    bool match = false;
                    for (IEnumerator ir = rightNode.IterateChildren(); ir.MoveNext();) {
                        XmpNode rightItem = (XmpNode) ir.Current;
                        if (rightItem == null)
                            continue;
                        if (ItemValuesMatch(leftItem, rightItem)) {
                            match = true;
                            break;
                        }
                    }
                    if (!match) {
                        return false;
                    }
                }
            }
            return true; // All of the checks passed.
        }
示例#4
0
        /// <summary>
        /// <ol>
        /// <li>Look for an exact match with the specific language.
        /// <li>If a generic language is given, look for partial matches.
        /// <li>Look for an "x-default"-item.
        /// <li>Choose the first item.
        /// </ol>
        /// </summary>
        /// <param name="arrayNode">
        ///            the alt text array node </param>
        /// <param name="genericLang">
        ///            the generic language </param>
        /// <param name="specificLang">
        ///            the specific language </param>
        /// <returns> Returns the kind of match as an Integer and the found node in an
        ///         array.
        /// </returns>
        /// <exception cref="XmpException"> </exception>
        internal static object[] ChooseLocalizedText(XmpNode arrayNode, string genericLang, string specificLang)
        {
            // See if the array has the right form. Allow empty alt arrays,
            // that is what parsing returns.
            if (!arrayNode.Options.ArrayAltText)
            {
                throw new XmpException("Localized text array is not alt-text", XmpError.BADXPATH);
            }
            if (!arrayNode.HasChildren())
            {
                return(new object[] { CLT_NO_VALUES, null });
            }

            int     foundGenericMatches = 0;
            XmpNode resultNode          = null;
            XmpNode xDefault            = null;

            // Look for the first partial match with the generic language.
            for (IEnumerator it = arrayNode.IterateChildren(); it.MoveNext();)
            {
                XmpNode currItem = (XmpNode)it.Current;

                // perform some checks on the current item
                if (currItem == null || currItem.Options == null || currItem.Options.CompositeProperty)
                {
                    throw new XmpException("Alt-text array item is not simple", XmpError.BADXPATH);
                }
                if (!currItem.HasQualifier() || !XML_LANG.Equals(currItem.GetQualifier(1).Name))
                {
                    throw new XmpException("Alt-text array item has no language qualifier", XmpError.BADXPATH);
                }

                string currLang = currItem.GetQualifier(1).Value;

                // Look for an exact match with the specific language.
                if (specificLang.Equals(currLang))
                {
                    return(new object[] { CLT_SPECIFIC_MATCH, currItem });
                }
                if (genericLang != null && currLang.StartsWith(genericLang))
                {
                    if (resultNode == null)
                    {
                        resultNode = currItem;
                    }
                    // ! Don't return/break, need to look for other matches.
                    foundGenericMatches++;
                }
                else if (X_DEFAULT.Equals(currLang))
                {
                    xDefault = currItem;
                }
            }

            // evaluate loop
            if (foundGenericMatches == 1)
            {
                return(new object[] { CLT_SINGLE_GENERIC, resultNode });
            }
            if (foundGenericMatches > 1)
            {
                return(new object[] { CLT_MULTIPLE_GENERIC, resultNode });
            }
            if (xDefault != null)
            {
                return(new object[] { CLT_XDEFAULT, xDefault });
            }
            {
                // Everything failed, choose the first item.
                return(new object[] { CLT_FIRST_ITEM, arrayNode.GetChild(1) });
            }
        }
示例#5
0
        /// <summary>
        /// Compares two nodes including its children and qualifier. </summary>
        /// <param name="leftNode"> an <code>XMPNode</code> </param>
        /// <param name="rightNode"> an <code>XMPNode</code> </param>
        /// <returns> Returns true if the nodes are equal, false otherwise. </returns>
        /// <exception cref="XmpException"> Forwards exceptions to the calling method. </exception>
        private static bool ItemValuesMatch(XmpNode leftNode, XmpNode rightNode)
        {
            PropertyOptions leftForm  = leftNode.Options;
            PropertyOptions rightForm = rightNode.Options;

            if (leftForm.Equals(rightForm))
            {
                return(false);
            }

            if (leftForm.Options == 0)
            {
                // Simple nodes, check the values and xml:lang qualifiers.
                if (!leftNode.Value.Equals(rightNode.Value))
                {
                    return(false);
                }
                if (leftNode.Options.HasLanguage != rightNode.Options.HasLanguage)
                {
                    return(false);
                }
                if (leftNode.Options.HasLanguage &&
                    !leftNode.GetQualifier(1).Value.Equals(rightNode.GetQualifier(1).Value))
                {
                    return(false);
                }
            }
            else if (leftForm.Struct)
            {
                // Struct nodes, see if all fields match, ignoring order.

                if (leftNode.ChildrenLength != rightNode.ChildrenLength)
                {
                    return(false);
                }

                for (IEnumerator it = leftNode.IterateChildren(); it.MoveNext();)
                {
                    XmpNode leftField = (XmpNode)it.Current;
                    if (leftField == null)
                    {
                        continue;
                    }
                    XmpNode rightField = XmpNodeUtils.FindChildNode(rightNode, leftField.Name, false);
                    if (rightField == null || !ItemValuesMatch(leftField, rightField))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                // Array nodes, see if the "leftNode" values are present in the
                // "rightNode", ignoring order, duplicates,
                // and extra values in the rightNode-> The rightNode is the
                // destination for AppendProperties.

                Debug.Assert(leftForm.Array);

                for (IEnumerator il = leftNode.IterateChildren(); il.MoveNext();)
                {
                    XmpNode leftItem = (XmpNode)il.Current;
                    if (leftItem == null)
                    {
                        continue;
                    }

                    bool match = false;
                    for (IEnumerator ir = rightNode.IterateChildren(); ir.MoveNext();)
                    {
                        XmpNode rightItem = (XmpNode)ir.Current;
                        if (rightItem == null)
                        {
                            continue;
                        }
                        if (ItemValuesMatch(leftItem, rightItem))
                        {
                            match = true;
                            break;
                        }
                    }
                    if (!match)
                    {
                        return(false);
                    }
                }
            }
            return(true); // All of the checks passed.
        }
示例#6
0
        /// <seealso cref= XMPUtilsImpl#appendProperties(XMPMeta, XMPMeta, boolean, boolean, boolean) </seealso>
        /// <param name="destXmp"> The destination XMP object. </param>
        /// <param name="sourceNode"> the source node </param>
        /// <param name="destParent"> the parent of the destination node </param>
        /// <param name="replaceOldValues"> Replace the values of existing properties. </param>
        /// <param name="deleteEmptyValues"> flag if properties with empty values should be deleted
        ///            in the destination object. </param>
        /// <exception cref="XmpException"> </exception>
        private static void AppendSubtree(XmpMetaImpl destXmp, XmpNode sourceNode, XmpNode destParent,
                                          bool replaceOldValues, bool deleteEmptyValues)
        {
            XmpNode destNode = XmpNodeUtils.FindChildNode(destParent, sourceNode.Name, false);

            bool valueIsEmpty = false;

            if (deleteEmptyValues)
            {
                valueIsEmpty = sourceNode.Options.Simple
                                   ? string.IsNullOrEmpty(sourceNode.Value)
                                   : !sourceNode.HasChildren();
            }

            if (deleteEmptyValues && valueIsEmpty)
            {
                if (destNode != null)
                {
                    destParent.RemoveChild(destNode);
                }
            }
            else if (destNode == null)
            {
                // The one easy case, the destination does not exist.
                destParent.AddChild((XmpNode)sourceNode.Clone());
            }
            else if (replaceOldValues)
            {
                // The destination exists and should be replaced.
                destXmp.SetNode(destNode, sourceNode.Value, sourceNode.Options, true);
                destParent.RemoveChild(destNode);
                destNode = (XmpNode)sourceNode.Clone();
                destParent.AddChild(destNode);
            }
            else
            {
                // The destination exists and is not totally replaced. Structs and
                // arrays are merged.

                PropertyOptions sourceForm = sourceNode.Options;
                PropertyOptions destForm   = destNode.Options;
                if (sourceForm != destForm)
                {
                    return;
                }
                if (sourceForm.Struct)
                {
                    // To merge a struct process the fields recursively. E.g. add simple missing fields.
                    // The recursive call to AppendSubtree will handle deletion for fields with empty
                    // values.
                    for (IEnumerator it = sourceNode.IterateChildren(); it.MoveNext();)
                    {
                        XmpNode sourceField = (XmpNode)it.Current;
                        if (sourceField == null)
                        {
                            continue;
                        }
                        AppendSubtree(destXmp, sourceField, destNode, replaceOldValues, deleteEmptyValues);
                        if (deleteEmptyValues && !destNode.HasChildren())
                        {
                            destParent.RemoveChild(destNode);
                        }
                    }
                }
                else if (sourceForm.ArrayAltText)
                {
                    // Merge AltText arrays by the "xml:lang" qualifiers. Make sure x-default is first.
                    // Make a special check for deletion of empty values. Meaningful in AltText arrays
                    // because the "xml:lang" qualifier provides unambiguous source/dest correspondence.
                    for (IEnumerator it = sourceNode.IterateChildren(); it.MoveNext();)
                    {
                        XmpNode sourceItem = (XmpNode)it.Current;
                        if (sourceItem == null)
                        {
                            continue;
                        }
                        if (!sourceItem.HasQualifier() || !XML_LANG.Equals(sourceItem.GetQualifier(1).Name))
                        {
                            continue;
                        }

                        int destIndex = XmpNodeUtils.LookupLanguageItem(destNode, sourceItem.GetQualifier(1).Value);
                        if (deleteEmptyValues && (string.IsNullOrEmpty(sourceItem.Value)))
                        {
                            if (destIndex != -1)
                            {
                                destNode.RemoveChild(destIndex);
                                if (!destNode.HasChildren())
                                {
                                    destParent.RemoveChild(destNode);
                                }
                            }
                        }
                        else if (destIndex == -1)
                        {
                            // Not replacing, keep the existing item.
                            if (!X_DEFAULT.Equals(sourceItem.GetQualifier(1).Value) || !destNode.HasChildren())
                            {
                                sourceItem.CloneSubtree(destNode);
                            }
                            else
                            {
                                XmpNode destItem = new XmpNode(sourceItem.Name, sourceItem.Value, sourceItem.Options);
                                sourceItem.CloneSubtree(destItem);
                                destNode.AddChild(1, destItem);
                            }
                        }
                    }
                }
                else if (sourceForm.Array)
                {
                    // Merge other arrays by item values. Don't worry about order or duplicates. Source
                    // items with empty values do not cause deletion, that conflicts horribly with
                    // merging.

                    for (IEnumerator @is = sourceNode.IterateChildren(); @is.MoveNext();)
                    {
                        XmpNode sourceItem = (XmpNode)@is.Current;
                        if (sourceItem == null)
                        {
                            continue;
                        }
                        bool match = false;
                        for (IEnumerator id = destNode.IterateChildren(); id.MoveNext();)
                        {
                            XmpNode destItem = (XmpNode)id.Current;
                            if (destItem == null)
                            {
                                continue;
                            }
                            if (ItemValuesMatch(sourceItem, destItem))
                            {
                                match = true;
                            }
                        }
                        if (!match)
                        {
                            destNode = (XmpNode)sourceItem.Clone();
                            destParent.AddChild(destNode);
                        }
                    }
                }
            }
        }