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.
boolean haveXDefault = false;
XMPNode xdItem = null;
for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
{
XMPNode currItem = (XMPNode) it.next();
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 = ((Integer) result[0]).intValue();
XMPNode itemNode = (XMPNode) result[1];
boolean 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.
assert haveXDefault && xdItem == itemNode;
for (Iterator it = arrayNode.iterateChildren(); it.hasNext();)
{
XMPNode currItem = (XMPNode) it.next();
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.