/// <summary>
 /// Tweak old XMP: Move an instance ID from rdf:about to the
 /// <em>xmpMM:InstanceID</em> property.
 /// </summary>
 /// <remarks>
 /// Tweak old XMP: Move an instance ID from rdf:about to the
 /// <em>xmpMM:InstanceID</em> property. An old instance ID usually looks
 /// like &quot;uuid:bac965c4-9d87-11d9-9a30-000d936b79c4&quot;, plus InDesign
 /// 3.0 wrote them like &quot;bac965c4-9d87-11d9-9a30-000d936b79c4&quot;. If
 /// the name looks like a UUID simply move it to <em>xmpMM:InstanceID</em>,
 /// don't worry about any existing <em>xmpMM:InstanceID</em>. Both will
 /// only be present when a newer file with the <em>xmpMM:InstanceID</em>
 /// property is updated by an old app that uses <em>rdf:about</em>.
 /// </remarks>
 /// <param name="tree">the root of the metadata tree</param>
 /// <exception cref="Com.Adobe.Xmp.XMPException">Thrown if tweaking fails.</exception>
 private static void TweakOldXMP(XMPNode tree)
 {
     if (tree.GetName() != null && tree.GetName().Length >= Utils.UuidLength)
     {
         string nameStr = tree.GetName().ToLower();
         if (nameStr.StartsWith("uuid:"))
         {
             nameStr = Sharpen.Runtime.Substring(nameStr, 5);
         }
         if (Utils.CheckUUIDFormat(nameStr))
         {
             // move UUID to xmpMM:InstanceID and remove it from the root node
             XMPPath path   = XMPPathParser.ExpandXPath(XMPConstConstants.NsXmpMm, "InstanceID");
             XMPNode idNode = XMPNodeUtils.FindNode(tree, path, true, null);
             if (idNode != null)
             {
                 idNode.SetOptions(null);
                 // Clobber any existing xmpMM:InstanceID.
                 idNode.SetValue("uuid:" + nameStr);
                 idNode.RemoveChildren();
                 idNode.RemoveQualifiers();
                 tree.SetName(null);
             }
             else
             {
                 throw new XMPException("Failure creating xmpMM:InstanceID", XMPErrorConstants.Internalfailure);
             }
         }
     }
 }
 /// <summary>
 /// Tweak old XMP: Move an instance ID from rdf:about to the
 /// <em>xmpMM:InstanceID</em> property.
 /// </summary>
 /// <remarks>
 /// Tweak old XMP: Move an instance ID from rdf:about to the
 /// <em>xmpMM:InstanceID</em> property. An old instance ID usually looks
 /// like &quot;uuid:bac965c4-9d87-11d9-9a30-000d936b79c4&quot;, plus InDesign
 /// 3.0 wrote them like &quot;bac965c4-9d87-11d9-9a30-000d936b79c4&quot;. If
 /// the name looks like a UUID simply move it to <em>xmpMM:InstanceID</em>,
 /// don't worry about any existing <em>xmpMM:InstanceID</em>. Both will
 /// only be present when a newer file with the <em>xmpMM:InstanceID</em>
 /// property is updated by an old app that uses <em>rdf:about</em>.
 /// </remarks>
 /// <param name="tree">the root of the metadata tree</param>
 /// <exception cref="iText.Kernel.XMP.XMPException">Thrown if tweaking fails.</exception>
 private static void TweakOldXMP(XMPNode tree)
 {
     if (tree.GetName() != null && tree.GetName().Length >= Utils.UUID_LENGTH)
     {
         String nameStr = tree.GetName().ToLower();
         if (nameStr.StartsWith("uuid:"))
         {
             nameStr = nameStr.Substring(5);
         }
         if (Utils.CheckUUIDFormat(nameStr))
         {
             // move UUID to xmpMM:InstanceID and remove it from the root node
             XMPPath path   = XMPPathParser.ExpandXPath(XMPConst.NS_XMP_MM, "InstanceID");
             XMPNode idNode = XMPNodeUtils.FindNode(tree, path, true, null);
             if (idNode != null)
             {
                 idNode.SetOptions(null);
                 // Clobber any existing xmpMM:InstanceID.
                 idNode.SetValue("uuid:" + nameStr);
                 idNode.RemoveChildren();
                 idNode.RemoveQualifiers();
                 tree.SetName(null);
             }
             else
             {
                 throw new XMPException("Failure creating xmpMM:InstanceID", XMPError.INTERNALFAILURE
                                        );
             }
         }
     }
 }
		public virtual XMPProperty GetLocalizedText(String schemaNS, String altTextName, 
			String genericLang, String specificLang)
		{
			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);
			XMPNode arrayNode = XMPNodeUtils.FindNode(tree, arrayPath, false, null);
			if (arrayNode == null)
			{
				return null;
			}
			Object[] result = XMPNodeUtils.ChooseLocalizedText(arrayNode, genericLang, specificLang
				);
			int match = (int)result[0];
			XMPNode itemNode = (XMPNode)result[1];
			if (match != XMPNodeUtils.CLT_NO_VALUES)
			{
				return new _XMPProperty_428(itemNode);
			}
			else
			{
				return null;
			}
		}
