001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Emil Ong
028: */
029:
030: package com.caucho.xml.saaj;
031:
032: import java.util.*;
033:
034: import javax.xml.XMLConstants;
035: import javax.xml.namespace.*;
036: import javax.xml.soap.*;
037:
038: import org.w3c.dom.*;
039:
040: import com.caucho.xml.XmlUtil;
041:
042: public abstract class SOAPNodeImpl implements javax.xml.soap.Node {
043: protected SOAPFactory _factory;
044:
045: protected Document _owner;
046:
047: protected SOAPElementImpl _parent;
048:
049: protected SOAPNodeImpl _firstChild;
050: protected SOAPNodeImpl _lastChild;
051:
052: protected SOAPNodeImpl _next;
053: protected SOAPNodeImpl _previous;
054:
055: protected NameImpl _name;
056:
057: protected SOAPNodeImpl(SOAPFactory factory, NameImpl name) {
058: _factory = factory;
059: _name = name;
060: }
061:
062: protected SOAPNodeImpl(SOAPFactory factory, NameImpl name,
063: Document owner) {
064: _factory = factory;
065: _name = name;
066: _owner = owner;
067: }
068:
069: public void setOwner(Document owner) {
070: _owner = owner;
071: // XXX deep set?
072: }
073:
074: // javax.xml.soap.Node
075:
076: public void detachNode() {
077: if (getParentNode() != null)
078: getParentNode().removeChild(this );
079: }
080:
081: public SOAPElement getParentElement() {
082: return (SOAPElement) getParentNode();
083: }
084:
085: public void setParentElement(SOAPElement parent)
086: throws SOAPException {
087: if (parent == null)
088: throw new IllegalArgumentException();
089:
090: if (parent instanceof SOAPElementImpl)
091: _parent = (SOAPElementImpl) parent;
092: else
093: _parent = new SOAPElementImpl(_factory, parent);
094: }
095:
096: public String getValue() {
097: if (_firstChild == null || _firstChild != _lastChild)
098: return null;
099:
100: if (_firstChild instanceof javax.xml.soap.Text)
101: return ((javax.xml.soap.Text) _firstChild).getValue();
102:
103: return null;
104: }
105:
106: public void setValue(String value) {
107: if (_firstChild == null)
108: appendChild(new TextImpl(_factory, value));
109: else {
110: if (_firstChild != _lastChild)
111: throw new IllegalStateException(
112: "Element has more than one child");
113:
114: if (!(_firstChild instanceof javax.xml.soap.Text))
115: throw new IllegalStateException(
116: "Child is not a Text node");
117:
118: ((javax.xml.soap.Text) _firstChild).setValue(value);
119: }
120: }
121:
122: public void recycleNode() {
123: }
124:
125: // org.w3c.dom.Node
126:
127: public NamedNodeMap getAttributes() {
128: return null;
129: }
130:
131: public Document getOwnerDocument() {
132: return _owner;
133: }
134:
135: public org.w3c.dom.Node appendChild(org.w3c.dom.Node newChild) {
136: SOAPNodeImpl node = (SOAPNodeImpl) newChild;
137:
138: try {
139: if (this instanceof SOAPElementImpl)
140: node.setParentElement((SOAPElementImpl) this );
141: } catch (SOAPException e) {
142: throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
143: e.getMessage());
144: }
145:
146: node._owner = _owner;
147:
148: if (_lastChild == null)
149: _firstChild = _lastChild = node;
150: else {
151: _lastChild._next = node;
152: node._previous = _lastChild;
153: _lastChild = node;
154: }
155:
156: return newChild;
157: }
158:
159: public org.w3c.dom.Node cloneNode(boolean deep) {
160: throw new UnsupportedOperationException();
161: }
162:
163: public short compareDocumentPosition(org.w3c.dom.Node other) {
164: throw new UnsupportedOperationException();
165: }
166:
167: public String getBaseURI() {
168: return null;
169: }
170:
171: public NodeList getChildNodes() {
172: return new NodeListImpl();
173: }
174:
175: public Object getFeature(String feature, String version) {
176: return null;
177: }
178:
179: public org.w3c.dom.Node getFirstChild() {
180: return _firstChild;
181: }
182:
183: public org.w3c.dom.Node getLastChild() {
184: return _lastChild;
185: }
186:
187: public String getPrefix() {
188: return _name.getPrefix();
189: }
190:
191: public String getLocalName() {
192: return _name.getLocalName();
193: }
194:
195: public String getNamespaceURI() {
196: if ("".equals(_name.getURI()))
197: return null;
198:
199: return _name.getURI();
200: }
201:
202: public org.w3c.dom.Node getNextSibling() {
203: return _next;
204: }
205:
206: public org.w3c.dom.Node getParentNode() {
207: return _parent;
208: }
209:
210: public org.w3c.dom.Node getPreviousSibling() {
211: return _previous;
212: }
213:
214: public String getTextContent() {
215: return XmlUtil.textValue(this );
216: }
217:
218: public Object getUserData(String key) {
219: return null;
220: }
221:
222: public Object setUserData(String key, Object data,
223: UserDataHandler handler) {
224: return null;
225: }
226:
227: public boolean hasAttributes() {
228: return false;
229: }
230:
231: public boolean hasChildNodes() {
232: return _firstChild != null;
233: }
234:
235: public org.w3c.dom.Node insertBefore(org.w3c.dom.Node newChild,
236: org.w3c.dom.Node refChild) {
237: throw new UnsupportedOperationException();
238: }
239:
240: public boolean isDefaultNamespace(String namespaceURI) {
241: throw new UnsupportedOperationException();
242: }
243:
244: public boolean isEqualNode(org.w3c.dom.Node arg) {
245: if (arg == null)
246: return false;
247:
248: if (getNodeType() != arg.getNodeType())
249: return false;
250:
251: if ((getNodeName() == null && arg.getNodeName() != null)
252: || (getNodeName() != null && !getNodeName().equals(
253: arg.getNodeName())))
254: return false;
255:
256: if ((getLocalName() == null && arg.getLocalName() != null)
257: || (getLocalName() != null && !getLocalName().equals(
258: arg.getLocalName())))
259: return false;
260:
261: if ((getNamespaceURI() == null && arg.getNamespaceURI() != null)
262: || (getNamespaceURI() != null && !getNamespaceURI()
263: .equals(arg.getNamespaceURI())))
264: return false;
265:
266: if ((getPrefix() == null && arg.getPrefix() != null)
267: || (getPrefix() != null && !getPrefix().equals(
268: arg.getPrefix())))
269: return false;
270:
271: if ((getNodeValue() == null && arg.getNodeValue() != null)
272: || (getNodeValue() != null && !getNodeValue().equals(
273: arg.getNodeValue())))
274: return false;
275:
276: NamedNodeMap map = getAttributes();
277: NamedNodeMap otherMap = arg.getAttributes();
278:
279: if ((map == null) != (otherMap == null))
280: return false;
281:
282: if (map != null) {
283: if (map.getLength() != otherMap.getLength())
284: return false;
285:
286: for (int i = 0; i < map.getLength(); i++) {
287: org.w3c.dom.Node attr = map.item(i);
288: org.w3c.dom.Node otherAttr = null;
289:
290: if (attr.getNamespaceURI() != null)
291: otherAttr = otherMap.getNamedItemNS(attr
292: .getNamespaceURI(), attr.getLocalName());
293: else
294: otherAttr = otherMap.getNamedItem(attr
295: .getLocalName());
296:
297: if (otherAttr == null || !attr.isEqualNode(otherAttr))
298: return false;
299: }
300: }
301:
302: normalize();
303: arg.normalize();
304:
305: NodeList children = getChildNodes();
306: NodeList otherChildren = arg.getChildNodes();
307:
308: if (children.getLength() != otherChildren.getLength())
309: return false;
310:
311: for (int i = 0; i < children.getLength(); i++) {
312: if (!children.item(i).isEqualNode(otherChildren.item(i)))
313: return false;
314: }
315:
316: return true;
317: }
318:
319: public boolean isSameNode(org.w3c.dom.Node other) {
320: return this == other;
321: }
322:
323: public boolean isSupported(String feature, String version) {
324: return false;
325: }
326:
327: public String lookupNamespaceURI(String prefix) {
328: return null;
329: }
330:
331: public String lookupPrefix(String namespaceURI) {
332: return null;
333: }
334:
335: public void normalize() {
336: }
337:
338: public org.w3c.dom.Node removeChild(org.w3c.dom.Node oldChild) {
339: if (oldChild.getParentNode() != this ) {
340: throw new DOMException(DOMException.NOT_FOUND_ERR,
341: "Child does not belong to this node");
342: }
343:
344: SOAPNodeImpl node = (SOAPNodeImpl) oldChild;
345: node._parent = null;
346:
347: if (node == _firstChild)
348: _firstChild = node._next;
349: else if (node._previous != null)
350: node._previous._next = node._next;
351:
352: if (node == _lastChild)
353: _lastChild = node._previous;
354: else if (node._next != null)
355: node._next._previous = node._previous;
356:
357: node._previous = null;
358: node._next = null;
359:
360: return node;
361: }
362:
363: public org.w3c.dom.Node replaceChild(org.w3c.dom.Node newChild,
364: org.w3c.dom.Node oldChild) {
365: throw new UnsupportedOperationException();
366: }
367:
368: public void setNodeValue(String nodeValue) {
369: }
370:
371: public void setPrefix(String prefix) {
372: }
373:
374: public void setTextContent(String textContent) {
375: throw new UnsupportedOperationException();
376: }
377:
378: protected class NodeListImpl implements NodeList {
379: public int getLength() {
380: int length = 0;
381:
382: for (org.w3c.dom.Node node = _firstChild; node != null; node = node
383: .getNextSibling())
384: length++;
385:
386: return length;
387: }
388:
389: public org.w3c.dom.Node item(int i) {
390: int j = 0;
391:
392: for (org.w3c.dom.Node node = _firstChild; node != null; node = node
393: .getNextSibling()) {
394: if (i == j)
395: return node;
396:
397: j++;
398: }
399:
400: return null;
401: }
402: }
403: }
|