コード例 #1
0
        /// <seealso cref="AppendProperties(Com.Adobe.Xmp.XMPMeta, Com.Adobe.Xmp.XMPMeta, bool, bool, bool)"/>
        /// <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="Com.Adobe.Xmp.XMPException"/>
        private static void AppendSubtree(XMPMetaImpl destXMP, XMPNode sourceNode, XMPNode destParent, bool replaceOldValues, bool deleteEmptyValues)
        {
            XMPNode destNode     = XMPNodeUtils.FindChildNode(destParent, sourceNode.GetName(), false);
            bool    valueIsEmpty = false;

            if (deleteEmptyValues)
            {
                valueIsEmpty = sourceNode.GetOptions().IsSimple() ? sourceNode.GetValue() == null || sourceNode.GetValue().Length == 0 : !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.GetValue(), sourceNode.GetOptions(), 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.GetOptions();
                        PropertyOptions destForm   = destNode.GetOptions();
                        if (sourceForm != destForm)
                        {
                            return;
                        }
                        if (sourceForm.IsStruct())
                        {
                            // 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 (Iterator it = sourceNode.IterateChildren(); it.HasNext();)
                            {
                                XMPNode sourceField = (XMPNode)it.Next();
                                AppendSubtree(destXMP, sourceField, destNode, replaceOldValues, deleteEmptyValues);
                                if (deleteEmptyValues && !destNode.HasChildren())
                                {
                                    destParent.RemoveChild(destNode);
                                }
                            }
                        }
                        else
                        {
                            if (sourceForm.IsArrayAltText())
                            {
                                // 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 (Iterator it = sourceNode.IterateChildren(); it.HasNext();)
                                {
                                    XMPNode sourceItem = (XMPNode)it.Next();
                                    if (!sourceItem.HasQualifier() || !XMPConstConstants.XmlLang.Equals(sourceItem.GetQualifier(1).GetName()))
                                    {
                                        continue;
                                    }
                                    int destIndex = XMPNodeUtils.LookupLanguageItem(destNode, sourceItem.GetQualifier(1).GetValue());
                                    if (deleteEmptyValues && (sourceItem.GetValue() == null || sourceItem.GetValue().Length == 0))
                                    {
                                        if (destIndex != -1)
                                        {
                                            destNode.RemoveChild(destIndex);
                                            if (!destNode.HasChildren())
                                            {
                                                destParent.RemoveChild(destNode);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (destIndex == -1)
                                        {
                                            // Not replacing, keep the existing item.
                                            if (!XMPConstConstants.XDefault.Equals(sourceItem.GetQualifier(1).GetValue()) || !destNode.HasChildren())
                                            {
                                                sourceItem.CloneSubtree(destNode);
                                            }
                                            else
                                            {
                                                XMPNode destItem = new XMPNode(sourceItem.GetName(), sourceItem.GetValue(), sourceItem.GetOptions());
                                                sourceItem.CloneSubtree(destItem);
                                                destNode.AddChild(1, destItem);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (sourceForm.IsArray())
                                {
                                    // 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 (Iterator @is = sourceNode.IterateChildren(); @is.HasNext();)
                                    {
                                        XMPNode sourceItem = (XMPNode)@is.Next();
                                        bool    match      = false;
                                        for (Iterator id = destNode.IterateChildren(); id.HasNext();)
                                        {
                                            XMPNode destItem = (XMPNode)id.Next();
                                            if (ItemValuesMatch(sourceItem, destItem))
                                            {
                                                match = true;
                                            }
                                        }
                                        if (!match)
                                        {
                                            destNode = (XMPNode)sourceItem.Clone();
                                            destParent.AddChild(destNode);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }