/* Licensed 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.activiti.engine.impl.util.xml; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.activiti.engine.ActivitiException; import org.xml.sax.Attributes; import org.xml.sax.Locator; /** * Represents one XML element. * * @author Tom Baeyens * @author Joram Barrez */ public class Element { protected String uri; protected String tagName; /* * Key of map = 'uri':attributeName * * if namespace is empty, key is 'attributeName' */ protected Map<String, Attribute> attributeMap = new HashMap<String, Attribute>(); protected int line; protected int column; protected StringBuilder text = new StringBuilder(); protected List<Element> elements = new ArrayList<Element>(); public Element(String uri, String localName, String qName, Attributes attributes, Locator locator) { this.uri = uri; this.tagName = (uri == null || uri.equals("")) ? qName : localName; if (attributes!=null) { for (int i=0; i<attributes.getLength(); i++) { String attributeUri = attributes.getURI(i); String name = (attributeUri == null || attributeUri.equals("")) ? attributes.getQName(i) : attributes.getLocalName(i); String value = attributes.getValue(i); this.attributeMap.put(composeMapKey(attributeUri, name), new Attribute(name, value, attributeUri)); } } if (locator!=null) { line = locator.getLineNumber(); column = locator.getColumnNumber(); } } public List<Element> elements(String tagName) { return elementsNS(null, tagName); } public List<Element> elementsNS(String nameSpaceUri, String tagName) { List<Element> selectedElements = new ArrayList<Element>(); for (Element element: elements) { if (tagName.equals(element.getTagName())) { if (nameSpaceUri == null || ( nameSpaceUri != null && nameSpaceUri.equals(element.getUri()) ) ) { selectedElements.add(element); } } } return selectedElements; } public Element element(String tagName) { return elementNS(null, tagName); } public Element elementNS(String nameSpaceUri, String tagName) { List<Element> elements = elementsNS(nameSpaceUri, tagName); if (elements.size() == 0) { return null; } else if (elements.size() > 1) { throw new ActivitiException("Parsing exception: multiple elements with tag name " + tagName + " found"); } return elements.get(0); } public void add(Element element) { elements.add(element); } public String attribute(String name) { if (attributeMap.containsKey(name)) { return attributeMap.get(name).getValue(); } return null; } public Set<String> attributes() { return attributeMap.keySet(); } public String attributeNS(String namespaceUri, String name) { return attribute(composeMapKey(namespaceUri, name)); } public String attribute(String name, String defaultValue) { if (attributeMap.containsKey(name)) { return attributeMap.get(name).getValue(); } return defaultValue; } public String attributeNS(String namespaceUri, String name, String defaultValue) { return attribute(composeMapKey(namespaceUri, name), defaultValue); } protected String composeMapKey(String attributeUri, String attributeName) { StringBuilder strb = new StringBuilder(); if (attributeUri != null && !attributeUri.equals("")) { strb.append(attributeUri); strb.append(":"); } strb.append(attributeName); return strb.toString(); } public List<Element> elements() { return elements; } public String toString() { return "<"+tagName+"..."; } public String getUri() { return uri; } public String getTagName() { return tagName; } public int getLine() { return line; } public int getColumn() { return column; } /** * Due to the nature of SAX parsing, sometimes the characters of an element * are not processed at once. So instead of a setText operation, we need * to have an appendText operation. */ public void appendText(String text) { this.text.append(text); } public String getText() { return text.toString(); } /** * allows to recursively collect the ids of all elements in the tree. */ public void collectIds(List<String> ids) { ids.add(attribute("id")); for (Element child : elements) { child.collectIds(ids); } } }