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="Com.Adobe.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", XMPErrorConstants.Badschema);
                    }
                }
                schemaNode.SetValue(prefix);
                tree.AddChild(schemaNode);
            }
            return(schemaNode);
        }
Ejemplo n.º 2
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="Com.Adobe.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", XMPErrorConstants.Badxpath);
                }
                else
                {
                    if (parent.GetOptions().IsArray())
                    {
                        throw new XMPException("Named children not allowed for arrays", XMPErrorConstants.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.º 3
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="Com.Adobe.Xmp.XMPException">Throws Exceptions</exception>
        private static int FindIndexedItem(XMPNode arrayNode, string segment, bool createNodes)
        {
            int index = 0;

            try
            {
                segment = Sharpen.Runtime.Substring(segment, 1, segment.Length - 1);
                index   = System.Convert.ToInt32(segment);
                if (index < 1)
                {
                    throw new XMPException("Array index must be larger than zero", XMPErrorConstants.Badxpath);
                }
            }
            catch (FormatException)
            {
                throw new XMPException("Array index not digits.", XMPErrorConstants.Badxpath);
            }
            if (createNodes && index == arrayNode.GetChildrenLength() + 1)
            {
                // Append a new last + 1 node.
                XMPNode newItem = new XMPNode(XMPConstConstants.ArrayItemName, null);
                newItem.SetImplicit(true);
                arrayNode.AddChild(newItem);
            }
            return(index);
        }
Ejemplo n.º 4
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="Com.Adobe.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", XMPErrorConstants.Badschema);
					}
				}
				schemaNode.SetValue(prefix);
				tree.AddChild(schemaNode);
			}
			return schemaNode;
		}
Ejemplo n.º 5
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="Com.Adobe.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.º 6
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="Com.Adobe.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", XMPErrorConstants.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.StepSchema).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.StructFieldStep && !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.º 7
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="Com.Adobe.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();

            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.GetAliasForm().ToPropertyOptions());
                                baseSchema.AddChild(baseNode);
                                TransplantArrayItemAlias(propertyIt, currProp, baseNode);
                            }
                        }
                        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);
                                }
                                propertyIt.Remove();
                            }
                            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, XMPConstConstants.XDefault);
                                    if (xdIndex != -1)
                                    {
                                        itemNode = baseNode.GetChild(xdIndex);
                                    }
                                }
                                else
                                {
                                    if (baseNode.HasChildren())
                                    {
                                        itemNode = baseNode.GetChild(1);
                                    }
                                }
                                if (itemNode == null)
                                {
                                    TransplantArrayItemAlias(propertyIt, currProp, baseNode);
                                }
                                else
                                {
                                    if (strictAliasing)
                                    {
                                        CompareAliasedSubtrees(currProp, itemNode, true);
                                    }
                                    propertyIt.Remove();
                                }
                            }
                        }
                    }
                }
                currSchema.SetHasAliases(false);
            }
        }
Ejemplo n.º 8
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="Com.Adobe.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.º 9
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="Com.Adobe.Xmp.XMPException">Throws Exceptions</exception>
 private static int FindIndexedItem(XMPNode arrayNode, string segment, bool createNodes)
 {
     int index = 0;
     try
     {
         segment = Sharpen.Runtime.Substring(segment, 1, segment.Length - 1);
         index = System.Convert.ToInt32(segment);
         if (index < 1)
         {
             throw new XMPException("Array index must be larger than zero", XMPErrorConstants.Badxpath);
         }
     }
     catch (FormatException)
     {
         throw new XMPException("Array index not digits.", XMPErrorConstants.Badxpath);
     }
     if (createNodes && index == arrayNode.GetChildrenLength() + 1)
     {
         // Append a new last + 1 node.
         XMPNode newItem = new XMPNode(XMPConstConstants.ArrayItemName, null);
         newItem.SetImplicit(true);
         arrayNode.AddChild(newItem);
     }
     return index;
 }
Ejemplo n.º 10
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="Com.Adobe.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", XMPErrorConstants.Badxpath);
         }
         else
         {
             if (parent.GetOptions().IsArray())
             {
                 throw new XMPException("Named children not allowed for arrays", XMPErrorConstants.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;
 }