001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: XMPHandler.java 426584 2006-07-28 16:01:47Z jeremias $ */
019:
020: package org.apache.xmlgraphics.xmp;
021:
022: import java.util.Stack;
023:
024: import org.apache.xmlgraphics.util.QName;
025: import org.xml.sax.Attributes;
026: import org.xml.sax.SAXException;
027: import org.xml.sax.helpers.AttributesImpl;
028: import org.xml.sax.helpers.DefaultHandler;
029:
030: /**
031: * Passive XMP parser implemented as a SAX DefaultHandler. After the XML document has been parsed
032: * the Metadata object can be retrieved.
033: */
034: public class XMPHandler extends DefaultHandler {
035:
036: private Metadata meta;
037:
038: private StringBuffer content = new StringBuffer();
039: //private Attributes lastAttributes;
040: private Stack attributesStack = new Stack();
041: //private Stack contextStack = new Stack();
042:
043: private QName currentPropertyName;
044: private XMPProperty currentProperty;
045: private XMPComplexValue currentComplexValue;
046:
047: /** @return the parsed metadata, available after the parsing. */
048: public Metadata getMetadata() {
049: return this .meta;
050: }
051:
052: // --- Overrides ---
053:
054: /**
055: * @see org.xml.sax.helpers.DefaultHandler#startElement(
056: * java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
057: */
058: public void startElement(String uri, String localName,
059: String qName, Attributes attributes) throws SAXException {
060: super .startElement(uri, localName, qName, attributes);
061: content.setLength(0); //Reset text buffer (see characters())
062: attributesStack.push(new AttributesImpl(attributes));
063:
064: if (XMPConstants.XMP_NAMESPACE.equals(uri)) {
065: if (!"xmpmeta".equals(localName)) {
066: throw new SAXException(
067: "Expected x:xmpmeta element, not " + qName);
068: }
069: if (this .meta != null) {
070: throw new SAXException(
071: "Invalid XMP document. Root already received earlier.");
072: }
073: this .meta = new Metadata();
074: } else if (XMPConstants.RDF_NAMESPACE.equals(uri)) {
075: if ("RDF".equals(localName)) {
076: if (this .meta == null) {
077: this .meta = new Metadata();
078: }
079: } else if ("Description".equals(localName)) {
080: if (currentPropertyName == null) {
081: //rdf:RDF is the parent
082: String about = attributes.getValue(
083: XMPConstants.RDF_NAMESPACE, "about");
084: } else {
085: //a structured property is the parent
086: }
087: } else if ("Seq".equals(localName)) {
088: this .currentComplexValue = new XMPArray(
089: XMPArrayType.SEQ);
090: } else if ("Bag".equals(localName)) {
091: this .currentComplexValue = new XMPArray(
092: XMPArrayType.BAG);
093: } else if ("Alt".equals(localName)) {
094: this .currentComplexValue = new XMPArray(
095: XMPArrayType.ALT);
096: } else if ("li".equals(localName)) {
097: }
098: } else {
099: this .currentPropertyName = new QName(uri, qName);
100: }
101: }
102:
103: /**
104: * @see org.xml.sax.helpers.DefaultHandler#endElement(
105: * java.lang.String, java.lang.String, java.lang.String)
106: */
107: public void endElement(String uri, String localName, String qName)
108: throws SAXException {
109: Attributes atts = (Attributes) attributesStack.pop();
110: if (XMPConstants.XMP_NAMESPACE.equals(uri)) {
111: //nop
112: } else if (XMPConstants.RDF_NAMESPACE.equals(uri)) {
113: if ("li".equals(localName)) {
114: String s = content.toString().trim();
115: if (s.length() > 0) {
116: getCurrentArray().add(s);
117: }
118: } else {
119: //nop
120: }
121: } else {
122: if (this .currentComplexValue != null) {
123: this .currentProperty = new XMPProperty(
124: this .currentPropertyName,
125: this .currentComplexValue);
126: this .currentComplexValue = null;
127: } else {
128: String s = content.toString().trim();
129: this .currentProperty = new XMPProperty(
130: this .currentPropertyName, s);
131: String lang = atts
132: .getValue(XMPConstants.XML_NS, "lang");
133: if (lang != null) {
134: this .currentProperty.setXMLLang(lang);
135: }
136: }
137: this .meta.setProperty(this .currentProperty);
138: this .currentProperty = null;
139: this .currentPropertyName = null;
140: }
141: content.setLength(0); //Reset text buffer (see characters())
142: super .endElement(uri, localName, qName);
143: }
144:
145: private XMPArray getCurrentArray() {
146: return (XMPArray) this .currentComplexValue;
147: }
148:
149: /** @see org.xml.sax.ContentHandler#characters(char[], int, int) */
150: public void characters(char[] ch, int start, int length)
151: throws SAXException {
152: content.append(ch, start, length);
153: }
154:
155: }
|