blob: d7718d6f73f0f751c4a5257405e6f2b06bf14b76 [file] [log] [blame]
/*
* 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.
*/
/* $Id$ */
package org.apache.xmlgraphics.xmp;
import java.net.URI;
import java.util.Iterator;
import java.util.Map;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.xmlgraphics.util.QName;
import org.apache.xmlgraphics.util.XMLizable;
/**
* This class is the base class for all XMP properties.
*/
public class XMPProperty implements XMLizable {
private QName name;
private Object value;
private String xmllang;
private Map qualifiers;
protected boolean attribute;
/**
* Creates a new XMP property.
* @param name the name of the property
* @param value the value for the property
*/
public XMPProperty(QName name, Object value) {
this.name = name;
this.value = value;
}
/** @return the qualified name of the property (namespace URI + local name) */
public QName getName() {
return this.name;
}
/** @return the namespace URI of the property */
public String getNamespace() {
return getName().getNamespaceURI();
}
/**
* Sets the value of the property
* @param value the new value
*/
public void setValue(Object value) {
this.value = value;
}
/**
* @return the property value (can be a normal Java object (normally a String) or a descendant
* of XMPComplexValue.
*/
public Object getValue() {
return this.value;
}
/**
* Sets the xml:lang value for this property
* @param lang the language ("x-default" for the default language, null to make the value
* language-independent)
*/
public void setXMLLang(String lang) {
this.xmllang = lang;
}
/**
* @return the language for language-dependent values ("x-default" for the default language)
*/
public String getXMLLang() {
return this.xmllang;
}
/**
* Indicates whether the property is an array.
* @return true if the property is an array
*/
public boolean isArray() {
return value instanceof XMPArray;
}
/** @return the XMPArray for an array or null if the value is not an array. */
public XMPArray getArrayValue() {
return (isArray() ? (XMPArray)value : null);
}
/**
* Converts a simple value to an array of a given type if the value is not already an array.
* @param type the desired type of array
* @return the array value
*/
public XMPArray convertSimpleValueToArray(XMPArrayType type) {
if (getArrayValue() == null) {
XMPArray array = new XMPArray(type);
if (getXMLLang() != null) {
array.add(getValue().toString(), getXMLLang());
} else {
array.add(getValue());
}
setValue(array);
setXMLLang(null);
return array;
} else {
return getArrayValue();
}
}
/** @return the XMPStructure for a structure or null if the value is not a structure. */
public PropertyAccess getStructureValue() {
return (value instanceof XMPStructure ? (XMPStructure)value : null);
}
private boolean hasPropertyQualifiers() {
return (this.qualifiers == null) || (this.qualifiers.size() == 0);
}
/**
* Indicates whether this property is actually not a structure, but a normal property with
* property qualifiers. If this method returns true, this structure can be converted to
* an simple XMPProperty using the simplify() method.
* @return true if this property is a structure property with property qualifiers
*/
public boolean isQualifiedProperty() {
PropertyAccess props = getStructureValue();
if (props != null) {
XMPProperty rdfValue = props.getValueProperty();
return (rdfValue != null);
} else {
return hasPropertyQualifiers();
}
}
public void simplify() {
PropertyAccess props = getStructureValue();
if (props != null) {
XMPProperty rdfValue = props.getValueProperty();
if (rdfValue != null) {
if (hasPropertyQualifiers()) {
throw new IllegalStateException("Illegal internal state"
+ " (qualifiers present on non-simplified property)");
}
XMPProperty prop = new XMPProperty(getName(), rdfValue);
Iterator iter = props.iterator();
while (iter.hasNext()) {
QName name = (QName)iter.next();
if (!XMPConstants.RDF_VALUE.equals(name)) {
prop.setPropertyQualifier(name, props.getProperty(name));
}
}
props.setProperty(prop);
}
}
}
private void setPropertyQualifier(QName name, XMPProperty property) {
if (this.qualifiers == null) {
this.qualifiers = new java.util.HashMap();
}
this.qualifiers.put(name, property);
}
private String getEffectiveQName() {
String prefix = getName().getPrefix();
if (prefix == null || "".equals(prefix)) {
XMPSchema schema = XMPSchemaRegistry.getInstance().getSchema(getNamespace());
if (schema == null) {
return getName().getLocalName();
}
prefix = schema.getPreferredPrefix();
}
return prefix + ":" + getName().getLocalName();
}
/** @see org.apache.xmlgraphics.util.XMLizable#toSAX(org.xml.sax.ContentHandler) */
public void toSAX(ContentHandler handler) throws SAXException {
AttributesImpl atts = new AttributesImpl();
String qName = getEffectiveQName();
if (value instanceof URI) {
atts.addAttribute(XMPConstants.RDF_NAMESPACE, "resource", "rdf:resource", "CDATA", ((URI)value).toString());
}
handler.startElement(getName().getNamespaceURI(),
getName().getLocalName(), qName, atts);
if (value instanceof XMPComplexValue) {
XMPComplexValue cv = ((XMPComplexValue)value);
cv.toSAX(handler);
} else if (!(value instanceof URI)) {
char[] chars = value.toString().toCharArray();
handler.characters(chars, 0, chars.length);
}
handler.endElement(getName().getNamespaceURI(),
getName().getLocalName(), qName);
}
/** @see java.lang.Object#toString() */
public String toString() {
StringBuffer sb = new StringBuffer("XMP Property ");
sb.append(getName()).append(": ");
sb.append(getValue());
return sb.toString();
}
}