Exemple #4
0
        /// <summary>Constructor with optionsl initial values.</summary>
        /// <remarks>
        /// Constructor with optionsl initial values. If <code>propName</code> is provided,
        /// <code>schemaNS</code> has also be provided.
        /// </remarks>
        /// <param name="xmp">the iterated metadata object.</param>
        /// <param name="schemaNS">the iteration is reduced to this schema (optional)</param>
        /// <param name="propPath">the iteration is redurce to this property within the <code>schemaNS</code>
        ///     </param>
        /// <param name="options">
        /// advanced iteration options, see
        /// <see cref="iText.Kernel.XMP.Options.IteratorOptions"/>
        /// </param>
        /// <exception cref="iText.Kernel.XMP.XMPException">If the node defined by the paramters is not existing.
        ///     </exception>
        public XMPIteratorImpl(XMPMetaImpl xmp, String schemaNS, String propPath, IteratorOptions
                               options)
        {
            // make sure that options is defined at least with defaults
            this.options = options ?? new IteratorOptions();

            // the start node of the iteration depending on the schema and property filter
            XMPNode startNode;
            string  initialPath  = null;
            bool    baseSchema   = !String.IsNullOrEmpty(schemaNS);
            bool    baseProperty = !String.IsNullOrEmpty(propPath);

            if (!baseSchema && !baseProperty)
            {
                // complete tree will be iterated
                startNode = xmp.GetRoot();
            }
            else if (baseSchema && baseProperty)
            {
                // Schema and property node provided
                XMPPath path = XMPPathParser.ExpandXPath(schemaNS, propPath);

                // base path is the prop path without the property leaf
                XMPPath basePath = new XMPPath();
                for (int i = 0; i < path.Size() - 1; i++)
                {
                    basePath.Add(path.GetSegment(i));
                }

                startNode   = XMPNodeUtils.FindNode(xmp.GetRoot(), path, false, null);
                this.baseNS = schemaNS;
                initialPath = basePath.ToString();
            }
            else if (baseSchema && !baseProperty)
            {
                // Only Schema provided
                startNode = XMPNodeUtils.FindSchemaNode(xmp.GetRoot(), schemaNS, false);
            }
            else             // !baseSchema  &&  baseProperty
            {
                // No schema but property provided -> error
                throw new XMPException("Schema namespace URI is required", XMPError.BADSCHEMA);
            }


            // create iterator
            if (startNode != null)
            {
                this.nodeIterator = (!this.options.IsJustChildren())
                                        ? new NodeIterator(this, startNode, initialPath, 1)
                                        : new NodeIteratorChildren(this, startNode, initialPath);
            }
            else
            {
                // create null iterator
                this.nodeIterator = EmptyList.GetEnumerator();
            }
        }
