/// <summary>Make sure that the array is well-formed AltText.</summary>
        /// <remarks>
        /// Make sure that the array is well-formed AltText. Each item must be simple
        /// and have an "xml:lang" qualifier. If repairs are needed, keep simple
        /// non-empty items by adding the "xml:lang" with value "x-repair".
        /// </remarks>
        /// <param name="arrayNode">the property node of the array to repair.</param>
        private static void RepairAltText(XMPNode arrayNode)
        {
            if (arrayNode == null || !arrayNode.GetOptions().IsArray())
            {
                // Already OK or not even an array.
                return;
            }

            // fix options
            arrayNode.GetOptions().SetArrayOrdered(true);
            arrayNode.GetOptions().SetArrayAlternate(true);
            arrayNode.GetOptions().SetArrayAltText(true);
            ArrayList   currChildsToRemove = new ArrayList();
            IEnumerator it = arrayNode.IterateChildren();

            while (it.MoveNext())
            {
                XMPNode currChild = (XMPNode)it.Current;
                if (currChild == null)
                {
                    continue;
                }
                if (currChild.GetOptions().IsCompositeProperty())
                {
                    // Delete non-simple children.
                    currChildsToRemove.Add(currChild);
                }
                else if (!currChild.GetOptions().GetHasLanguage())
                {
                    string childValue = currChild.GetValue();
                    if (String.IsNullOrEmpty(childValue))
                    {
                        // Delete empty valued children that have no xml:lang.
                        currChildsToRemove.Add(currChild);
                    }
                    else
                    {
                        // Add an xml:lang qualifier with the value "x-repair".
                        XMPNode repairLang = new XMPNode(XMPConst.XML_LANG, "x-repair", null);
                        currChild.AddQualifier(repairLang);
                    }
                }
            }
            foreach (object o in currChildsToRemove)
            {
                arrayNode.GetChildren().Remove(o);
            }
        }
Example #2
0
        /// <summary>Appends a language item to an alt text array.</summary>
        /// <param name="arrayNode">the language array</param>
        /// <param name="itemLang">the language of the item</param>
        /// <param name="itemValue">the content of the item</param>
        /// <exception cref="iText.Kernel.XMP.XMPException">Thrown if a duplicate property is added
        ///     </exception>
        internal static void AppendLangItem(XMPNode arrayNode, String itemLang, String itemValue
                                            )
        {
            XMPNode newItem  = new XMPNode(ARRAY_ITEM_NAME, itemValue, null);
            XMPNode langQual = new XMPNode(XML_LANG, itemLang, null);

            newItem.AddQualifier(langQual);
            if (!X_DEFAULT.Equals(langQual.GetValue()))
            {
                arrayNode.AddChild(newItem);
            }
            else
            {
                arrayNode.AddChild(1, newItem);
            }
        }
Example #3
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);
     }
 }
Example #4
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 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);
			}
		}
		/// <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;
		}