| /* |
| * 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(); |
| } |
| |
| } |