Exemple #5
0
        // EMPTY
        /// <seealso cref="Com.Adobe.Xmp.XMPUtils.CatenateArrayItems(Com.Adobe.Xmp.XMPMeta, string, string, string, string, bool)"/>
        /// <param name="xmp">The XMP object containing the array to be catenated.</param>
        /// <param name="schemaNS">
        /// The schema namespace URI for the array. Must not be null or
        /// the empty string.
        /// </param>
        /// <param name="arrayName">
        /// The name of the array. May be a general path expression, must
        /// not be null or the empty string. Each item in the array must
        /// be a simple string value.
        /// </param>
        /// <param name="separator">
        /// The string to be used to separate the items in the catenated
        /// string. Defaults to &quot;; &quot;, ASCII semicolon and space
        /// (U+003B, U+0020).
        /// </param>
        /// <param name="quotes">
        /// The characters to be used as quotes around array items that
        /// contain a separator. Defaults to &apos;&quot;&apos;
        /// </param>
        /// <param name="allowCommas">Option flag to control the catenation.</param>
        /// <returns>Returns the string containing the catenated array items.</returns>
        /// <exception cref="Com.Adobe.Xmp.XMPException">Forwards the Exceptions from the metadata processing</exception>
        public static string CatenateArrayItems(XMPMeta xmp, string schemaNS, string arrayName, string separator, string quotes, bool allowCommas)
        {
            ParameterAsserts.AssertSchemaNS(schemaNS);
            ParameterAsserts.AssertArrayName(arrayName);
            ParameterAsserts.AssertImplementation(xmp);
            if (separator == null || separator.Length == 0)
            {
                separator = "; ";
            }
            if (quotes == null || quotes.Length == 0)
            {
                quotes = "\"";
            }
            XMPMetaImpl xmpImpl   = (XMPMetaImpl)xmp;
            XMPNode     arrayNode = null;
            XMPNode     currItem  = null;
            // Return an empty result if the array does not exist,
            // hurl if it isn't the right form.
            XMPPath arrayPath = XMPPathParser.ExpandXPath(schemaNS, arrayName);

            arrayNode = XMPNodeUtils.FindNode(xmpImpl.GetRoot(), arrayPath, false, null);
            if (arrayNode == null)
            {
                return(string.Empty);
            }
            else
            {
                if (!arrayNode.GetOptions().IsArray() || arrayNode.GetOptions().IsArrayAlternate())
                {
                    throw new XMPException("Named property must be non-alternate array", XMPErrorConstants.Badparam);
                }
            }
            // Make sure the separator is OK.
            CheckSeparator(separator);
            // Make sure the open and close quotes are a legitimate pair.
            char openQuote  = quotes[0];
            char closeQuote = CheckQuotes(quotes, openQuote);
            // Build the result, quoting the array items, adding separators.
            // Hurl if any item isn't simple.
            StringBuilder catinatedString = new StringBuilder();

            for (Iterator it = arrayNode.IterateChildren(); it.HasNext();)
            {
                currItem = (XMPNode)it.Next();
                if (currItem.GetOptions().IsCompositeProperty())
                {
                    throw new XMPException("Array items must be simple", XMPErrorConstants.Badparam);
                }
                string str = ApplyQuotes(currItem.GetValue(), openQuote, closeQuote, allowCommas);
                catinatedString.Append(str);
                if (it.HasNext())
                {
                    catinatedString.Append(separator);
                }
            }
            return(catinatedString.ToString());
        }
        /// <summary>Compose the path expression to select an alternate item by a field's value.</summary>
        /// <remarks>
        /// Compose the path expression to select an alternate item by a field's value. The path syntax
        /// allows two forms of &quot;content addressing&quot; that may be used to select an item in an
        /// array of alternatives. The form used in ComposeFieldSelector lets you select an item in an
        /// array of structs based on the value of one of the fields in the structs. The other form of
        /// content addressing is shown in ComposeLangSelector. For example, consider a simple struct
        /// that has two fields, the name of a city and the URI of an FTP site in that city. Use this to
        /// create an array of download alternatives. You can show the user a popup built from the values
        /// of the city fields. You can then get the corresponding URI as follows:
        /// <p>
        /// <blockquote>
        /// <pre>
        /// String path = composeFieldSelector ( schemaNS, &quot;Downloads&quot;, fieldNS,
        /// &quot;City&quot;, chosenCity );
        /// XMPProperty prop = xmpObj.getStructField ( schemaNS, path, fieldNS, &quot;URI&quot; );
        /// </pre>
        /// </blockquote>
        /// </remarks>
        /// <param name="arrayName">
        /// The name of the array. May be a general path expression, must not be
        /// <code>null</code> or the empty string.
        /// </param>
        /// <param name="fieldNS">
        /// The namespace URI for the field used as the selector. Must not be
        /// <code>null</code> or the empty string.
        /// </param>
        /// <param name="fieldName">
        /// The name of the field used as the selector. Must be a simple XML name, must
        /// not be <code>null</code> or the empty string. It must be the name of a field that is
        /// itself simple.
        /// </param>
        /// <param name="fieldValue">The desired value of the field.</param>
        /// <returns>
        /// Returns the composed path. This will be of the form
        /// <tt>ns:arrayName[fNS:fieldName='fieldValue']</tt>, where &quot;ns&quot; is the
        /// prefix for schemaNS and &quot;fNS&quot; is the prefix for fieldNS.
        /// </returns>
        /// <exception cref="XMPException">Thrown if the path to create is not valid.</exception>
        /// <exception cref="Com.Adobe.Xmp.XMPException"/>
        public static string ComposeFieldSelector(string arrayName, string fieldNS, string fieldName, string fieldValue)
        {
            XMPPath fieldPath = XMPPathParser.ExpandXPath(fieldNS, fieldName);

            if (fieldPath.Size() != 2)
            {
                throw new XMPException("The fieldName name must be simple", XMPErrorConstants.Badxpath);
            }
            return(arrayName + '[' + fieldPath.GetSegment(XMPPath.StepRootProp).GetName() + "=\"" + fieldValue + "\"]");
        }
		public virtual void AppendArrayItem(String schemaNS, String arrayName, PropertyOptions
			 arrayOptions, String itemValue, PropertyOptions itemOptions)
		{
			ParameterAsserts.AssertSchemaNS(schemaNS);
			ParameterAsserts.AssertArrayName(arrayName);
			if (arrayOptions == null)
			{
				arrayOptions = new PropertyOptions();
			}
			if (!arrayOptions.IsOnlyArrayOptions())
			{
				throw new XMPException("Only array form flags allowed for arrayOptions", XMPError
					.BADOPTIONS);
			}
			// Check if array options are set correctly.
			arrayOptions = XMPNodeUtils.VerifySetOptions(arrayOptions, null);
			// Locate or create the array. If it already exists, make sure the array
			// form from the options
			// parameter is compatible with the current state.
			XMPPath arrayPath = XMPPathParser.ExpandXPath(schemaNS, arrayName);
			// Just lookup, don't try to create.
			XMPNode arrayNode = XMPNodeUtils.FindNode(tree, arrayPath, false, null);
			if (arrayNode != null)
			{
				// The array exists, make sure the form is compatible. Zero
				// arrayForm means take what exists.
				if (!arrayNode.GetOptions().IsArray())
				{
					throw new XMPException("The named property is not an array", XMPError.BADXPATH);
				}
			}
			else
			{
				// if (arrayOptions != null && !arrayOptions.equalArrayTypes(arrayNode.getOptions()))
				// {
				// throw new XMPException("Mismatch of existing and specified array form", BADOPTIONS);
				// }
				// The array does not exist, try to create it.
				if (arrayOptions.IsArray())
				{
					arrayNode = XMPNodeUtils.FindNode(tree, arrayPath, true, arrayOptions);
					if (arrayNode == null)
					{
						throw new XMPException("Failure creating array node", XMPError.BADXPATH);
					}
				}
				else
				{
					// array options missing
					throw new XMPException("Explicit arrayOptions required to create new array", XMPError
						.BADOPTIONS);
				}
			}
			DoSetArrayItem(arrayNode, ARRAY_LAST_ITEM, itemValue, itemOptions, true);
		}
