Ejemplo n.º 1
0
        /// <summary>Find or create a schema node if <code>createNodes</code> is true.</summary>
        /// <param name="tree">the root of the xmp tree.</param>
        /// <param name="namespaceURI">a namespace</param>
        /// <param name="suggestedPrefix">If a prefix is suggested, the namespace is allowed to be registered.
        ///     </param>
        /// <param name="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.
        /// </param>
        /// <returns>
        /// 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.
        /// </returns>
        /// <exception cref="iText.Kernel.XMP.XMPException">
        /// An exception is only thrown if an error occurred, not if a
        /// node was not found.
        /// </exception>
        internal static XMPNode FindSchemaNode(XMPNode tree, String namespaceURI, String
                                               suggestedPrefix, bool createNodes)
        {
            System.Diagnostics.Debug.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);
        }
Ejemplo n.º 2
0
        /// <param name="arrayNode">an array node</param>
        /// <param name="segment">the segment containing the array index</param>
        /// <param name="createNodes">flag if new nodes are allowed to be created.</param>
        /// <returns>Returns the index or index = -1 if not found</returns>
        /// <exception cref="iText.Kernel.XMP.XMPException">Throws Exceptions</exception>
        private static int FindIndexedItem(XMPNode arrayNode, String segment, bool createNodes
                                           )
        {
            int index = 0;

            try
            {
                segment = segment.JSubstring(1, segment.Length - 1);
                index   = System.Convert.ToInt32(segment);
                if (index < 1)
                {
                    throw new XMPException("Array index must be larger than zero", XMPError.BADXPATH);
                }
            }
            catch (FormatException)
            {
                throw new XMPException("Array index not digits.", XMPError.BADXPATH);
            }
            if (createNodes && index == arrayNode.GetChildrenLength() + 1)
            {
                // Append a new last + 1 node.
                XMPNode newItem = new XMPNode(ARRAY_ITEM_NAME, null);
                newItem.SetImplicit(true);
                arrayNode.AddChild(newItem);
            }
            return(index);
        }
Ejemplo n.º 3
0
        /// <summary>Find or create a qualifier node under a given parent node.</summary>
        /// <remarks>
        /// Find or create a qualifier node under a given parent node. Returns a pointer to the
        /// qualifier node, and optionally an iterator for the node's position in
        /// the parent's vector of qualifiers. The iterator is unchanged if no qualifier node (null)
        /// is returned.
        /// <em>Note:</em> On entry, the qualName parameter must not have the leading '?' from the
        /// XMPPath step.
        /// </remarks>
        /// <param name="parent">the parent XMPNode</param>
        /// <param name="qualName">the qualifier name</param>
        /// <param name="createNodes">flag if nodes shall be created</param>
        /// <returns>Returns the qualifier node if found or created, <code>null</code> otherwise.
        ///     </returns>
        /// <exception cref="iText.Kernel.XMP.XMPException"></exception>
        private static XMPNode FindQualifierNode(XMPNode parent, String qualName, bool createNodes
                                                 )
        {
            System.Diagnostics.Debug.Assert(!qualName.StartsWith("?"));
            XMPNode qualNode = parent.FindQualifierByName(qualName);

            if (qualNode == null && createNodes)
            {
                qualNode = new XMPNode(qualName, null);
                qualNode.SetImplicit(true);
                parent.AddQualifier(qualNode);
            }
            return(qualNode);
        }
Ejemplo n.º 4
0
        /// <summary>Find or create a child node under a given parent node.</summary>
        /// <remarks>
        /// Find or create a child node under a given parent node. If the parent node is no
        /// Returns the found or created child node.
        /// </remarks>
        /// <param name="parent">the parent node</param>
        /// <param name="childName">the node name to find</param>
        /// <param name="createNodes">flag, if new nodes shall be created.</param>
        /// <returns>Returns the found or created node or <code>null</code>.</returns>
        /// <exception cref="iText.Kernel.XMP.XMPException">Thrown if</exception>
        internal static XMPNode FindChildNode(XMPNode parent, String childName, bool createNodes
                                              )
        {
            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);
            }
            System.Diagnostics.Debug.Assert(childNode != null || !createNodes);
            return(childNode);
        }
