/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jempbox.xmp;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.jempbox.impl.DateConverter;
import org.apache.jempbox.impl.XMLUtil;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* This class represents a metadata schema that can be stored in an XMP
* document. It handles all generic properties that are available. See
* subclasses for access to specific properties.
*
* @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
* @version $Revision: 1.8 $
*/
public class XMPSchema
{
/**
* The standard xmlns namespace.
*/
public static final String NS_NAMESPACE = "http://www.w3.org/2000/xmlns/";
/**
* The XML schema prefix.
*/
protected String prefix;
/**
* The DOM representation of this object.
*/
protected Element schema = null;
/**
* Create a new blank schema that can be populated.
*
* @param parent
* The parent XMP document that this schema will be part of.
* @param namespaceName
* The name of the namespace, ie pdf,dc,...
* @param namespaceURI
* The URI of the namespace, ie "http://ns.adobe.com/pdf/1.3/"
*/
public XMPSchema(XMPMetadata parent, String namespaceName,
String namespaceURI)
{
schema = parent.xmpDocument.createElementNS(
"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdf:Description");
prefix = namespaceName;
schema.setAttributeNS(NS_NAMESPACE, "xmlns:" + namespaceName,
namespaceURI);
}
/**
* Create schema from an existing XML element.
*
* @param element
* The existing XML element.
* @param aPrefix
* The XML prefix.
*/
public XMPSchema(Element element, String aPrefix)
{
schema = element;
if (aPrefix != null)
{
prefix = aPrefix;
}
else
{
prefix = "";
}
}
/**
* Get the XML element that is represented by this schema.
*
* @return The root XML element of this schema.
*/
public Element getElement()
{
return schema;
}
/**
* Get the RDF about attribute.
*
* @return The RDF 'about' attribute.
*/
public String getAbout()
{
return getTextProperty("rdf:about");
}
/**
* Set the RDF 'about' attribute. Passing in null will clear this attribute.
*
* @param about
* The new RFD about value.
*/
public void setAbout(String about)
{
if (about == null)
{
schema.removeAttribute("rdf:about");
}
else
{
schema.setAttribute("rdf:about", about);
}
}
/**
* Set a simple text property on the schema.
*
* @param propertyName
* The name of the property, it must contain the namespace
* prefix, ie "pdf:Keywords"
* @param propertyValue
* The value for the property, can be any string. Passing null
* will remove the property.
*/
public void setTextProperty(String propertyName, String propertyValue)
{
if (propertyValue == null)
{
schema.removeAttribute(propertyName);
NodeList keywordList = schema.getElementsByTagName(propertyName);
for (int i = 0; i < keywordList.getLength(); i++)
{
schema.removeChild(keywordList.item(i));
}
}
else
{
if (schema.hasAttribute(propertyName))
{
schema.setAttribute(propertyName, propertyValue);
}
else
{
if (schema.hasChildNodes())
{
NodeList nodeList = schema
.getElementsByTagName(propertyName);
if (nodeList.getLength() > 0)
{
Element node = (Element) nodeList.item(0);
node.setNodeValue(propertyValue);
}
else
{
Element textNode = schema.getOwnerDocument()
.createElement(propertyName);
XMLUtil.setStringValue(textNode, propertyValue);
schema.appendChild(textNode);
}
}
else
{
schema.setAttribute(propertyName, propertyValue);
}
}
}
}
/**
* Get the value of a simple text property.
*
* @param propertyName
* The name of the property to get, it must include the namespace
* prefix. ie "pdf:Keywords".
*
* @return The value of the text property or the null if there is no value.
*/
public String getTextProperty(String propertyName)
{
// propertyValue == null does not work, since getAttribute returns the
// empty string if the attribute is not found
if (schema.hasAttribute(propertyName))
{
return schema.getAttribute(propertyName);
}
else
{
NodeList nodes = schema.getElementsByTagName(propertyName);
if (nodes.getLength() > 0)
{
Element node = (Element) nodes.item(0);
return XMLUtil.getStringValue(node);
}
return null;
}
}
/**
* Get the value of the property as a date.
*
* @param propertyName
* The fully qualified property name for the date.
*
* @return The value of the property as a date.
*
* @throws IOException
* If there is an error converting the value to a date.
*/
public Calendar getDateProperty(String propertyName) throws IOException
{
return DateConverter.toCalendar(getTextProperty(propertyName));
}
/**
* Set the value of the property as a date.
*
* @param propertyName
* The fully qualified property name for the date.
* @param date
* The date to set, or null to clear.
*/
public void setDateProperty(String propertyName, Calendar date)
{
setTextProperty(propertyName, DateConverter.toISO8601(date));
}
/**
* Get the value of the property as a boolean.
*
* @param propertyName
* The fully qualified property name for the boolean.
*
* @return The value of the property as a boolean.
*/
public Boolean getBooleanProperty(String propertyName)
{
Boolean value = null;
String stringValue = getTextProperty(propertyName);
if (stringValue != null)
{
value = stringValue.equals("True") ? Boolean.TRUE : Boolean.FALSE;
}
return value;
}
/**
* Set the value of the property as a boolean.
*
* @param propertyName
* The fully qualified property name for the boolean.
* @param bool
* The boolean to set, or null to clear.
*/
public void setBooleanProperty(String propertyName, Boolean bool)
{
String value = null;
if (bool != null)
{
value = bool.booleanValue() ? "True" : "False";
}
setTextProperty(propertyName, value);
}
/**
* Get the value of the property as an integer.
*
* @param propertyName
* The fully qualified property name for the integer.
*
* @return The value of the property as an integer.
*/
public Integer getIntegerProperty(String propertyName)
{
Integer retval = null;
String intProperty = getTextProperty(propertyName);
if (intProperty != null && intProperty.length() > 0)
{
retval = new Integer(intProperty);
}
return retval;
}
/**
* Set the value of the property as an integer.
*
* @param propertyName
* The fully qualified property name for the integer.
* @param intValue
* The int to set, or null to clear.
*/
public void setIntegerProperty(String propertyName, Integer intValue)
{
String textValue = null;
if (intValue != null)
{
textValue = intValue.toString();
}
setTextProperty(propertyName, textValue);
}
/**
* Remove all matching entries with the given value from the bag.
*
* @param bagName
* The name of the bag, it must include the namespace prefix. ie
* "pdf:Keywords".
* @param bagValue
* The value to remove from the bagList.
*/
public void removeBagValue(String bagName, String bagValue)
{
Element bagElement = null;
NodeList nodes = schema.getElementsByTagName(bagName);
if (nodes.getLength() > 0)
{
Element contElement = (Element) nodes.item(0);
NodeList bagList = contElement.getElementsByTagName("rdf:Bag");
if (bagList.getLength() > 0)
{
bagElement = (Element) bagList.item(0);
NodeList items = bagElement.getElementsByTagName("rdf:li");
for (int i = items.getLength() - 1; i >= 0; i--)
{
Element li = (Element) items.item(i);
String value = XMLUtil.getStringValue(li);
if (value.equals(bagValue))
{
bagElement.removeChild(li);
}
}
}
}
}
/**
* Add an entry to a bag property.
*
* @param bagName
* The name of the bag, it must include the namespace prefix. ie
* "pdf:Keywords".
* @param bagValue
* The value to add to the bagList.
*/
public void addBagValue(String bagName, String bagValue)
{
Element bagElement = null;
NodeList nodes = schema.getElementsByTagName(bagName);
if (nodes.getLength() > 0)
{
Element contElement = (Element) nodes.item(0);
NodeList bagList = contElement.getElementsByTagName("rdf:Bag");
if (bagList.getLength() > 0)
{
bagElement = (Element) bagList.item(0);
}
}
else
{
Element contElement = schema.getOwnerDocument().createElement(
bagName);
schema.appendChild(contElement);
bagElement = schema.getOwnerDocument().createElement("rdf:Bag");
contElement.appendChild(bagElement);
}
Element liElement = schema.getOwnerDocument().createElement("rdf:li");
XMLUtil.setStringValue(liElement, bagValue);
bagElement.appendChild(liElement);
}
/**
* Get all the values of the bag property. This will return a list of
* java.lang.String objects, this is a read-only list.
*
* @param bagName
* The name of the bag property to get, it must include the
* namespace prefix. ie "pdf:Keywords"
*
* @return All of the values of the bag property in a list.
*/
public List<String> getBagList(String bagName)
{
List<String> retval = null;
NodeList nodes = schema.getElementsByTagName(bagName);
if (nodes.getLength() > 0)
{
Element contributor = (Element) nodes.item(0);
NodeList bagList = contributor.getElementsByTagName("rdf:Bag");
if (bagList.getLength() > 0)
{
Element bag = (Element) bagList.item(0);
retval = new ArrayList<String>();
NodeList items = bag.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
retval.add(XMLUtil.getStringValue(li));
}
retval = Collections.unmodifiableList(retval);
}
}
return retval;
}
/**
* Remove all matching values from a sequence property.
*
* @param seqName
* The name of the sequence property. It must include the
* namespace prefix. ie "pdf:Keywords".
* @param seqValue
* The value to remove from the list.
*/
public void removeSequenceValue(String seqName, String seqValue)
{
Element bagElement = null;
NodeList nodes = schema.getElementsByTagName(seqName);
if (nodes.getLength() > 0)
{
Element contElement = (Element) nodes.item(0);
NodeList bagList = contElement.getElementsByTagName("rdf:Seq");
if (bagList.getLength() > 0)
{
bagElement = (Element) bagList.item(0);
NodeList items = bagElement.getElementsByTagName("rdf:li");
for (int i = items.getLength() - 1; i >= 0; i--)
{
Element li = (Element) items.item(i);
String value = XMLUtil.getStringValue(li);
if (value.equals(seqValue))
{
bagElement.removeChild(li);
}
}
}
}
}
/**
* Remove a value from a sequence property. This will remove all entries
* from the list.
*
* @param seqName
* The name of the sequence property. It must include the
* namespace prefix. ie "pdf:Keywords".
* @param seqValue
* The value to remove from the list.
*/
public void removeSequenceValue(String seqName, Elementable seqValue)
{
Element bagElement = null;
NodeList nodes = schema.getElementsByTagName(seqName);
if (nodes.getLength() > 0)
{
Element contElement = (Element) nodes.item(0);
NodeList bagList = contElement.getElementsByTagName("rdf:Seq");
if (bagList.getLength() > 0)
{
bagElement = (Element) bagList.item(0);
NodeList items = bagElement.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
if (li == seqValue.getElement())
{
bagElement.removeChild(li);
}
}
}
}
}
/**
* Add a new value to a sequence property.
*
* @param seqName
* The name of the sequence property, it must include the
* namespace prefix. ie "pdf:Keywords"
* @param seqValue
* The value to add to the sequence.
*/
public void addSequenceValue(String seqName, String seqValue)
{
Element bagElement = null;
NodeList nodes = schema.getElementsByTagName(seqName);
if (nodes.getLength() > 0)
{
Element contElement = (Element) nodes.item(0);
NodeList bagList = contElement.getElementsByTagName("rdf:Seq");
if (bagList.getLength() > 0)
{
bagElement = (Element) bagList.item(0);
}
else
{
// xml is crap discard it
schema.removeChild(nodes.item(0));
}
}
if (bagElement == null)
{
Element contElement = schema.getOwnerDocument().createElement(
seqName);
schema.appendChild(contElement);
bagElement = schema.getOwnerDocument().createElement("rdf:Seq");
contElement.appendChild(bagElement);
}
Element liElement = schema.getOwnerDocument().createElement("rdf:li");
liElement.appendChild(schema.getOwnerDocument()
.createTextNode(seqValue));
bagElement.appendChild(liElement);
}
/**
* Add a new value to a sequence property.
*
* @param seqName
* The name of the sequence property, it must include the
* namespace prefix. ie "pdf:Keywords"
* @param seqValue
* The value to add to the sequence.
*/
public void addSequenceValue(String seqName, Elementable seqValue)
{
Element bagElement = null;
NodeList nodes = schema.getElementsByTagName(seqName);
if (nodes.getLength() > 0)
{
Element contElement = (Element) nodes.item(0);
NodeList bagList = contElement.getElementsByTagName("rdf:Seq");
if (bagList.getLength() > 0)
{
bagElement = (Element) bagList.item(0);
}
}
else
{
Element contElement = schema.getOwnerDocument().createElement(
seqName);
schema.appendChild(contElement);
bagElement = schema.getOwnerDocument().createElement("rdf:Seq");
contElement.appendChild(bagElement);
}
bagElement.appendChild(seqValue.getElement());
}
/**
* Get all the values in a sequence property.
*
* @param seqName
* The name of the sequence property, it must include the
* namespace prefix. ie "pdf:Keywords".
*
* @return A read-only list of java.lang.String objects or null if the
* property does not exist.
*/
public List<String> getSequenceList(String seqName)
{
List<String> retval = null;
NodeList nodes = schema.getElementsByTagName(seqName);
if (nodes.getLength() > 0)
{
Element contributor = (Element) nodes.item(0);
NodeList bagList = contributor.getElementsByTagName("rdf:Seq");
if (bagList.getLength() > 0)
{
Element bag = (Element) bagList.item(0);
retval = new ArrayList<String>();
NodeList items = bag.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
retval.add(XMLUtil.getStringValue(li));
}
retval = Collections.unmodifiableList(retval);
}
}
return retval;
}
/**
* Get a list of ResourceEvent objects.
*
* @param seqName
* The name of the sequence to retrieve.
*
* @return A list of ResourceEvent objects or null if they do not exist.
*/
public List<ResourceEvent> getEventSequenceList(String seqName)
{
List<ResourceEvent> retval = null;
NodeList nodes = schema.getElementsByTagName(seqName);
if (nodes.getLength() > 0)
{
Element contributor = (Element) nodes.item(0);
NodeList bagList = contributor.getElementsByTagName("rdf:Seq");
if (bagList.getLength() > 0)
{
Element bag = (Element) bagList.item(0);
retval = new ArrayList<ResourceEvent>();
NodeList items = bag.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
retval.add(new ResourceEvent(li));
}
retval = Collections.unmodifiableList(retval);
}
}
return retval;
}
/**
* Remove a date sequence value from the list.
*
* @param seqName
* The name of the sequence property, it must include the
* namespace prefix. ie "pdf:Keywords"
* @param date
* The date to remove from the sequence property.
*/
public void removeSequenceDateValue(String seqName, Calendar date)
{
String dateAsString = DateConverter.toISO8601(date);
removeSequenceValue(seqName, dateAsString);
}
/**
* Add a date sequence value to the list.
*
* @param seqName
* The name of the sequence property, it must include the
* namespace prefix. ie "pdf:Keywords"
* @param date
* The date to add to the sequence property.
*/
public void addSequenceDateValue(String seqName, Calendar date)
{
String dateAsString = DateConverter.toISO8601(date);
addSequenceValue(seqName, dateAsString);
}
/**
* Get all the date values in a sequence property.
*
* @param seqName
* The name of the sequence property, it must include the
* namespace prefix. ie "pdf:Keywords".
*
* @return A read-only list of java.util.Calendar objects or null if the
* property does not exist.
*
* @throws IOException
* If there is an error converting the value to a date.
*/
public List<Calendar> getSequenceDateList(String seqName) throws IOException
{
List<String> strings = getSequenceList(seqName);
List<Calendar> retval = null;
if (strings != null)
{
retval = new ArrayList<Calendar>();
for (int i = 0; i < strings.size(); i++)
{
retval.add(DateConverter.toCalendar(strings.get(i)));
}
}
return retval;
}
/**
* Set the value of a multi-lingual property.
*
* @param propertyName
* The name of the property, it must include the namespace
* prefix. ie "pdf:Keywords"
* @param language
* The language code of the value. If null then "x-default" is
* assumed.
* @param value
* The value of the property in the specified language.
*/
public void setLanguageProperty(String propertyName, String language,
String value)
{
NodeList nodes = schema.getElementsByTagName(propertyName);
Element property = null;
if (nodes.getLength() == 0)
{
if (value == null)
{
// value is null, it doesn't already exist so there
// is nothing to do.
return;
}
property = schema.getOwnerDocument().createElement(propertyName);
schema.appendChild(property);
}
else
{
property = (Element) nodes.item(0);
}
Element alt = null;
NodeList altList = property.getElementsByTagName("rdf:Alt");
if (altList.getLength() == 0)
{
if (value == null)
{
// value is null, it doesn't already exist so there
// is nothing to do.
return;
}
alt = schema.getOwnerDocument().createElement("rdf:Alt");
property.appendChild(alt);
}
else
{
alt = (Element) altList.item(0);
}
NodeList items = alt.getElementsByTagName("rdf:li");
if (language == null)
{
language = "x-default";
}
boolean foundValue = false;
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
if (value == null)
{
alt.removeChild(li);
}
else if (language.equals(li.getAttribute("xml:lang")))
{
foundValue = true;
XMLUtil.setStringValue(li, value);
}
}
if (value != null && !foundValue)
{
Element li = schema.getOwnerDocument().createElement("rdf:li");
li.setAttribute("xml:lang", language);
XMLUtil.setStringValue(li, value);
if (language.equals("x-default"))
{
// default should be first element, see XMP spec
alt.insertBefore(li, alt.getFirstChild());
}
else
{
alt.appendChild(li);
}
}
}
/**
* Get the value of a multi-lingual property.
*
* @param propertyName
* The name of the property, it must include the namespace
* prefix. ie "pdf:Keywords"
* @param language
* The language code of the value. If null then "x-default" is
* assumed.
*
* @return The value of the language property.
*/
public String getLanguageProperty(String propertyName, String language)
{
String retval = null;
if (language == null)
{
language = "x-default";
}
NodeList nodes = schema.getElementsByTagName(propertyName);
if (nodes.getLength() > 0)
{
Element property = (Element) nodes.item(0);
NodeList altList = property.getElementsByTagName("rdf:Alt");
if (altList.getLength() > 0)
{
Element alt = (Element) altList.item(0);
NodeList items = alt.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength() && retval == null; i++)
{
Element li = (Element) items.item(i);
String elementLanguage = li.getAttribute("xml:lang");
if (language.equals(elementLanguage))
{
retval = XMLUtil.getStringValue(li);
}
}
}
else if (property.getChildNodes().getLength() == 1 && Node.TEXT_NODE == property.getFirstChild().getNodeType())
{
retval = property.getFirstChild().getNodeValue();
}
}
return retval;
}
/**
* Set the value of a multi-lingual property.
*
* @param propertyName
* The name of the property, it must include the namespace
* prefix. ie "pdf:Keywords"
* @param language
* The language code of the value. If null then "x-default" is
* assumed.
* @param value
* The value of the property in the specified language.
*/
public void setThumbnailProperty(String propertyName, String language,
Thumbnail value)
{
NodeList nodes = schema.getElementsByTagName(propertyName);
Element property = null;
if (nodes.getLength() == 0)
{
if (value == null)
{
// value is null, it doesn't already exist so there
// is nothing to do.
return;
}
property = schema.getOwnerDocument().createElement(propertyName);
schema.appendChild(property);
}
else
{
property = (Element) nodes.item(0);
}
Element alt = null;
NodeList altList = property.getElementsByTagName("rdf:Alt");
if (altList.getLength() == 0)
{
if (value == null)
{
// value is null, it doesn't already exist so there
// is nothing to do.
return;
}
alt = schema.getOwnerDocument().createElement("rdf:Alt");
property.appendChild(alt);
}
else
{
alt = (Element) altList.item(0);
}
NodeList items = alt.getElementsByTagName("rdf:li");
if (language == null)
{
language = "x-default";
}
boolean foundValue = false;
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
if (value == null)
{
alt.removeChild(li);
}
else if (language.equals(li.getAttribute("xml:lang")))
{
foundValue = true;
alt.replaceChild(li, value.getElement());
}
}
if (value != null && !foundValue)
{
Element li = value.getElement();
li.setAttribute("xml:lang", language);
if (language.equals("x-default"))
{
// default should be first element, see XMP spec
alt.insertBefore(li, alt.getFirstChild());
}
else
{
alt.appendChild(li);
}
}
}
/**
* Get the value of a multi-lingual property.
*
* @param propertyName
* The name of the property, it must include the namespace
* prefix. ie "pdf:Keywords"
* @param language
* The language code of the value. If null then "x-default" is
* assumed.
*
* @return The value of the language property.
*/
public Thumbnail getThumbnailProperty(String propertyName, String language)
{
Thumbnail retval = null;
if (language == null)
{
language = "x-default";
}
NodeList nodes = schema.getElementsByTagName(propertyName);
if (nodes.getLength() > 0)
{
Element property = (Element) nodes.item(0);
NodeList altList = property.getElementsByTagName("rdf:Alt");
if (altList.getLength() > 0)
{
Element alt = (Element) altList.item(0);
NodeList items = alt.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength() && retval == null; i++)
{
Element li = (Element) items.item(i);
String elementLanguage = li.getAttribute("xml:lang");
if (language.equals(elementLanguage))
{
retval = new Thumbnail(li);
}
}
}
}
return retval;
}
/**
* Get a list of all languages that are currently defined for a specific
* property.
*
* @param propertyName
* The name of the property, it must include the namespace
* prefix. ie "pdf:Keywords"
*
* @return A list of all languages, this will return an non-null empty list
* if none have been defined.
*/
public List<String> getLanguagePropertyLanguages(String propertyName)
{
List<String> retval = new ArrayList<String>();
NodeList nodes = schema.getElementsByTagName(propertyName);
if (nodes.getLength() > 0)
{
Element property = (Element) nodes.item(0);
NodeList altList = property.getElementsByTagName("rdf:Alt");
if (altList.getLength() > 0)
{
Element alt = (Element) altList.item(0);
NodeList items = alt.getElementsByTagName("rdf:li");
for (int i = 0; i < items.getLength(); i++)
{
Element li = (Element) items.item(i);
String elementLanguage = li.getAttribute("xml:lang");
if (elementLanguage == null)
{
retval.add("x-default");
}
else
{
retval.add(elementLanguage);
}
}
}
}
return retval;
}
/**
* A basic schema merge, it merges bags and sequences and replace everything
* else.
*
* @param xmpSchema The schema to merge.
* @throws IOException If there is an error during the merge.
*/
public void merge(XMPSchema xmpSchema) throws IOException
{
if (!xmpSchema.getClass().equals(this.getClass()))
{
throw new IOException("Can only merge schemas of the same type.");
}
NamedNodeMap attributes = xmpSchema.getElement().getAttributes();
for (int i = 0; i < attributes.getLength(); i++)
{
Node a = attributes.item(i);
String name = a.getNodeName();
if (name.startsWith(prefix))
{
String newValue = xmpSchema.getTextProperty(name);
setTextProperty(name, newValue);
}
}
NodeList nodes = xmpSchema.getElement().getChildNodes();
for (int i = 0; i < nodes.getLength(); i++)
{
Node a = nodes.item(i);
String name = a.getNodeName();
if (name.startsWith(prefix))
{
if (a instanceof Element)
{
Element e = (Element) a;
if (nodes.getLength() > 0)
{
NodeList seqList = e.getElementsByTagName("rdf:Seq");
if (seqList.getLength() > 0)
{
List<String> newList = xmpSchema.getSequenceList(name);
List<String> oldList = getSequenceList(name);
Iterator<String> it = newList.iterator();
while (it.hasNext())
{
String object = it.next();
if (oldList == null
|| !oldList.contains(object))
{
addSequenceValue(name, object);
}
}
continue;
}
NodeList bagList = e.getElementsByTagName("rdf:Bag");
if (bagList.getLength() > 0)
{
List<String> newList = xmpSchema.getBagList(name);
List<String> oldList = getBagList(name);
Iterator<String> it = newList.iterator();
while (it.hasNext())
{
String object = it.next();
if (oldList == null
|| !oldList.contains(object))
{
addBagValue(name, object);
}
}
continue;
}
}
}
String newValue = xmpSchema.getTextProperty(name);
setTextProperty(name, newValue);
}
}
}
}