Exemple #1
0
        /// <summary>Deletes the the given node and its children from its parent.</summary>
        /// <remarks>
        /// Deletes the the given node and its children from its parent.
        /// Takes care about adjusting the flags.
        /// </remarks>
        /// <param name="node">the top-most node to delete.</param>
        internal static void DeleteNode(XMPNode node)
        {
            XMPNode parent = node.GetParent();

            if (node.GetOptions().IsQualifier())
            {
                // root is qualifier
                parent.RemoveQualifier(node);
            }
            else
            {
                // root is NO qualifier
                parent.RemoveChild(node);
            }
            // delete empty Schema nodes
            if (!parent.HasChildren() && parent.GetOptions().IsSchemaNode())
            {
                parent.GetParent().RemoveChild(parent);
            }
        }
		/// <summary>Returns a property, but the result value can be requested.</summary>
		/// <seealso cref="iText.Kernel.XMP.XMPMeta.GetProperty(System.String, System.String)
		/// 	"/>
		/// <param name="schemaNS">a schema namespace</param>
		/// <param name="propName">a property name or path</param>
		/// <param name="valueType">the type of the value, see VALUE_...</param>
		/// <returns>
		/// Returns the node value as an object according to the
		/// <code>valueType</code>.
		/// </returns>
		/// <exception cref="iText.Kernel.XMP.XMPException">Collects any exception that occurs.</exception>
		protected internal virtual Object GetPropertyObject(String schemaNS, String propName
			, int valueType)
		{
			ParameterAsserts.AssertSchemaNS(schemaNS);
			ParameterAsserts.AssertPropName(propName);
			XMPPath expPath = XMPPathParser.ExpandXPath(schemaNS, propName);
			XMPNode propNode = XMPNodeUtils.FindNode(tree, expPath, false, null);
			if (propNode != null)
			{
				if (valueType != VALUE_STRING && propNode.GetOptions().IsCompositeProperty())
				{
					throw new XMPException("Property must be simple when a value type is requested", 
						XMPError.BADXPATH);
				}
				return EvaluateNodeValue(valueType, propNode);
			}
			else
			{
				return null;
			}
		}
