summaryrefslogtreecommitdiffstats
path: root/sax/java/android/sax/Element.java
diff options
context:
space:
mode:
Diffstat (limited to 'sax/java/android/sax/Element.java')
-rw-r--r--sax/java/android/sax/Element.java204
1 files changed, 204 insertions, 0 deletions
diff --git a/sax/java/android/sax/Element.java b/sax/java/android/sax/Element.java
new file mode 100644
index 0000000..8c8334c
--- /dev/null
+++ b/sax/java/android/sax/Element.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * 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 android.sax;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+
+import java.util.ArrayList;
+
+import android.util.Log;
+
+/**
+ * An XML element. Provides access to child elements and hooks to listen
+ * for events related to this element.
+ *
+ * @see RootElement
+ */
+public class Element {
+
+ final String uri;
+ final String localName;
+ final int depth;
+ final Element parent;
+
+ Children children;
+ ArrayList<Element> requiredChilden;
+
+ boolean visited;
+
+ StartElementListener startElementListener;
+ EndElementListener endElementListener;
+ EndTextElementListener endTextElementListener;
+
+ Element(Element parent, String uri, String localName, int depth) {
+ this.parent = parent;
+ this.uri = uri;
+ this.localName = localName;
+ this.depth = depth;
+ }
+
+ /**
+ * Gets the child element with the given name. Uses an empty string as the
+ * namespace.
+ */
+ public Element getChild(String localName) {
+ return getChild("", localName);
+ }
+
+ /**
+ * Gets the child element with the given name.
+ */
+ public Element getChild(String uri, String localName) {
+ if (endTextElementListener != null) {
+ throw new IllegalStateException("This element already has an end"
+ + " text element listener. It cannot have children.");
+ }
+
+ if (children == null) {
+ children = new Children();
+ }
+
+ return children.getOrCreate(this, uri, localName);
+ }
+
+ /**
+ * Gets the child element with the given name. Uses an empty string as the
+ * namespace. We will throw a {@link org.xml.sax.SAXException} at parsing
+ * time if the specified child is missing. This helps you ensure that your
+ * listeners are called.
+ */
+ public Element requireChild(String localName) {
+ return requireChild("", localName);
+ }
+
+ /**
+ * Gets the child element with the given name. We will throw a
+ * {@link org.xml.sax.SAXException} at parsing time if the specified child
+ * is missing. This helps you ensure that your listeners are called.
+ */
+ public Element requireChild(String uri, String localName) {
+ Element child = getChild(uri, localName);
+
+ if (requiredChilden == null) {
+ requiredChilden = new ArrayList<Element>();
+ requiredChilden.add(child);
+ } else {
+ if (!requiredChilden.contains(child)) {
+ requiredChilden.add(child);
+ }
+ }
+
+ return child;
+ }
+
+ /**
+ * Sets start and end element listeners at the same time.
+ */
+ public void setElementListener(ElementListener elementListener) {
+ setStartElementListener(elementListener);
+ setEndElementListener(elementListener);
+ }
+
+ /**
+ * Sets start and end text element listeners at the same time.
+ */
+ public void setTextElementListener(TextElementListener elementListener) {
+ setStartElementListener(elementListener);
+ setEndTextElementListener(elementListener);
+ }
+
+ /**
+ * Sets a listener for the start of this element.
+ */
+ public void setStartElementListener(
+ StartElementListener startElementListener) {
+ if (this.startElementListener != null) {
+ throw new IllegalStateException(
+ "Start element listener has already been set.");
+ }
+ this.startElementListener = startElementListener;
+ }
+
+ /**
+ * Sets a listener for the end of this element.
+ */
+ public void setEndElementListener(EndElementListener endElementListener) {
+ if (this.endElementListener != null) {
+ throw new IllegalStateException(
+ "End element listener has already been set.");
+ }
+ this.endElementListener = endElementListener;
+ }
+
+ /**
+ * Sets a listener for the end of this text element.
+ */
+ public void setEndTextElementListener(
+ EndTextElementListener endTextElementListener) {
+ if (this.endTextElementListener != null) {
+ throw new IllegalStateException(
+ "End text element listener has already been set.");
+ }
+
+ if (children != null) {
+ throw new IllegalStateException("This element already has children."
+ + " It cannot have an end text element listener.");
+ }
+
+ this.endTextElementListener = endTextElementListener;
+ }
+
+ @Override
+ public String toString() {
+ return toString(uri, localName);
+ }
+
+ static String toString(String uri, String localName) {
+ return "'" + (uri.equals("") ? localName : uri + ":" + localName) + "'";
+ }
+
+ /**
+ * Clears flags on required children.
+ */
+ void resetRequiredChildren() {
+ ArrayList<Element> requiredChildren = this.requiredChilden;
+ if (requiredChildren != null) {
+ for (int i = requiredChildren.size() - 1; i >= 0; i--) {
+ requiredChildren.get(i).visited = false;
+ }
+ }
+ }
+
+ /**
+ * Throws an exception if a required child was not present.
+ */
+ void checkRequiredChildren(Locator locator) throws SAXParseException {
+ ArrayList<Element> requiredChildren = this.requiredChilden;
+ if (requiredChildren != null) {
+ for (int i = requiredChildren.size() - 1; i >= 0; i--) {
+ Element child = requiredChildren.get(i);
+ if (!child.visited) {
+ throw new BadXmlException(
+ "Element named " + this + " is missing required"
+ + " child element named "
+ + child + ".", locator);
+ }
+ }
+ }
+ }
+}