Exemple #8
0
        /// <summary>Compose the path expression to select an alternate item by a field's value.</summary>
        /// <remarks>
        /// Compose the path expression to select an alternate item by a field's value. The path syntax
        /// allows two forms of &amp;quot;content addressing&amp;quot; that may be used to select an item in an
        /// array of alternatives. The form used in ComposeFieldSelector lets you select an item in an
        /// array of structs based on the value of one of the fields in the structs. The other form of
        /// content addressing is shown in ComposeLangSelector. For example, consider a simple struct
        /// that has two fields, the name of a city and the URI of an FTP site in that city. Use this to
        /// create an array of download alternatives. You can show the user a popup built from the values
        /// of the city fields. You can then get the corresponding URI as follows:
        /// <blockquote>
        /// <pre>
        /// String path = composeFieldSelector ( schemaNS, &amp;quot;Downloads&amp;quot;, fieldNS,
        /// &amp;quot;City&amp;quot;, chosenCity );
        /// XMPProperty prop = xmpObj.getStructField ( schemaNS, path, fieldNS, &amp;quot;URI&amp;quot; );
        /// </pre>
        /// </blockquote>
        /// </remarks>
        /// <param name="arrayName">
        /// The name of the array. May be a general path expression, must not be
        /// <c>null</c> or the empty string.
        /// </param>
        /// <param name="fieldNS">
        /// The namespace URI for the field used as the selector. Must not be
        /// <c>null</c> or the empty string.
        /// </param>
        /// <param name="fieldName">
        /// The name of the field used as the selector. Must be a simple XML name, must
        /// not be <c>null</c> or the empty string. It must be the name of a field that is
        /// itself simple.
        /// </param>
        /// <param name="fieldValue">The desired value of the field.</param>
        /// <returns>
        /// Returns the composed path. This will be of the form
        /// <tt>ns:arrayName[fNS:fieldName='fieldValue']</tt>, where &amp;quot;ns&amp;quot; is the
        /// prefix for schemaNS and &amp;quot;fNS&amp;quot; is the prefix for fieldNS.
        /// </returns>
        public static String ComposeFieldSelector(String arrayName, String fieldNS, String fieldName, String fieldValue
                                                  )
        {
            XMPPath fieldPath = XMPPathParser.ExpandXPath(fieldNS, fieldName);

            if (fieldPath.Size() != 2)
            {
                throw new XMPException("The fieldName name must be simple", XMPError.BADXPATH);
            }
            return(arrayName + '[' + fieldPath.GetSegment(XMPPath.STEP_ROOT_PROP).GetName() + "=\"" + fieldValue + "\"]");
        }
        /// <summary>Compose the path expression for a qualifier.</summary>
        /// <param name="qualNS">
        /// The namespace URI for the qualifier. May be <code>null</code> or the empty
        /// string if the qualifier is in the XML empty namespace.
        /// </param>
        /// <param name="qualName">
        /// The name of the qualifier. Must be a simple XML name, must not be
        /// <code>null</code> or the empty string.
        /// </param>
        /// <returns>
        /// Returns the composed path. This will be of the form
        /// <tt>ns:propName/?qNS:qualName</tt>, where &quot;ns&quot; is the prefix for
        /// schemaNS and &quot;qNS&quot; is the prefix for qualNS.
        /// </returns>
        /// <exception cref="XMPException">Thrown if the path to create is not valid.</exception>
        /// <exception cref="Com.Adobe.Xmp.XMPException"/>
        public static string ComposeQualifierPath(string qualNS, string qualName)
        {
            AssertQualNS(qualNS);
            AssertQualName(qualName);
            XMPPath qualPath = XMPPathParser.ExpandXPath(qualNS, qualName);

            if (qualPath.Size() != 2)
            {
                throw new XMPException("The qualifier name must be simple", XMPErrorConstants.Badxpath);
            }
            return("/?" + qualPath.GetSegment(XMPPath.StepRootProp).GetName());
        }
        /// <summary>Compose the path expression for a field in a struct.</summary>
        /// <remarks>
        /// Compose the path expression for a field in a struct. The result can be added to the
        /// path of
        /// </remarks>
        /// <param name="fieldNS">
        /// The namespace URI for the field. Must not be <code>null</code> or the empty
        /// string.
        /// </param>
        /// <param name="fieldName">
        /// The name of the field. Must be a simple XML name, must not be
        /// <code>null</code> or the empty string.
        /// </param>
        /// <returns>
        /// Returns the composed path. This will be of the form
        /// <tt>ns:structName/fNS:fieldName</tt>, where &quot;ns&quot; is the prefix for
        /// schemaNS and &quot;fNS&quot; is the prefix for fieldNS.
        /// </returns>
        /// <exception cref="XMPException">Thrown if the path to create is not valid.</exception>
        /// <exception cref="Com.Adobe.Xmp.XMPException"/>
        public static string ComposeStructFieldPath(string fieldNS, string fieldName)
        {
            AssertFieldNS(fieldNS);
            AssertFieldName(fieldName);
            XMPPath fieldPath = XMPPathParser.ExpandXPath(fieldNS, fieldName);

            if (fieldPath.Size() != 2)
            {
                throw new XMPException("The field name must be simple", XMPErrorConstants.Badxpath);
            }
            return('/' + fieldPath.GetSegment(XMPPath.StepRootProp).GetName());
        }
