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: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.xml2;
030:
031: import org.w3c.dom.Attr;
032: import org.w3c.dom.DOMException;
033: import org.w3c.dom.NamedNodeMap;
034: import org.w3c.dom.Node;
035:
036: import javax.xml.namespace.QName;
037:
038: public abstract class QAttributedNode extends QNode {
039: QAttr _firstAttribute;
040:
041: /**
042: * Returns a map of the attributes.
043: */
044: public NamedNodeMap getAttributes() {
045: return new QAttributeMap(this );
046: }
047:
048: /**
049: * Returns true if the element has attributes.
050: */
051: public boolean hasAttributes() {
052: return _firstAttribute != null;
053: }
054:
055: /**
056: * Returns the first attribute in the attribute list.
057: */
058: public Attr getFirstAttribute() {
059: return _firstAttribute;
060: }
061:
062: /**
063: * Returns the named attribute.
064: */
065: public String getAttribute(String name) {
066: for (QAbstractNode attr = _firstAttribute; attr != null; attr = attr._next) {
067: if (name.equals(attr.getNodeName()))
068: return attr.getNodeValue();
069: }
070:
071: return "";
072: }
073:
074: /**
075: * Returns the attribute specified by a namespace.
076: */
077: public String getAttributeNS(String namespaceURI, String local) {
078: for (QAbstractNode attr = _firstAttribute; attr != null; attr = attr._next) {
079: String attrURI = attr.getNamespaceURI();
080:
081: if (attr.getLocalName().equals(local)
082: && (attrURI == namespaceURI || attrURI != null
083: && attrURI.equals(namespaceURI)))
084: return attr.getNodeValue();
085: }
086:
087: return "";
088: }
089:
090: public boolean hasAttribute(String name) {
091: for (QAbstractNode attr = _firstAttribute; attr != null; attr = attr._next) {
092: if (attr.getNodeName().equals(name))
093: return true;
094: }
095:
096: return false;
097: }
098:
099: public boolean hasAttributeNS(String uri, String local) {
100: for (QAbstractNode attr = _firstAttribute; attr != null; attr = attr._next) {
101: String attrURI = attr.getNamespaceURI();
102:
103: if (attr.getLocalName().equals(local)
104: && (attrURI == uri || attrURI != null
105: && attrURI.equals(uri)))
106: return true;
107: }
108:
109: return false;
110: }
111:
112: /**
113: * Returns the attribute specified by the name.
114: */
115: public Attr getAttributeNode(String name) {
116: for (QAbstractNode attr = _firstAttribute; attr != null; attr = attr._next) {
117: if (attr.getNodeName().equals(name))
118: return (Attr) attr;
119: }
120:
121: return null;
122: }
123:
124: public Attr getAttributeNodeNS(String uri, String local) {
125: for (QAbstractNode attr = _firstAttribute; attr != null; attr = attr._next) {
126: String attrURI = attr.getNamespaceURI();
127:
128: if (attr.getLocalName().equals(local)
129: && (attrURI == uri || attrURI != null
130: && attrURI.equals(uri)))
131: return (Attr) attr;
132: }
133:
134: return null;
135: }
136:
137: public void setAttribute(String name, String value)
138: throws DOMException {
139: if (!isNameValid(name))
140: throw new QDOMException(DOMException.INVALID_CHARACTER_ERR,
141: "illegal attribute `" + name + "'");
142:
143: setAttributeNode(_owner.createAttribute(name, value));
144: }
145:
146: public void setAttributeNS(String uri, String local, String value) {
147: Attr attr = _owner.createAttributeNS(uri, local);
148: attr.setNodeValue(value);
149:
150: setAttributeNodeNS(attr);
151: }
152:
153: void setAttribute(QName name, String value) throws DOMException {
154: setAttributeNode(_owner.createAttribute(name, value));
155: }
156:
157: /**
158: * Sets an attribute, specified by the object.
159: */
160: public void setIdAttribute(String name, boolean isId)
161: throws DOMException {
162: }
163:
164: /**
165: * Sets an attribute, specified by the object.
166: */
167: public void setIdAttributeNS(String namespaceURI, String localName,
168: boolean isId) throws DOMException {
169: }
170:
171: /**
172: * Sets an attribute, specified by the object.
173: */
174: public void setIdAttributeNode(Attr attr, boolean isId)
175: throws DOMException {
176: }
177:
178: /**
179: * Sets an attribute, specified by the object.
180: */
181: public Attr setAttributeNode(Attr attr) throws DOMException {
182: QAttr qAttr = (QAttr) attr;
183:
184: if (qAttr._owner == null)
185: qAttr._owner = _owner;
186: else if (qAttr._owner != _owner)
187: throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR,
188: "attribute from wrong document");
189:
190: if (qAttr._parent != null)
191: throw new QDOMException(DOMException.INUSE_ATTRIBUTE_ERR,
192: "attribute `" + attr.getNodeName() + "' is in use");
193:
194: qAttr._parent = this ;
195:
196: // remove any matching old attribute
197: QAttr old = unlink(attr.getNodeName());
198:
199: QAttr ptr = _firstAttribute;
200:
201: if (ptr == null) {
202: _firstAttribute = qAttr;
203: } else {
204: for (; ptr._next != null; ptr = (QAttr) ptr._next) {
205: }
206:
207: ptr._next = qAttr;
208: }
209:
210: return old;
211: }
212:
213: public Attr setAttributeNodeNS(Attr attr) throws DOMException {
214: QAttr qAttr = (QAttr) attr;
215:
216: if (qAttr._owner != _owner)
217: throw new QDOMException(DOMException.WRONG_DOCUMENT_ERR,
218: "attribute from wrong document");
219:
220: if (qAttr._parent != null)
221: throw new QDOMException(DOMException.INUSE_ATTRIBUTE_ERR,
222: "attribute `" + attr.getNodeName() + "' is in use");
223:
224: // remove any matching old attribute
225: QAttr old = unlink(qAttr.getNamespaceURI(), qAttr
226: .getLocalName());
227:
228: qAttr._parent = this ;
229:
230: qAttr._next = _firstAttribute;
231: _firstAttribute = qAttr;
232:
233: return old;
234: }
235:
236: /**
237: * Removes the named attribute.
238: */
239: public void removeAttribute(String name) {
240: if (!isNameValid(name))
241: throw new QDOMException(DOMException.INVALID_CHARACTER_ERR,
242: "illegal attribute `" + name + "'");
243:
244: unlink(name);
245: }
246:
247: /**
248: * Removes the attribute specified by the localname and namespace.
249: */
250: public void removeAttributeNS(String uri, String name) {
251: unlink(uri, name);
252: }
253:
254: /**
255: * Removes the matching attribute.
256: */
257: public Attr removeAttributeNode(Attr attr) {
258: return unlink(attr.getNodeName());
259: }
260:
261: /**
262: * Removes the matching attribute.
263: */
264: public Attr removeAttributeNodeNS(Attr attr) {
265: return unlink(attr.getNamespaceURI(), attr.getLocalName());
266: }
267:
268: /**
269: * Unlinks an attribute, returning it.
270: */
271: QAttr unlink(String name) {
272: QAttr prev = null;
273: QAttr ptr;
274:
275: for (ptr = _firstAttribute; ptr != null
276: && !ptr.getNodeName().equals(name); ptr = (QAttr) ptr._next) {
277: prev = ptr;
278: }
279:
280: if (ptr == null)
281: return null;
282:
283: if (prev == null)
284: _firstAttribute = (QAttr) ptr._next;
285: else
286: prev._next = ptr._next;
287:
288: ptr._next = null;
289:
290: return ptr;
291: }
292:
293: /**
294: * Removes the attribute named by the URI and local name.
295: */
296: public QAttr unlink(String uri, String local) {
297: if (local == null || uri == null)
298: return null;
299:
300: QAttr prev = null;
301: QAttr ptr;
302:
303: for (ptr = (QAttr) _firstAttribute; ptr != null
304: && (!local.equals(ptr.getLocalName()) || !uri
305: .equals(ptr.getNamespaceURI())); ptr = (QAttr) ptr._next) {
306: prev = ptr;
307: }
308:
309: if (ptr == null)
310: return null;
311:
312: if (prev == null)
313: _firstAttribute = (QAttr) ptr._next;
314: else
315: prev._next = ptr._next;
316:
317: ptr._next = null;
318:
319: return ptr;
320: }
321:
322: static class QAttributeMap implements NamedNodeMap {
323: QAttributedNode _elt;
324: int _i;
325: QAttr _attr;
326:
327: QAttributeMap(QAttributedNode elt) {
328: _elt = elt;
329: }
330:
331: public Node getNamedItem(String name) {
332: return _elt.getAttributeNode(name);
333: }
334:
335: public Node getNamedItemNS(String uri, String localName) {
336: return _elt.getAttributeNodeNS(uri, localName);
337: }
338:
339: public Node setNamedItem(Node arg) throws DOMException {
340: return _elt.setAttributeNode((Attr) arg);
341: }
342:
343: public Node setNamedItemNS(Node arg) {
344: return _elt.setAttributeNodeNS((Attr) arg);
345: }
346:
347: public Node removeNamedItem(String name) throws DOMException {
348: return _elt.unlink(name);
349: }
350:
351: public Node removeNamedItemNS(String uri, String localName) {
352: return _elt.getAttributeNodeNS(uri, localName);
353: }
354:
355: public Node item(int index) {
356: QAbstractNode attr = _elt._firstAttribute;
357:
358: while (index > 0 && attr != null) {
359: attr = attr._next;
360: index--;
361: }
362:
363: return attr;
364: }
365:
366: public int getLength() {
367: int length = 0;
368:
369: for (QAbstractNode attr = _elt._firstAttribute; attr != null; attr = attr._next)
370: length++;
371:
372: return length;
373: }
374: }
375: }
|