Ejemplo n.º 5
0
        /// <summary>Follow an expanded path expression to find or create a node.</summary>
        /// <param name="xmpTree">the node to begin the search.</param>
        /// <param name="xpath">the complete xpath</param>
        /// <param name="createNodes">
        /// flag if nodes shall be created
        /// (when called by <code>setProperty()</code>)
        /// </param>
        /// <param name="leafOptions">
        /// the options for the created leaf nodes (only when
        /// <code>createNodes == true</code>).
        /// </param>
        /// <returns>Returns the node if found or created or <code>null</code>.</returns>
        /// <exception cref="iText.Kernel.XMP.XMPException">
        /// An exception is only thrown if an error occurred,
        /// not if a node was not found.
        /// </exception>
        internal static XMPNode FindNode(XMPNode xmpTree, XMPPath xpath, bool createNodes
                                         , PropertyOptions leafOptions)
        {
            // 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);
                            }
                            else
                            {
                                // "CheckImplicitStruct" in C++
                                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;
                            }
                        }
                    }
                }
            }
            catch (XMPException e)
            {
                // Save the top most implicit node.
                // if new notes have been created prior to the error, delete them
                if (rootImplicitNode != null)
                {
                    DeleteNode(rootImplicitNode);
                }
                throw;
            }
            if (rootImplicitNode != null)
            {
                // set options only if a node has been successful created
                currNode.GetOptions().MergeWith(leafOptions);
                currNode.SetOptions(currNode.GetOptions());
            }
            return(currNode);
        }
Ejemplo n.º 6
0
        /// <summary>Visit all of the top level nodes looking for aliases.</summary>
        /// <remarks>
        /// 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.
        /// </remarks>
        /// <param name="tree">the root of the metadata tree</param>
        /// <param name="options">th parsing options</param>
        /// <exception cref="iText.Kernel.XMP.XMPException">Forwards XMP errors</exception>
        private static void MoveExplicitAliases(XMPNode tree, ParseOptions options)
        {
            if (!tree.GetHasAliases())
            {
                return;
            }
            tree.SetHasAliases(false);

            bool        strictAliasing = options.GetStrictAliasing();
            IEnumerator schemaIt       = tree.GetUnmodifiableChildren().GetEnumerator();

            while (schemaIt.MoveNext())
            {
                XMPNode currSchema = (XMPNode)schemaIt.Current;
                if (currSchema == null)
                {
                    continue;
                }
                if (!currSchema.GetHasAliases())
                {
                    continue;
                }

                List <XMPNode> currPropsToRemove = new List <XMPNode>();
                IEnumerator    propertyIt        = currSchema.IterateChildren();
                while (propertyIt.MoveNext())
                {
                    XMPNode currProp = (XMPNode)propertyIt.Current;
                    if (currProp == null)
                    {
                        continue;
                    }

                    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);
                            }
                            else
                            {
                                // An alias to an array item,
                                // create the array and transplant the property.
                                baseNode = new XMPNode(info.GetPrefix() + info.GetPropName(),
                                                       info.GetAliasForm().ToPropertyOptions());
                                baseSchema.AddChild(baseNode);
                                TransplantArrayItemAlias(currProp, baseNode);
                            }
                            currPropsToRemove.Add(currProp);
                        }
                        else if (info.GetAliasForm().IsSimple())
                        {
                            // The base node does exist and this is a top-to-top alias.
                            // Check for conflicts if strict aliasing is on.
                            // Remove and delete the alias subtree.
                            if (strictAliasing)
                            {
                                CompareAliasedSubtrees(currProp, baseNode, true);
                            }
                            currPropsToRemove.Add(currProp);
                        }
                        else
                        {
                            // This is an alias to an array item and the array exists.
                            // Look for the aliased item.
                            // Then transplant or check & delete as appropriate.

                            XMPNode itemNode = null;
                            if (info.GetAliasForm().IsArrayAltText())
                            {
                                int xdIndex = XMPNodeUtils.LookupLanguageItem(baseNode, XMPConst.X_DEFAULT);
                                if (xdIndex != -1)
                                {
                                    itemNode = baseNode.GetChild(xdIndex);
                                }
                            }
                            else if (baseNode.HasChildren())
                            {
                                itemNode = baseNode.GetChild(1);
                            }

                            if (itemNode == null)
                            {
                                TransplantArrayItemAlias(currProp, baseNode);
                            }
                            else
                            {
                                if (strictAliasing)
                                {
                                    CompareAliasedSubtrees(currProp, itemNode, true);
                                }
                            }
                            currPropsToRemove.Add(currProp);
                        }
                    }
                }
                foreach (XMPNode o in currPropsToRemove)
                {
                    currSchema.RemoveChild(o);
                }
                currPropsToRemove.Clear();
                currSchema.SetHasAliases(false);
            }
        }