Exemple #11
0
        /// <summary>Compose the path expression for a field in a struct.</summary>
        /// <remarks>
        /// Compose the path expression for a field in a struct. The result can be added to the
        /// path of
        /// </remarks>
        /// <param name="fieldNS">
        /// The namespace URI for the field. Must not be <c>null</c> or the empty
        /// string.
        /// </param>
        /// <param name="fieldName">
        /// The name of the field. Must be a simple XML name, must not be
        /// <c>null</c> or the empty string.
        /// </param>
        /// <returns>
        /// Returns the composed path. This will be of the form
        /// <tt>ns:structName/fNS:fieldName</tt>, where &amp;quot;ns&amp;quot; is the prefix for
        /// schemaNS and &amp;quot;fNS&amp;quot; is the prefix for fieldNS.
        /// </returns>
        public static String ComposeStructFieldPath(String fieldNS, String fieldName)
        {
            AssertFieldNS(fieldNS);
            AssertFieldName(fieldName);
            XMPPath fieldPath = XMPPathParser.ExpandXPath(fieldNS, fieldName);

            if (fieldPath.Size() != 2)
            {
                throw new XMPException("The field name must be simple", XMPError.BADXPATH);
            }
            return('/' + fieldPath.GetSegment(XMPPath.STEP_ROOT_PROP).GetName());
        }
