001 /*
002 * Copyright 2002 - 2007 JEuclid, http://jeuclid.sf.net
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 /* $Id: AbstractPartialNodeImpl.java 363 2007-06-29 16:24:32Z maxberger $ */
018
019 package net.sourceforge.jeuclid.dom;
020
021 import java.util.List;
022 import java.util.Vector;
023
024 import org.w3c.dom.DOMException;
025 import org.w3c.dom.Document;
026 import org.w3c.dom.NamedNodeMap;
027 import org.w3c.dom.Node;
028 import org.w3c.dom.UserDataHandler;
029
030 /**
031 * Partial implementation of org.w3c.dom.Node
032 * <p>
033 * This implements only the functions necessary for MathElements. Feel free to
034 * implement whatever functions you need.
035 *
036 * @author Max Berger
037 * @version $Revision: 363 $
038 */
039 public abstract class AbstractPartialNodeImpl implements Node {
040
041 private static final String COULD_NOT_FIND_NODE = "Could not find node: ";
042
043 private final List<Node> children = new Vector<Node>();
044
045 private Node parent;
046
047 /**
048 * @see org.w3c.dom.NodeList
049 */
050 public static class NodeList implements org.w3c.dom.NodeList {
051 private final List<Node> children;
052
053 /**
054 * default constructor.
055 *
056 * @param childs
057 * list of children.
058 */
059 protected NodeList(final List<Node> childs) {
060 this.children = childs;
061 }
062
063 /** {@inheritDoc} */
064 public final int getLength() {
065 return this.children.size();
066 }
067
068 /** {@inheritDoc} */
069 public final Node item(final int index) {
070 return this.children.get(index);
071 }
072 }
073
074 /** {@inheritDoc} */
075 public final String lookupNamespaceURI(final String prefix) {
076 throw new UnsupportedOperationException("lookupNamespaceURI");
077 }
078
079 /** {@inheritDoc} */
080 public final void normalize() {
081 throw new UnsupportedOperationException("normalize");
082 }
083
084 /** {@inheritDoc} */
085 public final org.w3c.dom.NodeList getChildNodes() {
086 return new NodeList(this.children);
087 }
088
089 /** {@inheritDoc} */
090 public final Node getFirstChild() {
091 try {
092 return this.children.get(0);
093 } catch (final IndexOutOfBoundsException e) {
094 return null;
095 }
096 }
097
098 /** {@inheritDoc} */
099 public final boolean isSameNode(final Node other) {
100 return this.equals(other);
101 }
102
103 /** {@inheritDoc} */
104 public Node appendChild(final Node newChild) {
105 if (newChild instanceof AbstractPartialNodeImpl) {
106 this.children.add(newChild);
107 ((AbstractPartialNodeImpl) newChild).parent = this;
108 return newChild;
109 } else {
110 throw new IllegalArgumentException(
111 "Can only add children of type "
112 + AbstractPartialNodeImpl.class.getName()
113 + " to " + this.getClass().getName());
114 }
115 }
116
117 /** {@inheritDoc} */
118 public String getTextContent() {
119 final StringBuilder builder = new StringBuilder();
120 for (final Node n : this.children) {
121 builder.append(n.getTextContent());
122 }
123 return builder.toString();
124 }
125
126 /** {@inheritDoc} */
127 public void setTextContent(final String newTextContent) {
128 this.children.clear();
129 if (newTextContent != null && newTextContent.length() > 0) {
130 this.children.add(new PartialTextImpl(newTextContent));
131 }
132 }
133
134 /** {@inheritDoc} */
135 public final Node cloneNode(final boolean deep) {
136 throw new UnsupportedOperationException("cloneNode");
137 }
138
139 /** {@inheritDoc} */
140 public String getNodeValue() {
141 return null;
142 }
143
144 /** {@inheritDoc} */
145 public final String getNamespaceURI() {
146 return null;
147 }
148
149 /** {@inheritDoc} */
150 public final Node getParentNode() {
151 return this.parent;
152 }
153
154 /** {@inheritDoc} */
155 public final String getBaseURI() {
156 throw new UnsupportedOperationException("getBaseURI");
157 }
158
159 /** {@inheritDoc} */
160 public final String getPrefix() {
161 throw new UnsupportedOperationException("getPrefix");
162 }
163
164 /** {@inheritDoc} */
165 public NamedNodeMap getAttributes() {
166 return null;
167 }
168
169 /** {@inheritDoc} */
170 public final boolean hasChildNodes() {
171 return !this.children.isEmpty();
172 }
173
174 /** {@inheritDoc} */
175 public final boolean isDefaultNamespace(final String namespaceURI) {
176 throw new UnsupportedOperationException("isDefaultNamespace");
177 }
178
179 /** {@inheritDoc} */
180 public Node replaceChild(final Node newChild, final Node oldChild) {
181 // TODO: If newChild is already in the tree, it is supposed to be
182 // removed.
183 for (int i = 0; i < this.children.size(); i++) {
184 final Node oldChildAtIndex = this.children.get(i);
185 if (oldChildAtIndex.equals(oldChild)) {
186 this.children.set(i, newChild);
187 return oldChildAtIndex;
188 }
189 }
190 throw new DOMException(DOMException.NOT_FOUND_ERR,
191 AbstractPartialNodeImpl.COULD_NOT_FIND_NODE + oldChild);
192 }
193
194 /** {@inheritDoc} */
195 public final Node insertBefore(final Node newChild, final Node refChild) {
196 throw new UnsupportedOperationException("insertBefore");
197 }
198
199 /** {@inheritDoc} */
200 public final boolean isEqualNode(final Node arg) {
201 throw new UnsupportedOperationException("isEqualNode");
202 }
203
204 /** {@inheritDoc} */
205 public final Node getNextSibling() {
206 Node retval;
207 try {
208 final List<Node> parentsChildren = ((AbstractPartialNodeImpl) this.parent).children;
209 retval = parentsChildren.get(parentsChildren.indexOf(this) + 1);
210 } catch (final NullPointerException ne) {
211 retval = null;
212 } catch (final IndexOutOfBoundsException iobe) {
213 retval = null;
214 }
215 return retval;
216 }
217
218 /** {@inheritDoc} */
219 public final boolean hasAttributes() {
220 return this.getAttributes().getLength() > 0;
221 }
222
223 /** {@inheritDoc} */
224 public final short compareDocumentPosition(final Node other) {
225 throw new UnsupportedOperationException("compareDocumentPosition");
226 }
227
228 /** {@inheritDoc} */
229 public final Node removeChild(final Node oldChild) {
230 for (int i = 0; i < this.children.size(); i++) {
231 final Node oldChildAtIndex = this.children.get(i);
232 if (oldChildAtIndex.equals(oldChild)) {
233 this.children.remove(i);
234 return oldChildAtIndex;
235 }
236 }
237 throw new DOMException(DOMException.NOT_FOUND_ERR,
238 AbstractPartialNodeImpl.COULD_NOT_FIND_NODE + oldChild);
239
240 }
241
242 /** {@inheritDoc} */
243 public final Object getFeature(final String feature, final String version) {
244 throw new UnsupportedOperationException("getFeature");
245 }
246
247 /** {@inheritDoc} */
248 public final Node getLastChild() {
249 final List<Node> theChildren = this.children;
250 final int size = theChildren.size();
251 if (size == 0) {
252 return null;
253 } else {
254 return theChildren.get(size - 1);
255 }
256 }
257
258 /** {@inheritDoc} */
259 public String getLocalName() {
260 return null;
261 }
262
263 /** {@inheritDoc} */
264 public final Document getOwnerDocument() {
265 throw new UnsupportedOperationException("getOwnerDocument");
266 }
267
268 /** {@inheritDoc} */
269 public final Node getPreviousSibling() {
270 throw new UnsupportedOperationException("getPreviousSibling");
271 }
272
273 /** {@inheritDoc} */
274 public final boolean isSupported(final String feature,
275 final String version) {
276 throw new UnsupportedOperationException("isSupported");
277 }
278
279 /** {@inheritDoc} */
280 public final String lookupPrefix(final String namespaceURI) {
281 throw new UnsupportedOperationException("lookupPrefix");
282 }
283
284 /** {@inheritDoc} */
285 public final void setNodeValue(final String nodeValue) {
286 throw new UnsupportedOperationException("setNodeValue");
287 }
288
289 /** {@inheritDoc} */
290 public final void setPrefix(final String prefix) {
291 throw new UnsupportedOperationException("setPrefix");
292 }
293
294 /** {@inheritDoc} */
295 public final Object getUserData(final String key) {
296 throw new UnsupportedOperationException("getUserData");
297 }
298
299 /** {@inheritDoc} */
300 public final Object setUserData(final String key, final Object data,
301 final UserDataHandler handler) {
302 throw new UnsupportedOperationException("setUserData");
303 }
304
305 }