1/*
2 * Copyright (C) 2007 Esmertec AG.
3 * Copyright (C) 2007 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mms.dom;
19
20import java.util.NoSuchElementException;
21import java.util.Vector;
22
23import org.w3c.dom.DOMException;
24import org.w3c.dom.Document;
25import org.w3c.dom.NamedNodeMap;
26import org.w3c.dom.Node;
27import org.w3c.dom.NodeList;
28import org.w3c.dom.UserDataHandler;
29import org.w3c.dom.events.Event;
30import org.w3c.dom.events.EventException;
31import org.w3c.dom.events.EventListener;
32import org.w3c.dom.events.EventTarget;
33
34import com.android.mms.dom.events.EventTargetImpl;
35
36public abstract class NodeImpl implements Node, EventTarget {
37    private Node mParentNode;
38    private final Vector<Node> mChildNodes = new Vector<Node>();
39    DocumentImpl mOwnerDocument;
40    private final EventTarget mEventTarget = new EventTargetImpl(this);
41
42    /*
43     * Internal methods
44     */
45
46    protected NodeImpl(DocumentImpl owner) {
47        mOwnerDocument = owner;
48    }
49
50    /*
51     * Node Interface Methods
52     */
53
54    public Node appendChild(Node newChild) throws DOMException {
55        ((NodeImpl)newChild).setParentNode(this);
56        mChildNodes.remove(newChild);
57        mChildNodes.add(newChild);
58        return newChild;
59    }
60
61    public Node cloneNode(boolean deep) {
62        // TODO Auto-generated method stub
63        return null;
64    }
65
66    public NamedNodeMap getAttributes() {
67        // Default. Override in Element.
68        return null;
69    }
70
71    public NodeList getChildNodes() {
72        return new NodeListImpl(this, null, false);
73    }
74
75    public Node getFirstChild() {
76        Node firstChild = null;
77        try {
78            firstChild = mChildNodes.firstElement();
79        }
80        catch (NoSuchElementException e) {
81            // Ignore and return null
82        }
83        return firstChild;
84    }
85
86    public Node getLastChild() {
87        Node lastChild = null;
88        try {
89            lastChild = mChildNodes.lastElement();
90        }
91        catch (NoSuchElementException e) {
92            // Ignore and return null
93        }
94        return lastChild;
95    }
96
97    public String getLocalName() {
98        // TODO Auto-generated method stub
99        return null;
100    }
101
102    public String getNamespaceURI() {
103        // TODO Auto-generated method stub
104        return null;
105    }
106
107    public Node getNextSibling() {
108        if ((mParentNode != null) && (this != mParentNode.getLastChild())) {
109            Vector<Node> siblings = ((NodeImpl)mParentNode).mChildNodes;
110            int indexOfThis = siblings.indexOf(this);
111            return siblings.elementAt(indexOfThis + 1);
112        }
113        return null;
114    }
115
116    public abstract String getNodeName();
117
118    public abstract short getNodeType();
119
120    public String getNodeValue() throws DOMException {
121        // Default behaviour. Override if required.
122        return null;
123    }
124
125    public Document getOwnerDocument() {
126        return mOwnerDocument;
127    }
128
129    public Node getParentNode() {
130        return mParentNode;
131    }
132
133    public String getPrefix() {
134        // TODO Auto-generated method stub
135        return null;
136    }
137
138    public Node getPreviousSibling() {
139        if ((mParentNode != null) && (this != mParentNode.getFirstChild())) {
140            Vector<Node> siblings = ((NodeImpl)mParentNode).mChildNodes;
141            int indexOfThis = siblings.indexOf(this);
142            return siblings.elementAt(indexOfThis - 1);
143        }
144        return null;
145    }
146
147    public boolean hasAttributes() {
148        // Default. Override in Element.
149        return false;
150    }
151
152    public boolean hasChildNodes() {
153        return !(mChildNodes.isEmpty());
154    }
155
156    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
157        // TODO Auto-generated method stub
158        return null;
159    }
160
161    public boolean isSupported(String feature, String version) {
162        // TODO Auto-generated method stub
163        return false;
164    }
165
166    public void normalize() {
167        // TODO Auto-generated method stub
168    }
169
170    public Node removeChild(Node oldChild) throws DOMException {
171        if (mChildNodes.contains(oldChild)) {
172            mChildNodes.remove(oldChild);
173            ((NodeImpl)oldChild).setParentNode(null);
174        } else {
175            throw new DOMException(DOMException.NOT_FOUND_ERR, "Child does not exist");
176        }
177        return null;
178    }
179
180    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
181        if (mChildNodes.contains(oldChild)) {
182            // Try to remove the new child if available
183            try {
184                mChildNodes.remove(newChild);
185            } catch (DOMException e) {
186                // Ignore exception
187            }
188            mChildNodes.setElementAt(newChild, mChildNodes.indexOf(oldChild));
189            ((NodeImpl)newChild).setParentNode(this);
190            ((NodeImpl)oldChild).setParentNode(null);
191        } else {
192            throw new DOMException(DOMException.NOT_FOUND_ERR, "Old child does not exist");
193        }
194        return oldChild;
195    }
196
197    public void setNodeValue(String nodeValue) throws DOMException {
198        // Default behaviour. Override if required.
199    }
200
201    public void setPrefix(String prefix) throws DOMException {
202        // TODO Auto-generated method stub
203    }
204
205    private void setParentNode(Node parentNode) {
206        mParentNode = parentNode;
207    }
208
209    /*
210     * EventTarget Interface
211     */
212
213    public void addEventListener(String type, EventListener listener, boolean useCapture) {
214        mEventTarget.addEventListener(type, listener, useCapture);
215    }
216
217    public void removeEventListener(String type, EventListener listener, boolean useCapture) {
218        mEventTarget.removeEventListener(type, listener, useCapture);
219    }
220
221    public boolean dispatchEvent(Event evt) throws EventException {
222        return mEventTarget.dispatchEvent(evt);
223    }
224
225    public String getBaseURI() {
226        return null;
227    }
228
229    public short compareDocumentPosition(Node other) throws DOMException {
230        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
231    }
232
233    public String getTextContent() throws DOMException {
234        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
235    }
236
237    public void setTextContent(String textContent) throws DOMException {
238        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
239    }
240
241    public boolean isSameNode(Node other) {
242        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
243    }
244
245    public String lookupPrefix(String namespaceURI) {
246        return null;
247    }
248
249    public boolean isDefaultNamespace(String namespaceURI) {
250        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
251    }
252
253    public String lookupNamespaceURI(String prefix) {
254        return null;
255    }
256
257    public boolean isEqualNode(Node arg) {
258        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
259    }
260
261    public Object getFeature(String feature, String version) {
262        return null;
263    }
264
265    public Object setUserData(String key, Object data,
266            UserDataHandler handler) {
267        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, null);
268    }
269
270    public Object getUserData(String key) {
271        return null;
272    }
273}
274