Exemple #3
0
 /// <summary>See if an array is an alt-text array.</summary>
 /// <remarks>
 /// See if an array is an alt-text array. If so, make sure the x-default item
 /// is first.
 /// </remarks>
 /// <param name="arrayNode">the array node to check if its an alt-text array</param>
 internal static void DetectAltText(XMPNode arrayNode)
 {
     if (arrayNode.GetOptions().IsArrayAlternate() && arrayNode.HasChildren())
     {
         bool isAltText = false;
         for (IEnumerator it = arrayNode.IterateChildren(); it.MoveNext();)
         {
             XMPNode child = (XMPNode)it.Current;
             if (child.GetOptions().GetHasLanguage())
             {
                 isAltText = true;
                 break;
             }
         }
         if (isAltText)
         {
             arrayNode.GetOptions().SetArrayAltText(true);
             NormalizeLangArray(arrayNode);
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Sorts the complete datamodel according to the rules.
        /// </summary>
        /// <remarks>
        /// Sorts the complete datamodel according to the following rules:
        /// <ul>
        /// <li>Nodes at one level are sorted by name, that is prefix + local name</li>
        /// <li>Starting at the root node the children and qualifier are sorted recursively,
        /// which the following exceptions.</li>
        /// <li>Sorting will not be used for arrays.</li>
        /// <li>Within qualifier "xml:lang" and/or "rdf:type" stay at the top in that order,
        /// all others are sorted.</li>
        /// </ul>
        /// </remarks>
        public virtual void Sort()
        {
            // sort qualifier
            if (HasQualifier())
            {
                XMPNode[] quals = new XMPNode[GetQualifier().Count];
                GetQualifier().CopyTo(quals, 0);
                int sortFrom = 0;
                while (quals.Length > sortFrom &&
                       (XMPConst.XML_LANG.Equals(quals[sortFrom].GetName()) || "rdf:type".Equals(quals[sortFrom].GetName())))
                {
                    quals[sortFrom].Sort();
                    sortFrom++;
                }
                Array.Sort(quals, sortFrom, quals.Length - sortFrom);
                for (int j = 0; j < quals.Length; j++)
                {
                    qualifier[j] = quals[j];
                    quals[j].Sort();
                }
            }

            // sort children
            if (HasChildren())
            {
                if (!GetOptions().IsArray())
                {
                    ArrayList.Adapter(children).Sort();
                }
                IEnumerator it = IterateChildren();
                while (it.MoveNext())
                {
                    if (it.Current != null)
                    {
                        ((XMPNode)it.Current).Sort();
                    }
                }
            }
        }
Exemple #5
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);
        }
Exemple #6
0
 /// <summary>
 /// Searches for a qualifier selector in a node:
 /// [?qualName="value"] - an element in an array, chosen by a qualifier value.
 /// </summary>
 /// <remarks>
 /// Searches for a qualifier selector in a node:
 /// [?qualName="value"] - an element in an array, chosen by a qualifier value.
 /// No implicit nodes are created for qualifier selectors,
 /// except for an alias to an x-default item.
 /// </remarks>
 /// <param name="arrayNode">an array node</param>
 /// <param name="qualName">the qualifier name</param>
 /// <param name="qualValue">the qualifier value</param>
 /// <param name="aliasForm">
 /// in case the qual selector results from an alias,
 /// an x-default node is created if there has not been one.
 /// </param>
 /// <returns>Returns the index of th</returns>
 /// <exception cref="iText.Kernel.XMP.XMPException"></exception>
 private static int LookupQualSelector(XMPNode arrayNode, String qualName, String
                                       qualValue, int aliasForm)
 {
     if (XML_LANG.Equals(qualName))
     {
         qualValue = iText.Kernel.XMP.Impl.Utils.NormalizeLangValue(qualValue);
         int index = XMPNodeUtils.LookupLanguageItem(arrayNode, qualValue);
         if (index < 0 && (aliasForm & AliasOptions.PROP_ARRAY_ALT_TEXT) > 0)
         {
             XMPNode langNode = new XMPNode(ARRAY_ITEM_NAME, null);
             XMPNode xdefault = new XMPNode(XML_LANG, X_DEFAULT, null);
             langNode.AddQualifier(xdefault);
             arrayNode.AddChild(1, langNode);
             return(1);
         }
         else
         {
             return(index);
         }
     }
     else
     {
         for (int index = 1; index < arrayNode.GetChildrenLength(); index++)
         {
             XMPNode currItem = arrayNode.GetChild(index);
             for (IEnumerator it = currItem.IterateQualifier(); it.MoveNext();)
             {
                 XMPNode qualifier = (XMPNode)it.Current;
                 if (qualName.Equals(qualifier.GetName()) && qualValue.Equals(qualifier.GetValue()
                                                                              ))
                 {
                     return(index);
                 }
             }
         }
         return(-1);
     }
 }
Exemple #7
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="iText.Kernel.XMP.XMPException"/>
 internal static int LookupLanguageItem(XMPNode arrayNode, String language)
 {
     if (!arrayNode.GetOptions().IsArray())
     {
         throw new XMPException("Language item must be used on array", XMPError.BADXPATH);
     }
     for (int index = 1; index <= arrayNode.GetChildrenLength(); index++)
     {
         XMPNode child = arrayNode.GetChild(index);
         if (!child.HasQualifier() || !XML_LANG.Equals(child.GetQualifier(1).GetName()))
         {
             continue;
         }
         else
         {
             if (language.Equals(child.GetQualifier(1).GetValue()))
             {
                 return(index);
             }
         }
     }
     return(-1);
 }
		/// <summary>
		/// The internals for setProperty() and related calls, used after the node is
		/// found or created.
		/// </summary>
		/// <param name="node">the newly created node</param>
		/// <param name="value">the node value, can be <code>null</code></param>
		/// <param name="newOptions">options for the new node, must not be <code>null</code>.
		/// 	</param>
		/// <param name="deleteExisting">flag if the existing value is to be overwritten</param>
		/// <exception cref="iText.Kernel.XMP.XMPException">thrown if options and value do not correspond</exception>
		internal virtual void SetNode(XMPNode node, Object value, PropertyOptions newOptions
			, bool deleteExisting)
		{
			if (deleteExisting)
			{
				node.Clear();
			}
			// its checked by setOptions(), if the merged result is a valid options set
			node.GetOptions().MergeWith(newOptions);
			if (!node.GetOptions().IsCompositeProperty())
			{
				// This is setting the value of a leaf node.
				XMPNodeUtils.SetNodeValue(node, value);
			}
			else
			{
				if (value != null && value.ToString().Length > 0)
				{
					throw new XMPException("Composite nodes can't have values", XMPError.BADXPATH);
				}
				node.RemoveChildren();
			}
		}
Exemple #9
0
            /// <summary>
            /// Creates a property info object from an <code>XMPNode</code>. </summary>
            /// <param name="node"> an <code>XMPNode</code> </param>
            /// <param name="baseNs"> the base namespace to report </param>
            /// <param name="path"> the full property path </param>
            /// <returns> Returns a <code>XMPProperty</code>-object that serves representation of the node. </returns>
            protected internal virtual XMPPropertyInfo CreatePropertyInfo(XMPNode node, String baseNS, String path)
            {
                String value = node.GetOptions().IsSchemaNode() ? null : node.GetValue();

                return(new XMPPropertyInfoImpl(node, baseNS, path, value));
            }
			public _XMPProperty_428(XMPNode itemNode)
			{
				this.itemNode = itemNode;
			}
Exemple #11
0
        /// <summary>
        /// <ol>
        /// <li>Look for an exact match with the specific language.
        /// </summary>
        /// <remarks>
        /// <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>
        /// </remarks>
        /// <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="iText.Kernel.XMP.XMPException"/>
        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.GetOptions().IsArrayAltText())
            {
                throw new XMPException("Localized text array is not alt-text", XMPError.BADXPATH);
            }
            else
            {
                if (!arrayNode.HasChildren())
                {
                    return(new Object[] { XMPNodeUtils.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.GetOptions().IsCompositeProperty())
                {
                    throw new XMPException("Alt-text array item is not simple", XMPError.BADXPATH);
                }
                else
                {
                    if (!currItem.HasQualifier() || !XML_LANG.Equals(currItem.GetQualifier(1).GetName
                                                                         ()))
                    {
                        throw new XMPException("Alt-text array item has no language qualifier", XMPError.
                                               BADXPATH);
                    }
                }
                String currLang = currItem.GetQualifier(1).GetValue();
                // Look for an exact match with the specific language.
                if (specificLang.Equals(currLang))
                {
                    return(new Object[] { XMPNodeUtils.CLT_SPECIFIC_MATCH, currItem });
                }
                else
                {
                    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[] { XMPNodeUtils.CLT_SINGLE_GENERIC, resultNode });
            }
            else
            {
                if (foundGenericMatches > 1)
                {
                    return(new Object[] { XMPNodeUtils.CLT_MULTIPLE_GENERIC, resultNode });
                }
                else
                {
                    if (xDefault != null)
                    {
                        return(new Object[] { XMPNodeUtils.CLT_XDEFAULT, xDefault });
                    }
                    else
                    {
                        // Everything failed, choose the first item.
                        return(new Object[] { XMPNodeUtils.CLT_FIRST_ITEM, arrayNode.GetChild(1) });
                    }
                }
            }
        }
		public virtual void SetLocalizedText(String schemaNS, String altTextName, String 
			genericLang, String specificLang, String itemValue, PropertyOptions options)
		{
			ParameterAsserts.AssertSchemaNS(schemaNS);
			ParameterAsserts.AssertArrayName(altTextName);
			ParameterAsserts.AssertSpecificLang(specificLang);
			genericLang = genericLang != null ? iText.Kernel.XMP.Impl.Utils.NormalizeLangValue
				(genericLang) : null;
			specificLang = iText.Kernel.XMP.Impl.Utils.NormalizeLangValue(specificLang);
			XMPPath arrayPath = XMPPathParser.ExpandXPath(schemaNS, altTextName);
			// Find the array node and set the options if it was just created.
			XMPNode arrayNode = XMPNodeUtils.FindNode(tree, arrayPath, true, new PropertyOptions
				(PropertyOptions.ARRAY | PropertyOptions.ARRAY_ORDERED | PropertyOptions.ARRAY_ALTERNATE
				 | PropertyOptions.ARRAY_ALT_TEXT));
			if (arrayNode == null)
			{
				throw new XMPException("Failed to find or create array node", XMPError.BADXPATH);
			}
			else
			{
				if (!arrayNode.GetOptions().IsArrayAltText())
				{
					if (!arrayNode.HasChildren() && arrayNode.GetOptions().IsArrayAlternate())
					{
						arrayNode.GetOptions().SetArrayAltText(true);
					}
					else
					{
						throw new XMPException("Specified property is no alt-text array", XMPError.BADXPATH
							);
					}
				}
			}
			// Make sure the x-default item, if any, is first.
			bool haveXDefault = false;
			XMPNode xdItem = null;
			foreach (XMPNode currItem in arrayNode.GetChildren())
			{
				if (!currItem.HasQualifier() || !XMPConst.XML_LANG.Equals(currItem.GetQualifier(1
					).GetName()))
				{
					throw new XMPException("Language qualifier must be first", XMPError.BADXPATH);
				}
				else
				{
					if (XMPConst.X_DEFAULT.Equals(currItem.GetQualifier(1).GetValue()))
					{
						xdItem = currItem;
						haveXDefault = true;
						break;
					}
				}
			}
			// Moves x-default to the beginning of the array
			if (xdItem != null && arrayNode.GetChildrenLength() > 1)
			{
				arrayNode.RemoveChild(xdItem);
				arrayNode.AddChild(1, xdItem);
			}
			// Find the appropriate item.
			// chooseLocalizedText will make sure the array is a language
			// alternative.
			Object[] result = XMPNodeUtils.ChooseLocalizedText(arrayNode, genericLang, specificLang
				);
			int match = (int)result[0];
			XMPNode itemNode = (XMPNode)result[1];
			bool specificXDefault = XMPConst.X_DEFAULT.Equals(specificLang);
			switch (match)
			{
				case XMPNodeUtils.CLT_NO_VALUES:
				{
					// Create the array items for the specificLang and x-default, with
					// x-default first.
					XMPNodeUtils.AppendLangItem(arrayNode, XMPConst.X_DEFAULT, itemValue);
					haveXDefault = true;
					if (!specificXDefault)
					{
						XMPNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue);
					}
					break;
				}

				case XMPNodeUtils.CLT_SPECIFIC_MATCH:
				{
					if (!specificXDefault)
					{
						// Update the specific item, update x-default if it matches the
						// old value.
						if (haveXDefault && xdItem != itemNode && xdItem != null && xdItem.GetValue().Equals
							(itemNode.GetValue()))
						{
							xdItem.SetValue(itemValue);
						}
						// ! Do this after the x-default check!
						itemNode.SetValue(itemValue);
					}
					else
					{
						// Update all items whose values match the old x-default value.
						System.Diagnostics.Debug.Assert(haveXDefault && xdItem == itemNode);
						for (IEnumerator it_1 = arrayNode.IterateChildren(); it_1.MoveNext(); )
						{
							XMPNode currItem = (XMPNode)it_1.Current;
							if (currItem == xdItem || !currItem.GetValue().Equals(xdItem != null ? xdItem.GetValue
								() : null))
							{
								continue;
							}
							currItem.SetValue(itemValue);
						}
						// And finally do the x-default item.
						if (xdItem != null)
						{
							xdItem.SetValue(itemValue);
						}
					}
					break;
				}

				case XMPNodeUtils.CLT_SINGLE_GENERIC:
				{
					// Update the generic item, update x-default if it matches the old
					// value.
					if (haveXDefault && xdItem != itemNode && xdItem != null && xdItem.GetValue().Equals
						(itemNode.GetValue()))
					{
						xdItem.SetValue(itemValue);
					}
					itemNode.SetValue(itemValue);
					// ! Do this after
					// the x-default
					// check!
					break;
				}

				case XMPNodeUtils.CLT_MULTIPLE_GENERIC:
				{
					// Create the specific language, ignore x-default.
					XMPNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue);
					if (specificXDefault)
					{
						haveXDefault = true;
					}
					break;
				}

				case XMPNodeUtils.CLT_XDEFAULT:
				{
					// Create the specific language, update x-default if it was the only
					// item.
					if (xdItem != null && arrayNode.GetChildrenLength() == 1)
					{
						xdItem.SetValue(itemValue);
					}
					XMPNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue);
					break;
				}

				case XMPNodeUtils.CLT_FIRST_ITEM:
				{
					// Create the specific language, don't add an x-default item.
					XMPNodeUtils.AppendLangItem(arrayNode, specificLang, itemValue);
					if (specificXDefault)
					{
						haveXDefault = true;
					}
					break;
				}

				default:
				{
					// does not happen under normal circumstances
					throw new XMPException("Unexpected result from ChooseLocalizedText", XMPError.INTERNALFAILURE
						);
				}
			}
			// Add an x-default at the front if needed.
			if (!haveXDefault && arrayNode.GetChildrenLength() == 1)
			{
				XMPNodeUtils.AppendLangItem(arrayNode, XMPConst.X_DEFAULT, itemValue);
			}
		}