Exemple #12
0
        /// <summary>Compose the path expression for a qualifier.</summary>
        /// <param name="qualNS">
        /// The namespace URI for the qualifier. May be <c>null</c> or the empty
        /// string if the qualifier is in the XML empty namespace.
        /// </param>
        /// <param name="qualName">
        /// The name of the qualifier. Must be a simple XML name, must not be
        /// <c>null</c> or the empty string.
        /// </param>
        /// <returns>
        /// Returns the composed path. This will be of the form
        /// <tt>ns:propName/?qNS:qualName</tt>, where &amp;quot;ns&amp;quot; is the prefix for
        /// schemaNS and &amp;quot;qNS&amp;quot; is the prefix for qualNS.
        /// </returns>
        public static String ComposeQualifierPath(String qualNS, String qualName)
        {
            AssertQualNS(qualNS);
            AssertQualName(qualName);
            XMPPath qualPath = XMPPathParser.ExpandXPath(qualNS, qualName);

            if (qualPath.Size() != 2)
            {
                throw new XMPException("The qualifier name must be simple", XMPError.BADXPATH);
            }
            return("/?" + qualPath.GetSegment(XMPPath.STEP_ROOT_PROP).GetName());
        }
		public virtual bool DoesPropertyExist(String schemaNS, String propName)
		{
			try
			{
				ParameterAsserts.AssertSchemaNS(schemaNS);
				ParameterAsserts.AssertPropName(propName);
				XMPPath expPath = XMPPathParser.ExpandXPath(schemaNS, propName);
				XMPNode propNode = XMPNodeUtils.FindNode(tree, expPath, false, null);
				return propNode != null;
			}
			catch (XMPException)
			{
				return false;
			}
		}
		public virtual void SetProperty(String schemaNS, String propName, Object propValue
			, PropertyOptions options)
		{
			ParameterAsserts.AssertSchemaNS(schemaNS);
			ParameterAsserts.AssertPropName(propName);
			options = XMPNodeUtils.VerifySetOptions(options, propValue);
			XMPPath expPath = XMPPathParser.ExpandXPath(schemaNS, propName);
			XMPNode propNode = XMPNodeUtils.FindNode(tree, expPath, true, options);
			if (propNode != null)
			{
				SetNode(propNode, propValue, options, false);
			}
			else
			{
				throw new XMPException("Specified property does not exist", XMPError.BADXPATH);
			}
		}
		public virtual void InsertArrayItem(String schemaNS, String arrayName, int itemIndex
			, String itemValue, PropertyOptions options)
		{
			ParameterAsserts.AssertSchemaNS(schemaNS);
			ParameterAsserts.AssertArrayName(arrayName);
			// Just lookup, don't try to create.
			XMPPath arrayPath = XMPPathParser.ExpandXPath(schemaNS, arrayName);
			XMPNode arrayNode = XMPNodeUtils.FindNode(tree, arrayPath, false, null);
			if (arrayNode != null)
			{
				DoSetArrayItem(arrayNode, itemIndex, itemValue, options, true);
			}
			else
			{
				throw new XMPException("Specified array does not exist", XMPError.BADXPATH);
			}
		}
		public virtual void DeleteProperty(String schemaNS, String propName)
		{
			try
			{
				ParameterAsserts.AssertSchemaNS(schemaNS);
				ParameterAsserts.AssertPropName(propName);
				XMPPath expPath = XMPPathParser.ExpandXPath(schemaNS, propName);
				XMPNode propNode = XMPNodeUtils.FindNode(tree, expPath, false, null);
				if (propNode != null)
				{
					XMPNodeUtils.DeleteNode(propNode);
				}
			}
			catch (XMPException)
			{
				// EMPTY, exceptions are ignored within delete
			}
		}
		public virtual int CountArrayItems(String schemaNS, String arrayName)
		{
			ParameterAsserts.AssertSchemaNS(schemaNS);
			ParameterAsserts.AssertArrayName(arrayName);
			XMPPath arrayPath = XMPPathParser.ExpandXPath(schemaNS, arrayName);
			XMPNode arrayNode = XMPNodeUtils.FindNode(tree, arrayPath, false, null);
			if (arrayNode == null)
			{
				return 0;
			}
			if (arrayNode.GetOptions().IsArray())
			{
				return arrayNode.GetChildrenLength();
			}
			else
			{
				throw new XMPException("The named property is not an array", XMPError.BADXPATH);
			}
		}
		/// <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 #19
