blob: ba2ac5b4c319dfb11da942aa41f088dfd0b48c6d [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.metadata;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* An element represents an XML Element.
* It contains a name, a namepace, {@link Attribute} objects
* and sub-elements. This class is used to parse iPOJO metadata.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class Element {
/**
* The name of the element.
*/
private String m_name;
/**
* The namespace of the element.
*/
private String m_nameSpace;
/**
* The map of attributes of the element (attribute name -> {@link Attribute}).
* The map key is the qualified name of the attribute (<code>ns:name</code>)
* The value is the attribute object.
*/
private Map m_attributes = new HashMap();
/**
* The map of the sub-element of the element (element name -> {@link Element}.
* The map key is the element qualified name (ns:name).
* The value is the array of element of this name.
*/
private Map m_elements = new HashMap();
/**
* Creates an Element.
* @param name the name of the element
* @param ns the namespace of the element
*/
public Element(String name, String ns) {
m_name = name.toLowerCase();
if (ns != null && ns.length() > 0) {
m_nameSpace = ns.toLowerCase();
}
}
/**
* Gets sub-elements.
* If no sub-elements, an empty array is returned.
* @return the sub elements
*/
public Element[] getElements() {
Collection col = m_elements.values();
Iterator it = col.iterator();
List list = new ArrayList();
while (it.hasNext()) {
Element[] v = (Element[]) it.next();
for (int i = 0; i < v.length; i++) {
list.add(v[i]);
}
}
return (Element[]) list.toArray(new Element[list.size()]);
}
/**
* Gets element attributes.
* If no attributes, an empty array is returned.
* @return the attributes
*/
public Attribute[] getAttributes() {
return (Attribute[]) m_attributes.values().toArray(new Attribute[0]);
}
/**
* Gets element name.
* @return the name of the element
*/
public String getName() {
return m_name;
}
/**
* Gets element namespace.
* @return the namespace of the element
*/
public String getNameSpace() {
return m_nameSpace;
}
/**
* Returns the value of the attribute given in parameter.
* @param name the name of the searched attribute
* @return the value of the attribute given in parameter,
* <code>null</code> if the attribute does not exist
*/
public String getAttribute(String name) {
name = name.toLowerCase();
Attribute att = (Attribute) m_attributes.get(name);
if (att == null) {
return null;
} else {
return att.getValue();
}
}
/**
* Returns the value of the attribute "name" of the namespace "ns".
* @param name the name of the attribute to find
* @param ns the namespace of the attribute to find
* @return the String value of the attribute, or
* <code>null</code> if the attribute is not found.
*/
public String getAttribute(String name, String ns) {
name = ns.toLowerCase() + ":" + name.toLowerCase();
return getAttribute(name);
}
/**
* Gets the qualified name of the current element.
* @return the qualified name of the current element.
*/
private String getQualifiedName() {
if (m_nameSpace == null) {
return m_name;
} else {
return m_nameSpace + ":" + m_name;
}
}
/**
* Adds a sub-element.
* @param elem the element to add
*/
public void addElement(Element elem) {
Element[] array = (Element[]) m_elements.get(elem.getQualifiedName());
if (array == null) {
m_elements.put(elem.getQualifiedName(), new Element[] {elem});
} else {
Element[] newElementsList = new Element[array.length + 1];
System.arraycopy(array, 0, newElementsList, 0, array.length);
newElementsList[array.length] = elem;
m_elements.put(elem.getQualifiedName(), newElementsList);
}
}
/**
* Removes a sub-element.
* @param elem the element to remove
*/
public void removeElement(Element elem) {
Element[] array = (Element[]) m_elements.get(elem.getQualifiedName());
if (array == null) {
return;
} else {
int idx = -1;
for (int i = 0; i < array.length; i++) {
if (array[i] == elem) {
idx = i;
break;
}
}
if (idx >= 0) {
if ((array.length - 1) == 0) {
m_elements.remove(elem.getQualifiedName());
} else {
Element[] newElementsList = new Element[array.length - 1];
System.arraycopy(array, 0, newElementsList, 0, idx);
if (idx < newElementsList.length) {
System.arraycopy(array, idx + 1, newElementsList, idx, newElementsList.length - idx);
}
m_elements.put(elem.getQualifiedName(), newElementsList); // Update the stored list.
}
}
}
}
/**
* Adds a attribute.
* @param att the attribute to add
*/
public void addAttribute(Attribute att) {
String name = att.getName().toLowerCase();
if (att.getNameSpace() != null) {
name = att.getNameSpace().toLowerCase() + ":" + name;
}
m_attributes.put(name, att);
}
/**
* Removes an attribute.
* @param att the attribute to remove
*/
public void removeAttribute(Attribute att) {
String name = att.getName();
if (att.getNameSpace() != null) {
name = att.getNameSpace() + ":" + name;
}
m_attributes.remove(name);
}
/**
* Gets the elements array of the element type given in parameter.
* This method looks for an empty namespace.
* @param name the type of the element to find (element name)
* @return the resulting element array (<code>null</code> if the search failed)
*/
public Element[] getElements(String name) {
Element[] elems = (Element[]) m_elements.get(name.toLowerCase());
return elems;
}
/**
* Gets the elements array of the element type given in parameter.
* @param name the type of the element to find (element name)
* @param ns the namespace of the element
* @return the resulting element array (<code>null</code> if the search failed)
*/
public Element[] getElements(String name, String ns) {
if (ns == null || ns.length() == 0) {
return getElements(name);
}
name = ns + ":" + name;
return getElements(name);
}
/**
* Does the element contain a sub-element of the type given in parameter.
* @param name the type of the element to check.
* @return <code>true</code> if the element contains an element of the type "name"
*/
public boolean containsElement(String name) {
return m_elements.containsKey(name.toLowerCase());
}
/**
* Does the element contain a sub-element of the type given in parameter.
* @param name the type of the element to check.
* @param ns the namespace of the element to check.
* @return <code>true</code> if the element contains an element of the type "name"
*/
public boolean containsElement(String name, String ns) {
if (ns != null && ns.length() != 0) {
name = ns + ":" + name;
}
return containsElement(name);
}
/**
* Does the element contain an attribute of the name given in parameter.
* @param name the name of the element
* @return <code>true</code> if the element contains an attribute of the type "name"
*/
public boolean containsAttribute(String name) {
return m_attributes.containsKey(name.toLowerCase());
}
/**
* Gets the XML form of this element.
* @return the XML snippet representing this element.
*/
public String toXMLString() {
return toXMLString(0);
}
/**
* Internal method to get XML form of an element.
* @param indent the indentation to used.
* @return the XML snippet representing this element.
*/
private String toXMLString(int indent) {
StringBuffer xml = new StringBuffer();
StringBuffer tabs = new StringBuffer();
for (int j = 0; j < indent; j++) {
tabs.append("\t");
}
xml.append(tabs);
if (m_nameSpace == null) {
xml.append("<" + m_name);
} else {
xml.append("<" + m_nameSpace + ":" + m_name);
}
Set keys = m_attributes.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
Attribute current = (Attribute) m_attributes.get(it.next());
if (current.getNameSpace() == null) {
xml.append(" " + current.getName() + "=\"" + current.getValue() + "\"");
} else {
xml.append(" " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"");
}
}
if (m_elements.size() == 0) {
xml.append("/>");
return xml.toString();
} else {
xml.append(">");
keys = m_elements.keySet();
it = keys.iterator();
while (it.hasNext()) {
Element[] e = (Element[]) m_elements.get(it.next());
for (int i = 0; i < e.length; i++) {
xml.append("\n");
xml.append(e[i].toXMLString(indent + 1));
}
}
xml.append("\n" + tabs + "</" + m_name + ">");
return xml.toString();
}
}
/**
* To String method.
* @return the String form of this element.
* @see java.lang.Object#toString()
*/
public String toString() {
return toString(0);
}
/**
* Internal method to compute the toString method.
* @param indent the indentation to use.
* @return the String form of this element.
*/
private String toString(int indent) {
StringBuffer xml = new StringBuffer();
StringBuffer tabs = new StringBuffer();
for (int j = 0; j < indent; j++) {
tabs.append("\t");
}
xml.append(tabs);
if (m_nameSpace == null) {
xml.append(m_name);
} else {
xml.append(m_nameSpace + ":" + m_name);
}
Set keys = m_attributes.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
Attribute current = (Attribute) m_attributes.get(it.next());
if (current.getNameSpace() == null) {
xml.append(" " + current.getName() + "=\"" + current.getValue() + "\"");
} else {
xml.append(" " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"");
}
}
if (m_elements.size() == 0) {
return xml.toString();
} else {
keys = m_elements.keySet();
it = keys.iterator();
while (it.hasNext()) {
Element[] e = (Element[]) m_elements.get(it.next());
for (int i = 0; i < e.length; i++) {
xml.append("\n");
xml.append(e[i].toString(indent + 1));
}
}
return xml.toString();
}
}
}