Exemple #13
0
 // EMPTY
 /// <summary>Find or create a schema node if <code>createNodes</code> is false and</summary>
 /// <param name="tree">the root of the xmp tree.</param>
 /// <param name="namespaceURI">a namespace</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, bool createNodes
                                        )
 {
     return(FindSchemaNode(tree, namespaceURI, null, createNodes));
 }
			public _XMPProperty_703(Object value, XMPNode propNode)
			{
				this.value = value;
				this.propNode = propNode;
			}
Exemple #15
0
        /// <summary>
        /// After processing by ExpandXPath, a step can be of these forms:
        /// <ul>
        /// <li>qualName - A top level property or struct field.
        /// </summary>
        /// <remarks>
        /// After processing by ExpandXPath, a step can be of these forms:
        /// <ul>
        /// <li>qualName - A top level property or struct field.
        /// <li>[index] - An element of an array.
        /// <li>[last()] - The last element of an array.
        /// <li>[qualName="value"] - An element in an array of structs, chosen by a field value.
        /// <li>[?qualName="value"] - An element in an array, chosen by a qualifier value.
        /// <li>?qualName - A general qualifier.
        /// </ul>
        /// Find the appropriate child node, resolving aliases, and optionally creating nodes.
        /// </remarks>
        /// <param name="parentNode">the node to start to start from</param>
        /// <param name="nextStep">the xpath segment</param>
        /// <param name="createNodes"></param>
        /// <returns>returns the found or created XMPPath node</returns>
        /// <exception cref="iText.Kernel.XMP.XMPException"></exception>
        private static XMPNode FollowXPathStep(XMPNode parentNode, XMPPathSegment nextStep
                                               , bool createNodes)
        {
            XMPNode nextNode = null;
            int     index    = 0;
            int     stepKind = nextStep.GetKind();

            if (stepKind == XMPPath.STRUCT_FIELD_STEP)
            {
                nextNode = FindChildNode(parentNode, nextStep.GetName(), createNodes);
            }
            else
            {
                if (stepKind == XMPPath.QUALIFIER_STEP)
                {
                    nextNode = FindQualifierNode(parentNode, nextStep.GetName().Substring(1), createNodes
                                                 );
                }
                else
                {
                    // This is an array indexing step. First get the index, then get the node.
                    if (!parentNode.GetOptions().IsArray())
                    {
                        throw new XMPException("Indexing applied to non-array", XMPError.BADXPATH);
                    }
                    if (stepKind == XMPPath.ARRAY_INDEX_STEP)
                    {
                        index = FindIndexedItem(parentNode, nextStep.GetName(), createNodes);
                    }
                    else
                    {
                        if (stepKind == XMPPath.ARRAY_LAST_STEP)
                        {
                            index = parentNode.GetChildrenLength();
                        }
                        else
                        {
                            if (stepKind == XMPPath.FIELD_SELECTOR_STEP)
                            {
                                String[] result     = Utils.SplitNameAndValue(nextStep.GetName());
                                String   fieldName  = result[0];
                                String   fieldValue = result[1];
                                index = LookupFieldSelector(parentNode, fieldName, fieldValue);
                            }
                            else
                            {
                                if (stepKind == XMPPath.QUAL_SELECTOR_STEP)
                                {
                                    String[] result    = Utils.SplitNameAndValue(nextStep.GetName());
                                    String   qualName  = result[0];
                                    String   qualValue = result[1];
                                    index = LookupQualSelector(parentNode, qualName, qualValue, nextStep.GetAliasForm
                                                                   ());
                                }
                                else
                                {
                                    throw new XMPException("Unknown array indexing step in FollowXPathStep", XMPError
                                                           .INTERNALFAILURE);
                                }
                            }
                        }
                    }
                    if (1 <= index && index <= parentNode.GetChildrenLength())
                    {
                        nextNode = parentNode.GetChild(index);
                    }
                }
            }
            return(nextNode);
        }
		/// <summary>Constructor for an empty metadata object.</summary>
		public XMPMetaImpl()
		{
			// create root node
			tree = new XMPNode(null, null, null);
		}