0
        /// <summary>Utility to find or create the array used by <code>SeparateArrayItems()</code>.</summary>
        /// <param name="schemaNS">a the namespace fo the array</param>
        /// <param name="arrayName">the name of the array</param>
        /// <param name="arrayOptions">the options for the array if newly created</param>
        /// <param name="xmp">the xmp object</param>
        /// <returns>Returns the array node.</returns>
        /// <exception cref="Com.Adobe.Xmp.XMPException">Forwards exceptions</exception>
        private static XMPNode SeparateFindCreateArray(string schemaNS, string arrayName, PropertyOptions arrayOptions, XMPMetaImpl xmp)
        {
            arrayOptions = XMPNodeUtils.VerifySetOptions(arrayOptions, null);
            if (!arrayOptions.IsOnlyArrayOptions())
            {
                throw new XMPException("Options can only provide array form", XMPErrorConstants.Badoptions);
            }
            // Find the array node, make sure it is OK. Move the current children
            // aside, to be readded later if kept.
            XMPPath arrayPath = XMPPathParser.ExpandXPath(schemaNS, arrayName);
            XMPNode arrayNode = XMPNodeUtils.FindNode(xmp.GetRoot(), arrayPath, false, null);

            if (arrayNode != null)
            {
                // The array exists, make sure the form is compatible. Zero
                // arrayForm means take what exists.
                PropertyOptions arrayForm = arrayNode.GetOptions();
                if (!arrayForm.IsArray() || arrayForm.IsArrayAlternate())
                {
                    throw new XMPException("Named property must be non-alternate array", XMPErrorConstants.Badxpath);
                }
                if (arrayOptions.EqualArrayTypes(arrayForm))
                {
                    throw new XMPException("Mismatch of specified and existing array form", XMPErrorConstants.Badxpath);
                }
            }
            else
            {
                // *** Right error?
                // The array does not exist, try to create it.
                // don't modify the options handed into the method
                arrayNode = XMPNodeUtils.FindNode(xmp.GetRoot(), arrayPath, true, arrayOptions.SetArray(true));
                if (arrayNode == null)
                {
                    throw new XMPException("Failed to create named array", XMPErrorConstants.Badxpath);
                }
            }
            return(arrayNode);
        }
Exemple #20
0
        /// <seealso cref="Com.Adobe.Xmp.XMPUtils.RemoveProperties(Com.Adobe.Xmp.XMPMeta, string, string, bool, bool)"/>
        /// <param name="xmp">The XMP object containing the properties to be removed.</param>
        /// <param name="schemaNS">
        /// Optional schema namespace URI for the properties to be
        /// removed.
        /// </param>
        /// <param name="propName">Optional path expression for the property to be removed.</param>
        /// <param name="doAllProperties">
        /// Option flag to control the deletion: do internal properties in
        /// addition to external properties.
        /// </param>
        /// <param name="includeAliases">
        /// Option flag to control the deletion: Include aliases in the
        /// "named schema" case above.
        /// </param>
        /// <exception cref="Com.Adobe.Xmp.XMPException">If metadata processing fails</exception>
        public static void RemoveProperties(XMPMeta xmp, string schemaNS, string propName, bool doAllProperties, bool includeAliases)
        {
            ParameterAsserts.AssertImplementation(xmp);
            XMPMetaImpl xmpImpl = (XMPMetaImpl)xmp;

            if (propName != null && propName.Length > 0)
            {
                // Remove just the one indicated property. This might be an alias,
                // the named schema might not actually exist. So don't lookup the
                // schema node.
                if (schemaNS == null || schemaNS.Length == 0)
                {
                    throw new XMPException("Property name requires schema namespace", XMPErrorConstants.Badparam);
                }
                XMPPath expPath  = XMPPathParser.ExpandXPath(schemaNS, propName);
                XMPNode propNode = XMPNodeUtils.FindNode(xmpImpl.GetRoot(), expPath, false, null);
                if (propNode != null)
                {
                    if (doAllProperties || !Utils.IsInternalProperty(expPath.GetSegment(XMPPath.StepSchema).GetName(), expPath.GetSegment(XMPPath.StepRootProp).GetName()))
                    {
                        XMPNode parent = propNode.GetParent();
                        parent.RemoveChild(propNode);
                        if (parent.GetOptions().IsSchemaNode() && !parent.HasChildren())
                        {
                            // remove empty schema node
                            parent.GetParent().RemoveChild(parent);
                        }
                    }
                }
            }
            else
            {
                if (schemaNS != null && schemaNS.Length > 0)
                {
                    // Remove all properties from the named schema. Optionally include
                    // aliases, in which case
                    // there might not be an actual schema node.
                    // XMP_NodePtrPos schemaPos;
                    XMPNode schemaNode = XMPNodeUtils.FindSchemaNode(xmpImpl.GetRoot(), schemaNS, false);
                    if (schemaNode != null)
                    {
                        if (RemoveSchemaChildren(schemaNode, doAllProperties))
                        {
                            xmpImpl.GetRoot().RemoveChild(schemaNode);
                        }
                    }
                    if (includeAliases)
                    {
                        // We're removing the aliases also. Look them up by their
                        // namespace prefix.
                        // But that takes more code and the extra speed isn't worth it.
                        // Lookup the XMP node
                        // from the alias, to make sure the actual exists.
                        XMPAliasInfo[] aliases = XMPMetaFactory.GetSchemaRegistry().FindAliases(schemaNS);
                        for (int i = 0; i < aliases.Length; i++)
                        {
                            XMPAliasInfo info       = aliases[i];
                            XMPPath      path       = XMPPathParser.ExpandXPath(info.GetNamespace(), info.GetPropName());
                            XMPNode      actualProp = XMPNodeUtils.FindNode(xmpImpl.GetRoot(), path, false, null);
                            if (actualProp != null)
                            {
                                XMPNode parent = actualProp.GetParent();
                                parent.RemoveChild(actualProp);
                            }
                        }
                    }
                }
                else
                {
                    // Remove all appropriate properties from all schema. In this case
                    // we don't have to be
                    // concerned with aliases, they are handled implicitly from the
                    // actual properties.
                    for (Iterator it = xmpImpl.GetRoot().IterateChildren(); it.HasNext();)
                    {
                        XMPNode schema = (XMPNode)it.Next();
                        if (RemoveSchemaChildren(schema, doAllProperties))
                        {
                            it.Remove();
                        }
                    }
                }
            }
        }
		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 #22
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);
        }
