blob: e10e762b196bf762e70829424bcbc8d5f25c6846 [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.
*/
package org.apache.felix.ipojo.xml.parser;
import org.apache.felix.ipojo.metadata.Attribute;
import org.apache.felix.ipojo.metadata.Element;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
/**
* XML Metadata parser.
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class XMLMetadataParser implements ContentHandler {
/**
* Element of the metadata.
*/
private Element[] m_elements = new Element[0];
/**
* Get parsed metadata.
* The document must be parsed before calling this method.
* @return : all the metadata.
* @throws ParseException : occurs if an error occurs during the parsing.
*/
public Element[] getMetadata() throws ParseException {
return m_elements[0].getElements();
}
/**
* Characters.
* @param ch : character
* @param start : start
* @param length : length
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length) throws SAXException {
// NOTHING TO DO
}
/**
* End the document.
* @throws SAXException : can never occrus.
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument() throws SAXException {
}
/**
* End of an element.
* @param namespaceURI : element namespace
* @param localName : local name
* @param qName : qualified name
* @throws SAXException : occurs when the element is malformed
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
// Get the last element of the list
Element lastElement = removeLastElement();
// Check if the name is consistent with the name of this end tag
if (!lastElement.getName().equalsIgnoreCase(qName) && !lastElement.getNameSpace().equalsIgnoreCase(namespaceURI)) {
throw new SAXException("Parse error when ending an element : " + qName + " [" + namespaceURI + "]");
}
// The name is consistent
// Add this element last element with if it is not the root
if (m_elements.length != 0) {
Element newQueue = m_elements[m_elements.length - 1];
newQueue.addElement(lastElement);
} else {
// It is the last element
addElement(lastElement);
}
}
/**
* End prefix mapping.
* @param prefix : ended prefix
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix) throws SAXException {
// NOTHING TO DO
}
/**
* Ignore whitespace.
* @param ch : character
* @param start : start
* @param length : length
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
// NOTHING TO DO
}
/**
* Process an instruction.
* @param target : target
* @param data : data
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
public void processingInstruction(String target, String data) throws SAXException {
// DO NOTHING
}
/**
* Set Document locator.
* @param locator : new locator.
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator) {
// NOTHING TO DO
}
/**
* Skipped entity.
* @param name : name.
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name) throws SAXException {
// NOTHING TO DO
}
/**
* Start a document.
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument() throws SAXException {
}
/**
* Start an element.
* @param namespaceURI : element namespace.
* @param localName : local element.
* @param qName : qualified name.
* @param atts : attribute
* @throws SAXException : occurs if the element cannot be parsed correctly.
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
Element elem = new Element(localName, namespaceURI);
for (int i = 0; i < atts.getLength(); i++) {
String name = (String) atts.getLocalName(i);
String ns = (String) atts.getURI(i);
String value = (String) atts.getValue(i);
Attribute att = new Attribute(name, ns, value);
elem.addAttribute(att);
}
addElement(elem);
}
/**
* Start a prefix mapping.
* @param prefix : prefix.
* @param uri : uri.
* @throws SAXException : can never occurs.
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri) throws SAXException {
// NOTHING TO DO
}
/**
* Add an element.
* @param elem : the element to add
*/
private void addElement(Element elem) {
for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
if (m_elements[i] == elem) {
return;
}
}
if (m_elements != null) {
Element[] newElementsList = new Element[m_elements.length + 1];
System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
newElementsList[m_elements.length] = elem;
m_elements = newElementsList;
} else {
m_elements = new Element[] { elem };
}
}
/**
* Remove an element.
* @return : the removed element.
*/
private Element removeLastElement() {
int idx = -1;
idx = m_elements.length - 1;
Element last = m_elements[idx];
if (idx >= 0) {
if ((m_elements.length - 1) == 0) {
// It is the last element of the list;
m_elements = new Element[0];
} else {
// Remove the last element of the list :
Element[] newElementsList = new Element[m_elements.length - 1];
System.arraycopy(m_elements, 0, newElementsList, 0, idx);
m_elements = newElementsList;
}
}
return last;
}
}