| /* |
| * 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.util.Stack; |
| |
| import org.apache.xmlgraphics.util.QName; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.helpers.AttributesImpl; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| /** |
| * Passive XMP parser implemented as a SAX DefaultHandler. After the XML document has been parsed |
| * the Metadata object can be retrieved. |
| */ |
| public class XMPHandler extends DefaultHandler { |
| |
| private Metadata meta; |
| |
| private StringBuffer content = new StringBuffer(); |
| //private Attributes lastAttributes; |
| private Stack attributesStack = new Stack(); |
| //private Stack contextStack = new Stack(); |
| |
| private QName currentPropertyName; |
| private XMPProperty currentProperty; |
| private XMPComplexValue currentComplexValue; |
| |
| /** @return the parsed metadata, available after the parsing. */ |
| public Metadata getMetadata() { |
| return this.meta; |
| } |
| |
| // --- Overrides --- |
| |
| /** |
| * @see org.xml.sax.helpers.DefaultHandler#startElement( |
| * java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) |
| */ |
| public void startElement(String uri, String localName, String qName, Attributes attributes) |
| throws SAXException { |
| super.startElement(uri, localName, qName, attributes); |
| content.setLength(0); //Reset text buffer (see characters()) |
| attributesStack.push(new AttributesImpl(attributes)); |
| |
| if (XMPConstants.XMP_NAMESPACE.equals(uri)) { |
| if (!"xmpmeta".equals(localName)) { |
| throw new SAXException("Expected x:xmpmeta element, not " + qName); |
| } |
| if (this.meta != null) { |
| throw new SAXException("Invalid XMP document. Root already received earlier."); |
| } |
| this.meta = new Metadata(); |
| } else if (XMPConstants.RDF_NAMESPACE.equals(uri)) { |
| if ("RDF".equals(localName)) { |
| if (this.meta == null) { |
| this.meta = new Metadata(); |
| } |
| } else if ("Description".equals(localName)) { |
| if (currentPropertyName == null) { |
| //rdf:RDF is the parent |
| String about = attributes.getValue(XMPConstants.RDF_NAMESPACE, "about"); |
| } else { |
| //a structured property is the parent |
| } |
| } else if ("Seq".equals(localName)) { |
| this.currentComplexValue = new XMPArray(XMPArrayType.SEQ); |
| } else if ("Bag".equals(localName)) { |
| this.currentComplexValue = new XMPArray(XMPArrayType.BAG); |
| } else if ("Alt".equals(localName)) { |
| this.currentComplexValue = new XMPArray(XMPArrayType.ALT); |
| } else if ("li".equals(localName)) { |
| } |
| } else { |
| this.currentPropertyName = new QName(uri, qName); |
| } |
| } |
| |
| /** |
| * @see org.xml.sax.helpers.DefaultHandler#endElement( |
| * java.lang.String, java.lang.String, java.lang.String) |
| */ |
| public void endElement(String uri, String localName, String qName) throws SAXException { |
| Attributes atts = (Attributes)attributesStack.pop(); |
| if (XMPConstants.XMP_NAMESPACE.equals(uri)) { |
| //nop |
| } else if (XMPConstants.RDF_NAMESPACE.equals(uri)) { |
| if ("li".equals(localName)) { |
| String s = content.toString().trim(); |
| if (s.length() > 0) { |
| getCurrentArray().add(s); |
| } |
| } else { |
| //nop |
| } |
| } else { |
| if (this.currentComplexValue != null) { |
| this.currentProperty = new XMPProperty(this.currentPropertyName, |
| this.currentComplexValue); |
| this.currentComplexValue = null; |
| } else { |
| String s = content.toString().trim(); |
| this.currentProperty = new XMPProperty(this.currentPropertyName, s); |
| String lang = atts.getValue(XMPConstants.XML_NS, "lang"); |
| if (lang != null) { |
| this.currentProperty.setXMLLang(lang); |
| } |
| } |
| this.meta.setProperty(this.currentProperty); |
| this.currentProperty = null; |
| this.currentPropertyName = null; |
| } |
| content.setLength(0); //Reset text buffer (see characters()) |
| super.endElement(uri, localName, qName); |
| } |
| |
| private XMPArray getCurrentArray() { |
| return (XMPArray)this.currentComplexValue; |
| } |
| |
| /** @see org.xml.sax.ContentHandler#characters(char[], int, int) */ |
| public void characters(char[] ch, int start, int length) throws SAXException { |
| content.append(ch, start, length); |
| } |
| |
| } |