Exemple #23
0
        /// <summary>Constructor with optionsl initial values.</summary>
        /// <remarks>
        /// Constructor with optionsl initial values. If <code>propName</code> is provided,
        /// <code>schemaNS</code> has also be provided.
        /// </remarks>
        /// <param name="xmp">the iterated metadata object.</param>
        /// <param name="schemaNS">the iteration is reduced to this schema (optional)</param>
        /// <param name="propPath">the iteration is redurce to this property within the <code>schemaNS</code></param>
        /// <param name="options">
        /// advanced iteration options, see
        /// <see cref="Com.Adobe.Xmp.Options.IteratorOptions"/>
        /// </param>
        /// <exception cref="Com.Adobe.Xmp.XMPException">If the node defined by the paramters is not existing.</exception>
        public XMPIteratorImpl(XMPMetaImpl xmp, string schemaNS, string propPath, IteratorOptions options)
        {
            // make sure that options is defined at least with defaults
            this.options = options != null ? options : new IteratorOptions();
            // the start node of the iteration depending on the schema and property filter
            XMPNode startNode    = null;
            string  initialPath  = null;
            bool    baseSchema   = schemaNS != null && schemaNS.Length > 0;
            bool    baseProperty = propPath != null && propPath.Length > 0;

            if (!baseSchema && !baseProperty)
            {
                // complete tree will be iterated
                startNode = xmp.GetRoot();
            }
            else
            {
                if (baseSchema && baseProperty)
                {
                    // Schema and property node provided
                    XMPPath path = XMPPathParser.ExpandXPath(schemaNS, propPath);
                    // base path is the prop path without the property leaf
                    XMPPath basePath = new XMPPath();
                    for (int i = 0; i < path.Size() - 1; i++)
                    {
                        basePath.Add(path.GetSegment(i));
                    }
                    startNode   = XMPNodeUtils.FindNode(xmp.GetRoot(), path, false, null);
                    baseNS      = schemaNS;
                    initialPath = basePath.ToString();
                }
                else
                {
                    if (baseSchema && !baseProperty)
                    {
                        // Only Schema provided
                        startNode = XMPNodeUtils.FindSchemaNode(xmp.GetRoot(), schemaNS, false);
                    }
                    else
                    {
                        // !baseSchema  &&  baseProperty
                        // No schema but property provided -> error
                        throw new XMPException("Schema namespace URI is required", XMPErrorConstants.Badschema);
                    }
                }
            }
            // create iterator
            if (startNode != null)
            {
                if (!this.options.IsJustChildren())
                {
                    nodeIterator = new XMPIteratorImpl.NodeIterator(this, startNode, initialPath, 1);
                }
                else
                {
                    nodeIterator = new XMPIteratorImpl.NodeIteratorChildren(this, startNode, initialPath);
                }
            }
            else
            {
                // create null iterator
                nodeIterator = Collections.EmptyList().ListIterator();
            }
        }