Exemple #17
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);
        }
        /// <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);
            }
        }
		/// <summary>
		/// Evaluates a raw node value to the given value type, apply special
		/// conversions for defined types in XMP.
		/// </summary>
		/// <param name="valueType">an int indicating the value type</param>
		/// <param name="propNode">the node containing the value</param>
		/// <returns>Returns a literal value for the node.</returns>
		/// <exception cref="iText.Kernel.XMP.XMPException">
		/// if the value of <code>propNode</code> is <code>null</code> or empty or the conversion fails.
		/// </exception>
		private Object EvaluateNodeValue(int valueType, XMPNode propNode)
		{
			Object value;
			String rawValue = propNode.GetValue();
			switch (valueType)
			{
				case VALUE_BOOLEAN:
				{
					value = XMPUtils.ConvertToBoolean(rawValue);
					break;
				}

				case VALUE_INTEGER:
				{
					value = XMPUtils.ConvertToInteger(rawValue);
					break;
				}

				case VALUE_LONG:
				{
					value = XMPUtils.ConvertToLong(rawValue);
					break;
				}

				case VALUE_DOUBLE:
				{
					value = XMPUtils.ConvertToDouble(rawValue);
					break;
				}

				case VALUE_DATE:
				{
					value = XMPUtils.ConvertToDate(rawValue);
					break;
				}

				case VALUE_CALENDAR:
				{
					XMPDateTime dt = XMPUtils.ConvertToDate(rawValue);
					value = dt.GetCalendar();
					break;
				}

				case VALUE_BASE64:
				{
					value = XMPUtils.DecodeBase64(rawValue);
					break;
				}

				case VALUE_STRING:
				default:
				{
					// leaf values return empty string instead of null
					// for the other cases the converter methods provides a "null"
					// value.
					// a default value can only occur if this method is made public.
					value = rawValue != null || propNode.GetOptions().IsCompositeProperty() ? rawValue
						 : "";
					break;
				}
			}
			return value;
		}
Exemple #20
0
 //------------------------------------------------------------------------------ private methods
 /// <summary>Dumps this node and its qualifier and children recursively.</summary>
 /// <remarks>
 /// Dumps this node and its qualifier and children recursively.
 /// <em>Note:</em> It creats empty options on every node.
 /// </remarks>
 /// <param name="result">the buffer to append the dump.</param>
 /// <param name="recursive">Flag is qualifier and child nodes shall be rendered too</param>
 /// <param name="indent">the current indent level.</param>
 /// <param name="index">the index within the parent node (important for arrays)</param>
 private void DumpNode(StringBuilder result, bool recursive, int indent, int index
                       )
 {
     // write indent
     for (int i = 0; i < indent; i++)
     {
         result.Append('\t');
     }
     // render Node
     if (parent != null)
     {
         if (GetOptions().IsQualifier())
         {
             result.Append('?');
             result.Append(name);
         }
         else
         {
             if (GetParent().GetOptions().IsArray())
             {
                 result.Append('[');
                 result.Append(index);
                 result.Append(']');
             }
             else
             {
                 result.Append(name);
             }
         }
     }
     else
     {
         // applies only to the root node
         result.Append("ROOT NODE");
         if (name != null && name.Length > 0)
         {
             // the "about" attribute
             result.Append(" (");
             result.Append(name);
             result.Append(')');
         }
     }
     if (value != null && value.Length > 0)
     {
         result.Append(" = \"");
         result.Append(value);
         result.Append('"');
     }
     // render options if at least one is set
     if (GetOptions().ContainsOneOf(unchecked ((int)(0xffffffff))))
     {
         result.Append("\t(");
         result.Append(GetOptions().ToString());
         result.Append(" : ");
         result.Append(GetOptions().GetOptionsString());
         result.Append(')');
     }
     result.Append('\n');
     // render qualifier
     if (recursive && HasQualifier())
     {
         XMPNode[] quals = new XMPNode[GetQualifier().Count];
         GetQualifier().CopyTo(quals, 0);
         int i = 0;
         while (quals.Length > i && (XMPConst.XML_LANG.Equals(quals[i].GetName()) || "rdf:type"
                                     .Equals(quals[i].GetName())))
         {
             i++;
         }
         System.Array.Sort(quals, i, quals.Length);
         for (i = 0; i < quals.Length; i++)
         {
             iText.Kernel.XMP.Impl.XMPNode qualifier = quals[i];
             qualifier.DumpNode(result, recursive, indent + 2, i + 1);
         }
     }
     // render children
     if (recursive && HasChildren())
     {
         XMPNode[] children = new XMPNode[GetChildren().Count];
         GetChildren().CopyTo(children, 0);
         if (!GetOptions().IsArray())
         {
             System.Array.Sort(children);
         }
         for (int i = 0; i < children.Length; i++)
         {
             iText.Kernel.XMP.Impl.XMPNode child = children[i];
             child.DumpNode(result, recursive, indent + 1, i + 1);
         }
     }
 }
		/// <summary>Constructor for a cloned metadata tree.</summary>
		/// <param name="tree">
		/// an prefilled metadata tree which fulfills all
		/// <code>XMPNode</code> contracts.
		/// </param>
		public XMPMetaImpl(XMPNode tree)
		{
			this.tree = tree;
		}
		/// <summary>Performs a deep clone of the XMPMeta-object</summary>
		/// <seealso cref="System.Object.Clone()"/>
		public virtual Object Clone()
		{
			XMPNode clonedTree = (XMPNode)tree.Clone();
			return new XMPMetaImpl(clonedTree);
		}