0001: /*
0002: * Copyright 1999-2004 The Apache Software Foundation.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016: /*
0017: * $Id: DTMNodeProxy.java,v 1.24 2005/06/22 15:27:43 mkwan Exp $
0018: */
0019: package org.apache.xml.dtm.ref;
0020:
0021: import java.util.Vector;
0022:
0023: import org.apache.xml.dtm.DTM;
0024: import org.apache.xml.dtm.DTMDOMException;
0025: import org.apache.xpath.NodeSet;
0026:
0027: import org.w3c.dom.Attr;
0028: import org.w3c.dom.CDATASection;
0029: import org.w3c.dom.Comment;
0030: import org.w3c.dom.DOMException;
0031: import org.w3c.dom.DOMImplementation;
0032: import org.w3c.dom.Document;
0033: import org.w3c.dom.DocumentFragment;
0034: import org.w3c.dom.DocumentType;
0035: import org.w3c.dom.Element;
0036: import org.w3c.dom.EntityReference;
0037: import org.w3c.dom.NamedNodeMap;
0038: import org.w3c.dom.Node;
0039: import org.w3c.dom.NodeList;
0040: import org.w3c.dom.ProcessingInstruction;
0041: import org.w3c.dom.Text;
0042:
0043: import org.w3c.dom.UserDataHandler;
0044: import org.w3c.dom.DOMConfiguration;
0045: import org.w3c.dom.TypeInfo;
0046:
0047: /**
0048: * <code>DTMNodeProxy</code> presents a DOM Node API front-end to the DTM model.
0049: * <p>
0050: * It does _not_ attempt to address the "node identity" question; no effort
0051: * is made to prevent the creation of multiple proxies referring to a single
0052: * DTM node. Users can create a mechanism for managing this, or relinquish the
0053: * use of "==" and use the .sameNodeAs() mechanism, which is under
0054: * consideration for future versions of the DOM.
0055: * <p>
0056: * DTMNodeProxy may be subclassed further to present specific DOM node types.
0057: *
0058: * @see org.w3c.dom
0059: * @xsl.usage internal
0060: */
0061: public class DTMNodeProxy implements Node, Document, Text, Element,
0062: Attr, ProcessingInstruction, Comment, DocumentFragment {
0063:
0064: /** The DTM for this node. */
0065: public DTM dtm;
0066:
0067: /** The DTM node handle. */
0068: int node;
0069:
0070: /** The return value as Empty String. */
0071: private static final String EMPTYSTRING = "";
0072:
0073: /** The DOMImplementation object */
0074: static final DOMImplementation implementation = new DTMNodeProxyImplementation();
0075:
0076: /**
0077: * Create a DTMNodeProxy Node representing a specific Node in a DTM
0078: *
0079: * @param dtm The DTM Reference, must be non-null.
0080: * @param node The DTM node handle.
0081: */
0082: public DTMNodeProxy(DTM dtm, int node) {
0083: this .dtm = dtm;
0084: this .node = node;
0085: }
0086:
0087: /**
0088: * NON-DOM: Return the DTM model
0089: *
0090: * @return The DTM that this proxy is a representative for.
0091: */
0092: public final DTM getDTM() {
0093: return dtm;
0094: }
0095:
0096: /**
0097: * NON-DOM: Return the DTM node number
0098: *
0099: * @return The DTM node handle.
0100: */
0101: public final int getDTMNodeNumber() {
0102: return node;
0103: }
0104:
0105: /**
0106: * Test for equality based on node number.
0107: *
0108: * @param node A DTM node proxy reference.
0109: *
0110: * @return true if the given node has the same handle as this node.
0111: */
0112: public final boolean equals(Node node) {
0113:
0114: try {
0115: DTMNodeProxy dtmp = (DTMNodeProxy) node;
0116:
0117: // return (dtmp.node == this.node);
0118: // Patch attributed to Gary L Peskin <garyp@firstech.com>
0119: return (dtmp.node == this .node) && (dtmp.dtm == this .dtm);
0120: } catch (ClassCastException cce) {
0121: return false;
0122: }
0123: }
0124:
0125: /**
0126: * Test for equality based on node number.
0127: *
0128: * @param node A DTM node proxy reference.
0129: *
0130: * @return true if the given node has the same handle as this node.
0131: */
0132: public final boolean equals(Object node) {
0133:
0134: try {
0135:
0136: // DTMNodeProxy dtmp = (DTMNodeProxy)node;
0137: // return (dtmp.node == this.node);
0138: // Patch attributed to Gary L Peskin <garyp@firstech.com>
0139: return equals((Node) node);
0140: } catch (ClassCastException cce) {
0141: return false;
0142: }
0143: }
0144:
0145: /**
0146: * FUTURE DOM: Test node identity, in lieu of Node==Node
0147: *
0148: * @param other
0149: *
0150: * @return true if the given node has the same handle as this node.
0151: */
0152: public final boolean sameNodeAs(Node other) {
0153:
0154: if (!(other instanceof DTMNodeProxy))
0155: return false;
0156:
0157: DTMNodeProxy that = (DTMNodeProxy) other;
0158:
0159: return this .dtm == that.dtm && this .node == that.node;
0160: }
0161:
0162: /**
0163: *
0164: *
0165: * @see org.w3c.dom.Node
0166: */
0167: public final String getNodeName() {
0168: return dtm.getNodeName(node);
0169: }
0170:
0171: /**
0172: * A PI's "target" states what processor channel the PI's data
0173: * should be directed to. It is defined differently in HTML and XML.
0174: * <p>
0175: * In XML, a PI's "target" is the first (whitespace-delimited) token
0176: * following the "<?" token that begins the PI.
0177: * <p>
0178: * In HTML, target is always null.
0179: * <p>
0180: * Note that getNodeName is aliased to getTarget.
0181: *
0182: *
0183: */
0184: public final String getTarget() {
0185: return dtm.getNodeName(node);
0186: } // getTarget():String
0187:
0188: /**
0189: *
0190: *
0191: * @see org.w3c.dom.Node as of DOM Level 2
0192: */
0193: public final String getLocalName() {
0194: return dtm.getLocalName(node);
0195: }
0196:
0197: /**
0198: * @return The prefix for this node.
0199: * @see org.w3c.dom.Node as of DOM Level 2
0200: */
0201: public final String getPrefix() {
0202: return dtm.getPrefix(node);
0203: }
0204:
0205: /**
0206: *
0207: * @param prefix
0208: *
0209: * @throws DOMException
0210: * @see org.w3c.dom.Node as of DOM Level 2 -- DTMNodeProxy is read-only
0211: */
0212: public final void setPrefix(String prefix) throws DOMException {
0213: throw new DTMDOMException(
0214: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0215: }
0216:
0217: /**
0218: *
0219: *
0220: * @see org.w3c.dom.Node as of DOM Level 2
0221: */
0222: public final String getNamespaceURI() {
0223: return dtm.getNamespaceURI(node);
0224: }
0225:
0226: /** Ask whether we support a given DOM feature.
0227: * In fact, we do not _fully_ support any DOM feature -- we're a
0228: * read-only subset -- so arguably we should always return false.
0229: * Or we could say that we support DOM Core Level 2 but all nodes
0230: * are read-only. Unclear which answer is least misleading.
0231: *
0232: * NON-DOM method. This was present in early drafts of DOM Level 2,
0233: * but was renamed isSupported. It's present here only because it's
0234: * cheap, harmless, and might help some poor fool who is still trying
0235: * to use an early Working Draft of the DOM.
0236: *
0237: * @param feature
0238: * @param version
0239: *
0240: * @return false
0241: */
0242: public final boolean supports(String feature, String version) {
0243: return implementation.hasFeature(feature, version);
0244: //throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0245: }
0246:
0247: /** Ask whether we support a given DOM feature.
0248: * In fact, we do not _fully_ support any DOM feature -- we're a
0249: * read-only subset -- so arguably we should always return false.
0250: *
0251: * @param feature
0252: * @param version
0253: *
0254: * @return false
0255: * @see org.w3c.dom.Node as of DOM Level 2
0256: */
0257: public final boolean isSupported(String feature, String version) {
0258: return implementation.hasFeature(feature, version);
0259: // throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0260: }
0261:
0262: /**
0263: *
0264: *
0265: *
0266: * @throws DOMException
0267: * @see org.w3c.dom.Node
0268: */
0269: public final String getNodeValue() throws DOMException {
0270: return dtm.getNodeValue(node);
0271: }
0272:
0273: /**
0274: * @return The string value of the node
0275: *
0276: * @throws DOMException
0277: */
0278: public final String getStringValue() throws DOMException {
0279: return dtm.getStringValue(node).toString();
0280: }
0281:
0282: /**
0283: *
0284: * @param nodeValue
0285: *
0286: * @throws DOMException
0287: * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
0288: */
0289: public final void setNodeValue(String nodeValue)
0290: throws DOMException {
0291: throw new DTMDOMException(
0292: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0293: }
0294:
0295: /**
0296: *
0297: *
0298: * @see org.w3c.dom.Node
0299: */
0300: public final short getNodeType() {
0301: return (short) dtm.getNodeType(node);
0302: }
0303:
0304: /**
0305: *
0306: *
0307: * @see org.w3c.dom.Node
0308: */
0309: public final Node getParentNode() {
0310:
0311: if (getNodeType() == Node.ATTRIBUTE_NODE)
0312: return null;
0313:
0314: int newnode = dtm.getParent(node);
0315:
0316: return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
0317: }
0318:
0319: /**
0320: *
0321: *
0322: * @see org.w3c.dom.Node
0323: */
0324: public final Node getOwnerNode() {
0325:
0326: int newnode = dtm.getParent(node);
0327:
0328: return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
0329: }
0330:
0331: /**
0332: *
0333: *
0334: * @see org.w3c.dom.Node
0335: */
0336: public final NodeList getChildNodes() {
0337:
0338: // Annoyingly, AxisIterators do not currently implement DTMIterator, so
0339: // we can't just wap DTMNodeList around an Axis.CHILD iterator.
0340: // Instead, we've created a special-case operating mode for that object.
0341: return new DTMChildIterNodeList(dtm, node);
0342:
0343: // throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0344: }
0345:
0346: /**
0347: *
0348: *
0349: * @see org.w3c.dom.Node
0350: */
0351: public final Node getFirstChild() {
0352:
0353: int newnode = dtm.getFirstChild(node);
0354:
0355: return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
0356: }
0357:
0358: /**
0359: *
0360: *
0361: * @see org.w3c.dom.Node
0362: */
0363: public final Node getLastChild() {
0364:
0365: int newnode = dtm.getLastChild(node);
0366:
0367: return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
0368: }
0369:
0370: /**
0371: *
0372: *
0373: * @see org.w3c.dom.Node
0374: */
0375: public final Node getPreviousSibling() {
0376:
0377: int newnode = dtm.getPreviousSibling(node);
0378:
0379: return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
0380: }
0381:
0382: /**
0383: *
0384: *
0385: * @see org.w3c.dom.Node
0386: */
0387: public final Node getNextSibling() {
0388:
0389: // Attr's Next is defined at DTM level, but not at DOM level.
0390: if (dtm.getNodeType(node) == Node.ATTRIBUTE_NODE)
0391: return null;
0392:
0393: int newnode = dtm.getNextSibling(node);
0394:
0395: return (newnode == DTM.NULL) ? null : dtm.getNode(newnode);
0396: }
0397:
0398: // DTMNamedNodeMap m_attrs;
0399:
0400: /**
0401: *
0402: *
0403: * @see org.w3c.dom.Node
0404: */
0405: public final NamedNodeMap getAttributes() {
0406:
0407: return new DTMNamedNodeMap(dtm, node);
0408: }
0409:
0410: /**
0411: * Method hasAttribute
0412: *
0413: *
0414: * @param name
0415: *
0416: *
0417: */
0418: public boolean hasAttribute(String name) {
0419: return DTM.NULL != dtm.getAttributeNode(node, null, name);
0420: }
0421:
0422: /**
0423: * Method hasAttributeNS
0424: *
0425: *
0426: * @param namespaceURI
0427: * @param localName
0428: *
0429: *
0430: */
0431: public boolean hasAttributeNS(String namespaceURI, String localName) {
0432: return DTM.NULL != dtm.getAttributeNode(node, namespaceURI,
0433: localName);
0434: }
0435:
0436: /**
0437: *
0438: *
0439: * @see org.w3c.dom.Node
0440: */
0441: public final Document getOwnerDocument() {
0442: // Note that this uses the DOM-compatable version of the call
0443: return (Document) (dtm.getNode(dtm.getOwnerDocument(node)));
0444: }
0445:
0446: /**
0447: *
0448: * @param newChild
0449: * @param refChild
0450: *
0451: *
0452: *
0453: * @throws DOMException
0454: * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
0455: */
0456: public final Node insertBefore(Node newChild, Node refChild)
0457: throws DOMException {
0458: throw new DTMDOMException(
0459: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0460: }
0461:
0462: /**
0463: *
0464: * @param newChild
0465: * @param oldChild
0466: *
0467: *
0468: *
0469: * @throws DOMException
0470: * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
0471: */
0472: public final Node replaceChild(Node newChild, Node oldChild)
0473: throws DOMException {
0474: throw new DTMDOMException(
0475: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0476: }
0477:
0478: /**
0479: *
0480: * @param oldChild
0481: *
0482: *
0483: *
0484: * @throws DOMException
0485: * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
0486: */
0487: public final Node removeChild(Node oldChild) throws DOMException {
0488: throw new DTMDOMException(
0489: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0490: }
0491:
0492: /**
0493: *
0494: * @param newChild
0495: *
0496: *
0497: *
0498: * @throws DOMException
0499: * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
0500: */
0501: public final Node appendChild(Node newChild) throws DOMException {
0502: throw new DTMDOMException(
0503: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0504: }
0505:
0506: /**
0507: *
0508: *
0509: * @see org.w3c.dom.Node
0510: */
0511: public final boolean hasChildNodes() {
0512: return (DTM.NULL != dtm.getFirstChild(node));
0513: }
0514:
0515: /**
0516: *
0517: * @param deep
0518: *
0519: *
0520: * @see org.w3c.dom.Node -- DTMNodeProxy is read-only
0521: */
0522: public final Node cloneNode(boolean deep) {
0523: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0524: }
0525:
0526: /**
0527: *
0528: *
0529: * @see org.w3c.dom.Document
0530: */
0531: public final DocumentType getDoctype() {
0532: return null;
0533: }
0534:
0535: /**
0536: *
0537: *
0538: * @see org.w3c.dom.Document
0539: */
0540: public final DOMImplementation getImplementation() {
0541: return implementation;
0542: }
0543:
0544: /** This is a bit of a problem in DTM, since a DTM may be a Document
0545: * Fragment and hence not have a clear-cut Document Element. We can
0546: * make it work in the well-formed cases but would that be confusing for others?
0547: *
0548: *
0549: * @see org.w3c.dom.Document
0550: */
0551: public final Element getDocumentElement() {
0552: int dochandle = dtm.getDocument();
0553: int elementhandle = DTM.NULL;
0554: for (int kidhandle = dtm.getFirstChild(dochandle); kidhandle != DTM.NULL; kidhandle = dtm
0555: .getNextSibling(kidhandle)) {
0556: switch (dtm.getNodeType(kidhandle)) {
0557: case Node.ELEMENT_NODE:
0558: if (elementhandle != DTM.NULL) {
0559: elementhandle = DTM.NULL; // More than one; ill-formed.
0560: kidhandle = dtm.getLastChild(dochandle); // End loop
0561: } else
0562: elementhandle = kidhandle;
0563: break;
0564:
0565: // These are harmless; document is still wellformed
0566: case Node.COMMENT_NODE:
0567: case Node.PROCESSING_INSTRUCTION_NODE:
0568: case Node.DOCUMENT_TYPE_NODE:
0569: break;
0570:
0571: default:
0572: elementhandle = DTM.NULL; // ill-formed
0573: kidhandle = dtm.getLastChild(dochandle); // End loop
0574: break;
0575: }
0576: }
0577: if (elementhandle == DTM.NULL)
0578: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0579: else
0580: return (Element) (dtm.getNode(elementhandle));
0581: }
0582:
0583: /**
0584: *
0585: * @param tagName
0586: *
0587: *
0588: *
0589: * @throws DOMException
0590: * @see org.w3c.dom.Document
0591: */
0592: public final Element createElement(String tagName)
0593: throws DOMException {
0594: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0595: }
0596:
0597: /**
0598: *
0599: *
0600: * @see org.w3c.dom.Document
0601: */
0602: public final DocumentFragment createDocumentFragment() {
0603: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0604: }
0605:
0606: /**
0607: *
0608: * @param data
0609: *
0610: *
0611: * @see org.w3c.dom.Document
0612: */
0613: public final Text createTextNode(String data) {
0614: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0615: }
0616:
0617: /**
0618: *
0619: * @param data
0620: *
0621: *
0622: * @see org.w3c.dom.Document
0623: */
0624: public final Comment createComment(String data) {
0625: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0626: }
0627:
0628: /**
0629: *
0630: * @param data
0631: *
0632: *
0633: *
0634: * @throws DOMException
0635: * @see org.w3c.dom.Document
0636: */
0637: public final CDATASection createCDATASection(String data)
0638: throws DOMException {
0639: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0640: }
0641:
0642: /**
0643: *
0644: * @param target
0645: * @param data
0646: *
0647: *
0648: *
0649: * @throws DOMException
0650: * @see org.w3c.dom.Document
0651: */
0652: public final ProcessingInstruction createProcessingInstruction(
0653: String target, String data) throws DOMException {
0654: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0655: }
0656:
0657: /**
0658: *
0659: * @param name
0660: *
0661: *
0662: *
0663: * @throws DOMException
0664: * @see org.w3c.dom.Document
0665: */
0666: public final Attr createAttribute(String name) throws DOMException {
0667: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0668: }
0669:
0670: /**
0671: *
0672: * @param name
0673: *
0674: *
0675: *
0676: * @throws DOMException
0677: * @see org.w3c.dom.Document
0678: */
0679: public final EntityReference createEntityReference(String name)
0680: throws DOMException {
0681: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0682: }
0683:
0684: /**
0685: *
0686: * @param tagname
0687: *
0688: *
0689: * @see org.w3c.dom.Document
0690: */
0691: public final NodeList getElementsByTagName(String tagname) {
0692: Vector listVector = new Vector();
0693: Node retNode = dtm.getNode(node);
0694: if (retNode != null) {
0695: boolean isTagNameWildCard = "*".equals(tagname);
0696: if (DTM.ELEMENT_NODE == retNode.getNodeType()) {
0697: NodeList nodeList = retNode.getChildNodes();
0698: for (int i = 0; i < nodeList.getLength(); i++) {
0699: traverseChildren(listVector, nodeList.item(i),
0700: tagname, isTagNameWildCard);
0701: }
0702: } else if (DTM.DOCUMENT_NODE == retNode.getNodeType()) {
0703: traverseChildren(listVector, dtm.getNode(node),
0704: tagname, isTagNameWildCard);
0705: }
0706: }
0707: int size = listVector.size();
0708: NodeSet nodeSet = new NodeSet(size);
0709: for (int i = 0; i < size; i++) {
0710: nodeSet.addNode((Node) listVector.elementAt(i));
0711: }
0712: return (NodeList) nodeSet;
0713: }
0714:
0715: /**
0716: *
0717: * @param listVector
0718: * @param tempNode
0719: * @param tagname
0720: * @param isTagNameWildCard
0721: *
0722: *
0723: * Private method to be used for recursive iterations to obtain elements by tag name.
0724: */
0725: private final void traverseChildren(Vector listVector,
0726: Node tempNode, String tagname, boolean isTagNameWildCard) {
0727: if (tempNode == null) {
0728: return;
0729: } else {
0730: if (tempNode.getNodeType() == DTM.ELEMENT_NODE
0731: && (isTagNameWildCard || tempNode.getNodeName()
0732: .equals(tagname))) {
0733: listVector.add(tempNode);
0734: }
0735: if (tempNode.hasChildNodes()) {
0736: NodeList nodeList = tempNode.getChildNodes();
0737: for (int i = 0; i < nodeList.getLength(); i++) {
0738: traverseChildren(listVector, nodeList.item(i),
0739: tagname, isTagNameWildCard);
0740: }
0741: }
0742: }
0743: }
0744:
0745: /**
0746: *
0747: * @param importedNode
0748: * @param deep
0749: *
0750: *
0751: *
0752: * @throws DOMException
0753: * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only
0754: */
0755: public final Node importNode(Node importedNode, boolean deep)
0756: throws DOMException {
0757: throw new DTMDOMException(
0758: DOMException.NO_MODIFICATION_ALLOWED_ERR);
0759: }
0760:
0761: /**
0762: *
0763: * @param namespaceURI
0764: * @param qualifiedName
0765: *
0766: *
0767: *
0768: * @throws DOMException
0769: * @see org.w3c.dom.Document as of DOM Level 2
0770: */
0771: public final Element createElementNS(String namespaceURI,
0772: String qualifiedName) throws DOMException {
0773: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0774: }
0775:
0776: /**
0777: *
0778: * @param namespaceURI
0779: * @param qualifiedName
0780: *
0781: *
0782: *
0783: * @throws DOMException
0784: * @see org.w3c.dom.Document as of DOM Level 2
0785: */
0786: public final Attr createAttributeNS(String namespaceURI,
0787: String qualifiedName) throws DOMException {
0788: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0789: }
0790:
0791: /**
0792: *
0793: * @param namespaceURI
0794: * @param localName
0795: *
0796: *
0797: * @see org.w3c.dom.Document as of DOM Level 2
0798: */
0799: public final NodeList getElementsByTagNameNS(String namespaceURI,
0800: String localName) {
0801: Vector listVector = new Vector();
0802: Node retNode = dtm.getNode(node);
0803: if (retNode != null) {
0804: boolean isNamespaceURIWildCard = "*".equals(namespaceURI);
0805: boolean isLocalNameWildCard = "*".equals(localName);
0806: if (DTM.ELEMENT_NODE == retNode.getNodeType()) {
0807: NodeList nodeList = retNode.getChildNodes();
0808: for (int i = 0; i < nodeList.getLength(); i++) {
0809: traverseChildren(listVector, nodeList.item(i),
0810: namespaceURI, localName,
0811: isNamespaceURIWildCard, isLocalNameWildCard);
0812: }
0813: } else if (DTM.DOCUMENT_NODE == retNode.getNodeType()) {
0814: traverseChildren(listVector, dtm.getNode(node),
0815: namespaceURI, localName,
0816: isNamespaceURIWildCard, isLocalNameWildCard);
0817: }
0818: }
0819: int size = listVector.size();
0820: NodeSet nodeSet = new NodeSet(size);
0821: for (int i = 0; i < size; i++) {
0822: nodeSet.addNode((Node) listVector.elementAt(i));
0823: }
0824: return (NodeList) nodeSet;
0825: }
0826:
0827: /**
0828: *
0829: * @param listVector
0830: * @param tempNode
0831: * @param namespaceURI
0832: * @param localname
0833: * @param isNamespaceURIWildCard
0834: * @param isLocalNameWildCard
0835: *
0836: * Private method to be used for recursive iterations to obtain elements by tag name
0837: * and namespaceURI.
0838: */
0839: private final void traverseChildren(Vector listVector,
0840: Node tempNode, String namespaceURI, String localname,
0841: boolean isNamespaceURIWildCard, boolean isLocalNameWildCard) {
0842: if (tempNode == null) {
0843: return;
0844: } else {
0845: if (tempNode.getNodeType() == DTM.ELEMENT_NODE
0846: && (isLocalNameWildCard || tempNode.getLocalName()
0847: .equals(localname))) {
0848: String nsURI = tempNode.getNamespaceURI();
0849: if ((namespaceURI == null && nsURI == null)
0850: || isNamespaceURIWildCard
0851: || (namespaceURI != null && namespaceURI
0852: .equals(nsURI))) {
0853: listVector.add(tempNode);
0854: }
0855: }
0856: if (tempNode.hasChildNodes()) {
0857: NodeList nl = tempNode.getChildNodes();
0858: for (int i = 0; i < nl.getLength(); i++) {
0859: traverseChildren(listVector, nl.item(i),
0860: namespaceURI, localname,
0861: isNamespaceURIWildCard, isLocalNameWildCard);
0862: }
0863: }
0864: }
0865: }
0866:
0867: /**
0868: *
0869: * @param elementId
0870: *
0871: *
0872: * @see org.w3c.dom.Document as of DOM Level 2
0873: */
0874: public final Element getElementById(String elementId) {
0875: return (Element) dtm.getNode(dtm.getElementById(elementId));
0876: }
0877:
0878: /**
0879: *
0880: * @param offset
0881: *
0882: *
0883: *
0884: * @throws DOMException
0885: * @see org.w3c.dom.Text
0886: */
0887: public final Text splitText(int offset) throws DOMException {
0888: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0889: }
0890:
0891: /**
0892: *
0893: *
0894: *
0895: * @throws DOMException
0896: * @see org.w3c.dom.CharacterData
0897: */
0898: public final String getData() throws DOMException {
0899: return dtm.getNodeValue(node);
0900: }
0901:
0902: /**
0903: *
0904: * @param data
0905: *
0906: * @throws DOMException
0907: * @see org.w3c.dom.CharacterData
0908: */
0909: public final void setData(String data) throws DOMException {
0910: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0911: }
0912:
0913: /**
0914: *
0915: *
0916: * @see org.w3c.dom.CharacterData
0917: */
0918: public final int getLength() {
0919: // %OPT% This should do something smarter?
0920: return dtm.getNodeValue(node).length();
0921: }
0922:
0923: /**
0924: *
0925: * @param offset
0926: * @param count
0927: *
0928: *
0929: *
0930: * @throws DOMException
0931: * @see org.w3c.dom.CharacterData
0932: */
0933: public final String substringData(int offset, int count)
0934: throws DOMException {
0935: return getData().substring(offset, offset + count);
0936: }
0937:
0938: /**
0939: *
0940: * @param arg
0941: *
0942: * @throws DOMException
0943: * @see org.w3c.dom.CharacterData
0944: */
0945: public final void appendData(String arg) throws DOMException {
0946: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0947: }
0948:
0949: /**
0950: *
0951: * @param offset
0952: * @param arg
0953: *
0954: * @throws DOMException
0955: * @see org.w3c.dom.CharacterData
0956: */
0957: public final void insertData(int offset, String arg)
0958: throws DOMException {
0959: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0960: }
0961:
0962: /**
0963: *
0964: * @param offset
0965: * @param count
0966: *
0967: * @throws DOMException
0968: * @see org.w3c.dom.CharacterData
0969: */
0970: public final void deleteData(int offset, int count)
0971: throws DOMException {
0972: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0973: }
0974:
0975: /**
0976: *
0977: * @param offset
0978: * @param count
0979: * @param arg
0980: *
0981: * @throws DOMException
0982: * @see org.w3c.dom.CharacterData
0983: */
0984: public final void replaceData(int offset, int count, String arg)
0985: throws DOMException {
0986: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
0987: }
0988:
0989: /**
0990: *
0991: *
0992: * @see org.w3c.dom.Element
0993: */
0994: public final String getTagName() {
0995: return dtm.getNodeName(node);
0996: }
0997:
0998: /**
0999: *
1000: * @param name
1001: *
1002: *
1003: * @see org.w3c.dom.Element
1004: */
1005: public final String getAttribute(String name) {
1006:
1007: DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node);
1008: Node node = map.getNamedItem(name);
1009: return (null == node) ? EMPTYSTRING : node.getNodeValue();
1010: }
1011:
1012: /**
1013: *
1014: * @param name
1015: * @param value
1016: *
1017: * @throws DOMException
1018: * @see org.w3c.dom.Element
1019: */
1020: public final void setAttribute(String name, String value)
1021: throws DOMException {
1022: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1023: }
1024:
1025: /**
1026: *
1027: * @param name
1028: *
1029: * @throws DOMException
1030: * @see org.w3c.dom.Element
1031: */
1032: public final void removeAttribute(String name) throws DOMException {
1033: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1034: }
1035:
1036: /**
1037: *
1038: * @param name
1039: *
1040: *
1041: * @see org.w3c.dom.Element
1042: */
1043: public final Attr getAttributeNode(String name) {
1044:
1045: DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node);
1046: return (Attr) map.getNamedItem(name);
1047: }
1048:
1049: /**
1050: *
1051: * @param newAttr
1052: *
1053: *
1054: *
1055: * @throws DOMException
1056: * @see org.w3c.dom.Element
1057: */
1058: public final Attr setAttributeNode(Attr newAttr)
1059: throws DOMException {
1060: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1061: }
1062:
1063: /**
1064: *
1065: * @param oldAttr
1066: *
1067: *
1068: *
1069: * @throws DOMException
1070: * @see org.w3c.dom.Element
1071: */
1072: public final Attr removeAttributeNode(Attr oldAttr)
1073: throws DOMException {
1074: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1075: }
1076:
1077: /**
1078: * Introduced in DOM Level 2.
1079: *
1080: *
1081: */
1082: public boolean hasAttributes() {
1083: return DTM.NULL != dtm.getFirstAttribute(node);
1084: }
1085:
1086: /** @see org.w3c.dom.Element */
1087: public final void normalize() {
1088: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1089: }
1090:
1091: /**
1092: *
1093: * @param namespaceURI
1094: * @param localName
1095: *
1096: *
1097: * @see org.w3c.dom.Element
1098: */
1099: public final String getAttributeNS(String namespaceURI,
1100: String localName) {
1101: Node retNode = null;
1102: int n = dtm.getAttributeNode(node, namespaceURI, localName);
1103: if (n != DTM.NULL)
1104: retNode = dtm.getNode(n);
1105: return (null == retNode) ? EMPTYSTRING : retNode.getNodeValue();
1106: }
1107:
1108: /**
1109: *
1110: * @param namespaceURI
1111: * @param qualifiedName
1112: * @param value
1113: *
1114: * @throws DOMException
1115: * @see org.w3c.dom.Element
1116: */
1117: public final void setAttributeNS(String namespaceURI,
1118: String qualifiedName, String value) throws DOMException {
1119: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1120: }
1121:
1122: /**
1123: *
1124: * @param namespaceURI
1125: * @param localName
1126: *
1127: * @throws DOMException
1128: * @see org.w3c.dom.Element
1129: */
1130: public final void removeAttributeNS(String namespaceURI,
1131: String localName) throws DOMException {
1132: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1133: }
1134:
1135: /**
1136: *
1137: * @param namespaceURI
1138: * @param localName
1139: *
1140: *
1141: * @see org.w3c.dom.Element
1142: */
1143: public final Attr getAttributeNodeNS(String namespaceURI,
1144: String localName) {
1145: Attr retAttr = null;
1146: int n = dtm.getAttributeNode(node, namespaceURI, localName);
1147: if (n != DTM.NULL)
1148: retAttr = (Attr) dtm.getNode(n);
1149: return retAttr;
1150: }
1151:
1152: /**
1153: *
1154: * @param newAttr
1155: *
1156: *
1157: *
1158: * @throws DOMException
1159: * @see org.w3c.dom.Element
1160: */
1161: public final Attr setAttributeNodeNS(Attr newAttr)
1162: throws DOMException {
1163: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1164: }
1165:
1166: /**
1167: *
1168: *
1169: * @see org.w3c.dom.Attr
1170: */
1171: public final String getName() {
1172: return dtm.getNodeName(node);
1173: }
1174:
1175: /**
1176: *
1177: *
1178: * @see org.w3c.dom.Attr
1179: */
1180: public final boolean getSpecified() {
1181: // We really don't know which attributes might have come from the
1182: // source document versus from the DTD. Treat them all as having
1183: // been provided by the user.
1184: // %REVIEW% if/when we become aware of DTDs/schemae.
1185: return true;
1186: }
1187:
1188: /**
1189: *
1190: *
1191: * @see org.w3c.dom.Attr
1192: */
1193: public final String getValue() {
1194: return dtm.getNodeValue(node);
1195: }
1196:
1197: /**
1198: *
1199: * @param value
1200: * @see org.w3c.dom.Attr
1201: */
1202: public final void setValue(String value) {
1203: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1204: }
1205:
1206: /**
1207: * Get the owner element of an attribute.
1208: *
1209: *
1210: * @see org.w3c.dom.Attr as of DOM Level 2
1211: */
1212: public final Element getOwnerElement() {
1213: if (getNodeType() != Node.ATTRIBUTE_NODE)
1214: return null;
1215: // In XPath and DTM data models, unlike DOM, an Attr's parent is its
1216: // owner element.
1217: int newnode = dtm.getParent(node);
1218: return (newnode == DTM.NULL) ? null : (Element) (dtm
1219: .getNode(newnode));
1220: }
1221:
1222: /**
1223: * NEEDSDOC Method adoptNode
1224: *
1225: *
1226: * NEEDSDOC @param source
1227: *
1228: *
1229: *
1230: * @throws DOMException
1231: */
1232: public Node adoptNode(Node source) throws DOMException {
1233:
1234: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1235: }
1236:
1237: /**
1238: * <p>Based on the <a
1239: * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
1240: * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
1241: * <p>
1242: * An attribute specifying, as part of the XML declaration, the encoding
1243: * of this document. This is <code>null</code> when unspecified.
1244: * @since DOM Level 3
1245: *
1246: *
1247: */
1248: public String getInputEncoding() {
1249:
1250: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1251: }
1252:
1253: /**
1254: * <p>Based on the <a
1255: * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
1256: * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
1257: * <p>
1258: * An attribute specifying whether errors checking is enforced or not.
1259: * When set to <code>false</code>, the implementation is free to not
1260: * test every possible error case normally defined on DOM operations,
1261: * and not raise any <code>DOMException</code>. In case of error, the
1262: * behavior is undefined. This attribute is <code>true</code> by
1263: * defaults.
1264: * @since DOM Level 3
1265: *
1266: *
1267: */
1268: public boolean getStrictErrorChecking() {
1269:
1270: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1271: }
1272:
1273: /**
1274: * <p>Based on the <a
1275: * href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407'>Document
1276: * Object Model (DOM) Level 3 Core Specification of 07 April 2004.</a>.
1277: * <p>
1278: * An attribute specifying whether errors checking is enforced or not.
1279: * When set to <code>false</code>, the implementation is free to not
1280: * test every possible error case normally defined on DOM operations,
1281: * and not raise any <code>DOMException</code>. In case of error, the
1282: * behavior is undefined. This attribute is <code>true</code> by
1283: * defaults.
1284: * @since DOM Level 3
1285: *
1286: * NEEDSDOC @param strictErrorChecking
1287: */
1288: public void setStrictErrorChecking(boolean strictErrorChecking) {
1289: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1290: }
1291:
1292: /** Inner class to support getDOMImplementation.
1293: */
1294: static class DTMNodeProxyImplementation implements
1295: DOMImplementation {
1296: public DocumentType createDocumentType(String qualifiedName,
1297: String publicId, String systemId) {
1298: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1299: }
1300:
1301: public Document createDocument(String namespaceURI,
1302: String qualfiedName, DocumentType doctype) {
1303: // Could create a DTM... but why, when it'd have to be permanantly empty?
1304: throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR);
1305: }
1306:
1307: /** Ask whether we support a given DOM feature.
1308: *
1309: * In fact, we do not _fully_ support any DOM feature -- we're a
1310: * read-only subset -- so arguably we should always return false.
1311: * On the other hand, it may be more practically useful to return
1312: * true and simply treat the whole DOM as read-only, failing on the
1313: * methods we can't support. I'm not sure which would be more useful
1314: * to the caller.
1315: */
1316: public boolean hasFeature(String feature, String version) {
1317: if (("CORE".equals(feature.toUpperCase()) || "XML"
1318: .equals(feature.toUpperCase()))
1319: && ("1.0".equals(version) || "2.0".equals(version)))
1320: return true;
1321: return false;
1322: }
1323:
1324: /**
1325: * This method returns a specialized object which implements the
1326: * specialized APIs of the specified feature and version. The
1327: * specialized object may also be obtained by using binding-specific
1328: * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations
1329: .
1330: * @param feature The name of the feature requested (case-insensitive).
1331: * @param version This is the version number of the feature to test. If
1332: * the version is <code>null</code> or the empty string, supporting
1333: * any version of the feature will cause the method to return an
1334: * object that supports at least one version of the feature.
1335: * @return Returns an object which implements the specialized APIs of
1336: * the specified feature and version, if any, or <code>null</code> if
1337: * there is no object which implements interfaces associated with that
1338: * feature. If the <code>DOMObject</code> returned by this method
1339: * implements the <code>Node</code> interface, it must delegate to the
1340: * primary core <code>Node</code> and not return results inconsistent
1341: * with the primary core <code>Node</code> such as attributes,
1342: * childNodes, etc.
1343: * @since DOM Level 3
1344: */
1345: public Object getFeature(String feature, String version) {
1346: // we don't have any alternate node, either this node does the job
1347: // or we don't have anything that does
1348: //return hasFeature(feature, version) ? this : null;
1349: return null; //PENDING
1350: }
1351:
1352: }
1353:
1354: //RAMESH : Pending proper implementation of DOM Level 3
1355:
1356: public Object setUserData(String key, Object data,
1357: UserDataHandler handler) {
1358: return getOwnerDocument().setUserData(key, data, handler);
1359: }
1360:
1361: /**
1362: * Retrieves the object associated to a key on a this node. The object
1363: * must first have been set to this node by calling
1364: * <code>setUserData</code> with the same key.
1365: * @param key The key the object is associated to.
1366: * @return Returns the <code>DOMObject</code> associated to the given key
1367: * on this node, or <code>null</code> if there was none.
1368: * @since DOM Level 3
1369: */
1370: public Object getUserData(String key) {
1371: return getOwnerDocument().getUserData(key);
1372: }
1373:
1374: /**
1375: * This method returns a specialized object which implements the
1376: * specialized APIs of the specified feature and version. The
1377: * specialized object may also be obtained by using binding-specific
1378: * casting methods but is not necessarily expected to, as discussed in Mixed DOM implementations.
1379: * @param feature The name of the feature requested (case-insensitive).
1380: * @param version This is the version number of the feature to test. If
1381: * the version is <code>null</code> or the empty string, supporting
1382: * any version of the feature will cause the method to return an
1383: * object that supports at least one version of the feature.
1384: * @return Returns an object which implements the specialized APIs of
1385: * the specified feature and version, if any, or <code>null</code> if
1386: * there is no object which implements interfaces associated with that
1387: * feature. If the <code>DOMObject</code> returned by this method
1388: * implements the <code>Node</code> interface, it must delegate to the
1389: * primary core <code>Node</code> and not return results inconsistent
1390: * with the primary core <code>Node</code> such as attributes,
1391: * childNodes, etc.
1392: * @since DOM Level 3
1393: */
1394: public Object getFeature(String feature, String version) {
1395: // we don't have any alternate node, either this node does the job
1396: // or we don't have anything that does
1397: return isSupported(feature, version) ? this : null;
1398: }
1399:
1400: /**
1401: * Tests whether two nodes are equal.
1402: * <br>This method tests for equality of nodes, not sameness (i.e.,
1403: * whether the two nodes are references to the same object) which can be
1404: * tested with <code>Node.isSameNode</code>. All nodes that are the same
1405: * will also be equal, though the reverse may not be true.
1406: * <br>Two nodes are equal if and only if the following conditions are
1407: * satisfied: The two nodes are of the same type.The following string
1408: * attributes are equal: <code>nodeName</code>, <code>localName</code>,
1409: * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
1410: * , <code>baseURI</code>. This is: they are both <code>null</code>, or
1411: * they have the same length and are character for character identical.
1412: * The <code>attributes</code> <code>NamedNodeMaps</code> are equal.
1413: * This is: they are both <code>null</code>, or they have the same
1414: * length and for each node that exists in one map there is a node that
1415: * exists in the other map and is equal, although not necessarily at the
1416: * same index.The <code>childNodes</code> <code>NodeLists</code> are
1417: * equal. This is: they are both <code>null</code>, or they have the
1418: * same length and contain equal nodes at the same index. This is true
1419: * for <code>Attr</code> nodes as for any other type of node. Note that
1420: * normalization can affect equality; to avoid this, nodes should be
1421: * normalized before being compared.
1422: * <br>For two <code>DocumentType</code> nodes to be equal, the following
1423: * conditions must also be satisfied: The following string attributes
1424: * are equal: <code>publicId</code>, <code>systemId</code>,
1425: * <code>internalSubset</code>.The <code>entities</code>
1426: * <code>NamedNodeMaps</code> are equal.The <code>notations</code>
1427: * <code>NamedNodeMaps</code> are equal.
1428: * <br>On the other hand, the following do not affect equality: the
1429: * <code>ownerDocument</code> attribute, the <code>specified</code>
1430: * attribute for <code>Attr</code> nodes, the
1431: * <code>isWhitespaceInElementContent</code> attribute for
1432: * <code>Text</code> nodes, as well as any user data or event listeners
1433: * registered on the nodes.
1434: * @param arg The node to compare equality with.
1435: * @param deep If <code>true</code>, recursively compare the subtrees; if
1436: * <code>false</code>, compare only the nodes themselves (and its
1437: * attributes, if it is an <code>Element</code>).
1438: * @return If the nodes, and possibly subtrees are equal,
1439: * <code>true</code> otherwise <code>false</code>.
1440: * @since DOM Level 3
1441: */
1442: public boolean isEqualNode(Node arg) {
1443: if (arg == this ) {
1444: return true;
1445: }
1446: if (arg.getNodeType() != getNodeType()) {
1447: return false;
1448: }
1449: // in theory nodeName can't be null but better be careful
1450: // who knows what other implementations may be doing?...
1451: if (getNodeName() == null) {
1452: if (arg.getNodeName() != null) {
1453: return false;
1454: }
1455: } else if (!getNodeName().equals(arg.getNodeName())) {
1456: return false;
1457: }
1458:
1459: if (getLocalName() == null) {
1460: if (arg.getLocalName() != null) {
1461: return false;
1462: }
1463: } else if (!getLocalName().equals(arg.getLocalName())) {
1464: return false;
1465: }
1466:
1467: if (getNamespaceURI() == null) {
1468: if (arg.getNamespaceURI() != null) {
1469: return false;
1470: }
1471: } else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
1472: return false;
1473: }
1474:
1475: if (getPrefix() == null) {
1476: if (arg.getPrefix() != null) {
1477: return false;
1478: }
1479: } else if (!getPrefix().equals(arg.getPrefix())) {
1480: return false;
1481: }
1482:
1483: if (getNodeValue() == null) {
1484: if (arg.getNodeValue() != null) {
1485: return false;
1486: }
1487: } else if (!getNodeValue().equals(arg.getNodeValue())) {
1488: return false;
1489: }
1490: /*
1491: if (getBaseURI() == null) {
1492: if (((NodeImpl) arg).getBaseURI() != null) {
1493: return false;
1494: }
1495: }
1496: else if (!getBaseURI().equals(((NodeImpl) arg).getBaseURI())) {
1497: return false;
1498: }
1499: */
1500: return true;
1501: }
1502:
1503: /**
1504: * DOM Level 3:
1505: * Look up the namespace URI associated to the given prefix, starting from this node.
1506: * Use lookupNamespaceURI(null) to lookup the default namespace
1507: *
1508: * @param namespaceURI
1509: * @return th URI for the namespace
1510: * @since DOM Level 3
1511: */
1512: public String lookupNamespaceURI(String specifiedPrefix) {
1513: short type = this .getNodeType();
1514: switch (type) {
1515: case Node.ELEMENT_NODE: {
1516:
1517: String namespace = this .getNamespaceURI();
1518: String prefix = this .getPrefix();
1519: if (namespace != null) {
1520: // REVISIT: is it possible that prefix is empty string?
1521: if (specifiedPrefix == null
1522: && prefix == specifiedPrefix) {
1523: // looking for default namespace
1524: return namespace;
1525: } else if (prefix != null
1526: && prefix.equals(specifiedPrefix)) {
1527: // non default namespace
1528: return namespace;
1529: }
1530: }
1531: if (this .hasAttributes()) {
1532: NamedNodeMap map = this .getAttributes();
1533: int length = map.getLength();
1534: for (int i = 0; i < length; i++) {
1535: Node attr = map.item(i);
1536: String attrPrefix = attr.getPrefix();
1537: String value = attr.getNodeValue();
1538: namespace = attr.getNamespaceURI();
1539: if (namespace != null
1540: && namespace
1541: .equals("http://www.w3.org/2000/xmlns/")) {
1542: // at this point we are dealing with DOM Level 2 nodes only
1543: if (specifiedPrefix == null
1544: && attr.getNodeName().equals("xmlns")) {
1545: // default namespace
1546: return value;
1547: } else if (attrPrefix != null
1548: && attrPrefix.equals("xmlns")
1549: && attr.getLocalName().equals(
1550: specifiedPrefix)) {
1551: // non default namespace
1552: return value;
1553: }
1554: }
1555: }
1556: }
1557: /*
1558: NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1559: if (ancestor != null) {
1560: return ancestor.lookupNamespaceURI(specifiedPrefix);
1561: }
1562: */
1563: return null;
1564: }
1565: /*
1566: case Node.DOCUMENT_NODE : {
1567: return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix) ;
1568: }
1569: */
1570: case Node.ENTITY_NODE:
1571: case Node.NOTATION_NODE:
1572: case Node.DOCUMENT_FRAGMENT_NODE:
1573: case Node.DOCUMENT_TYPE_NODE:
1574: // type is unknown
1575: return null;
1576: case Node.ATTRIBUTE_NODE: {
1577: if (this .getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
1578: return getOwnerElement().lookupNamespaceURI(
1579: specifiedPrefix);
1580: }
1581: return null;
1582: }
1583: default: {
1584: /*
1585: NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1586: if (ancestor != null) {
1587: return ancestor.lookupNamespaceURI(specifiedPrefix);
1588: }
1589: */
1590: return null;
1591: }
1592:
1593: }
1594: }
1595:
1596: /**
1597: * DOM Level 3:
1598: * This method checks if the specified <code>namespaceURI</code> is the
1599: * default namespace or not.
1600: * @param namespaceURI The namespace URI to look for.
1601: * @return <code>true</code> if the specified <code>namespaceURI</code>
1602: * is the default namespace, <code>false</code> otherwise.
1603: * @since DOM Level 3
1604: */
1605: public boolean isDefaultNamespace(String namespaceURI) {
1606: /*
1607: // REVISIT: remove casts when DOM L3 becomes REC.
1608: short type = this.getNodeType();
1609: switch (type) {
1610: case Node.ELEMENT_NODE: {
1611: String namespace = this.getNamespaceURI();
1612: String prefix = this.getPrefix();
1613:
1614: // REVISIT: is it possible that prefix is empty string?
1615: if (prefix == null || prefix.length() == 0) {
1616: if (namespaceURI == null) {
1617: return (namespace == namespaceURI);
1618: }
1619: return namespaceURI.equals(namespace);
1620: }
1621: if (this.hasAttributes()) {
1622: ElementImpl elem = (ElementImpl)this;
1623: NodeImpl attr = (NodeImpl)elem.getAttributeNodeNS("http://www.w3.org/2000/xmlns/", "xmlns");
1624: if (attr != null) {
1625: String value = attr.getNodeValue();
1626: if (namespaceURI == null) {
1627: return (namespace == value);
1628: }
1629: return namespaceURI.equals(value);
1630: }
1631: }
1632:
1633: NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1634: if (ancestor != null) {
1635: return ancestor.isDefaultNamespace(namespaceURI);
1636: }
1637: return false;
1638: }
1639: case Node.DOCUMENT_NODE:{
1640: return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI);
1641: }
1642:
1643: case Node.ENTITY_NODE :
1644: case Node.NOTATION_NODE:
1645: case Node.DOCUMENT_FRAGMENT_NODE:
1646: case Node.DOCUMENT_TYPE_NODE:
1647: // type is unknown
1648: return false;
1649: case Node.ATTRIBUTE_NODE:{
1650: if (this.ownerNode.getNodeType() == Node.ELEMENT_NODE) {
1651: return ownerNode.isDefaultNamespace(namespaceURI);
1652:
1653: }
1654: return false;
1655: }
1656: default:{
1657: NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1658: if (ancestor != null) {
1659: return ancestor.isDefaultNamespace(namespaceURI);
1660: }
1661: return false;
1662: }
1663:
1664: }
1665: */
1666: return false;
1667: }
1668:
1669: /**
1670: * DOM Level 3:
1671: * Look up the prefix associated to the given namespace URI, starting from this node.
1672: *
1673: * @param namespaceURI
1674: * @return the prefix for the namespace
1675: */
1676: public String lookupPrefix(String namespaceURI) {
1677:
1678: // REVISIT: When Namespaces 1.1 comes out this may not be true
1679: // Prefix can't be bound to null namespace
1680: if (namespaceURI == null) {
1681: return null;
1682: }
1683:
1684: short type = this .getNodeType();
1685:
1686: switch (type) {
1687: /*
1688: case Node.ELEMENT_NODE: {
1689:
1690: String namespace = this.getNamespaceURI(); // to flip out children
1691: return lookupNamespacePrefix(namespaceURI, (ElementImpl)this);
1692: }
1693:
1694: case Node.DOCUMENT_NODE:{
1695: return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI);
1696: }
1697: */
1698: case Node.ENTITY_NODE:
1699: case Node.NOTATION_NODE:
1700: case Node.DOCUMENT_FRAGMENT_NODE:
1701: case Node.DOCUMENT_TYPE_NODE:
1702: // type is unknown
1703: return null;
1704: case Node.ATTRIBUTE_NODE: {
1705: if (this .getOwnerElement().getNodeType() == Node.ELEMENT_NODE) {
1706: return getOwnerElement().lookupPrefix(namespaceURI);
1707:
1708: }
1709: return null;
1710: }
1711: default: {
1712: /*
1713: NodeImpl ancestor = (NodeImpl)getElementAncestor(this);
1714: if (ancestor != null) {
1715: return ancestor.lookupPrefix(namespaceURI);
1716: }
1717: */
1718: return null;
1719: }
1720: }
1721: }
1722:
1723: /**
1724: * Returns whether this node is the same node as the given one.
1725: * <br>This method provides a way to determine whether two
1726: * <code>Node</code> references returned by the implementation reference
1727: * the same object. When two <code>Node</code> references are references
1728: * to the same object, even if through a proxy, the references may be
1729: * used completely interchangably, such that all attributes have the
1730: * same values and calling the same DOM method on either reference
1731: * always has exactly the same effect.
1732: * @param other The node to test against.
1733: * @return Returns <code>true</code> if the nodes are the same,
1734: * <code>false</code> otherwise.
1735: * @since DOM Level 3
1736: */
1737: public boolean isSameNode(Node other) {
1738: // we do not use any wrapper so the answer is obvious
1739: return this == other;
1740: }
1741:
1742: /**
1743: * This attribute returns the text content of this node and its
1744: * descendants. When it is defined to be null, setting it has no effect.
1745: * When set, any possible children this node may have are removed and
1746: * replaced by a single <code>Text</code> node containing the string
1747: * this attribute is set to. On getting, no serialization is performed,
1748: * the returned string does not contain any markup. No whitespace
1749: * normalization is performed, the returned string does not contain the
1750: * element content whitespaces . Similarly, on setting, no parsing is
1751: * performed either, the input string is taken as pure textual content.
1752: * <br>The string returned is made of the text content of this node
1753: * depending on its type, as defined below:
1754: * <table border='1'>
1755: * <tr>
1756: * <th>Node type</th>
1757: * <th>Content</th>
1758: * </tr>
1759: * <tr>
1760: * <td valign='top' rowspan='1' colspan='1'>
1761: * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
1762: * DOCUMENT_FRAGMENT_NODE</td>
1763: * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
1764: * attribute value of every child node, excluding COMMENT_NODE and
1765: * PROCESSING_INSTRUCTION_NODE nodes</td>
1766: * </tr>
1767: * <tr>
1768: * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
1769: * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
1770: * <td valign='top' rowspan='1' colspan='1'>
1771: * <code>nodeValue</code></td>
1772: * </tr>
1773: * <tr>
1774: * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
1775: * <td valign='top' rowspan='1' colspan='1'>
1776: * null</td>
1777: * </tr>
1778: * </table>
1779: * @exception DOMException
1780: * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
1781: * @exception DOMException
1782: * DOMSTRING_SIZE_ERR: Raised when it would return more characters than
1783: * fit in a <code>DOMString</code> variable on the implementation
1784: * platform.
1785: * @since DOM Level 3
1786: */
1787: public void setTextContent(String textContent) throws DOMException {
1788: setNodeValue(textContent);
1789: }
1790:
1791: /**
1792: * This attribute returns the text content of this node and its
1793: * descendants. When it is defined to be null, setting it has no effect.
1794: * When set, any possible children this node may have are removed and
1795: * replaced by a single <code>Text</code> node containing the string
1796: * this attribute is set to. On getting, no serialization is performed,
1797: * the returned string does not contain any markup. No whitespace
1798: * normalization is performed, the returned string does not contain the
1799: * element content whitespaces . Similarly, on setting, no parsing is
1800: * performed either, the input string is taken as pure textual content.
1801: * <br>The string returned is made of the text content of this node
1802: * depending on its type, as defined below:
1803: * <table border='1'>
1804: * <tr>
1805: * <th>Node type</th>
1806: * <th>Content</th>
1807: * </tr>
1808: * <tr>
1809: * <td valign='top' rowspan='1' colspan='1'>
1810: * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
1811: * DOCUMENT_FRAGMENT_NODE</td>
1812: * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code>
1813: * attribute value of every child node, excluding COMMENT_NODE and
1814: * PROCESSING_INSTRUCTION_NODE nodes</td>
1815: * </tr>
1816: * <tr>
1817: * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE,
1818: * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
1819: * <td valign='top' rowspan='1' colspan='1'>
1820: * <code>nodeValue</code></td>
1821: * </tr>
1822: * <tr>
1823: * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
1824: * <td valign='top' rowspan='1' colspan='1'>
1825: * null</td>
1826: * </tr>
1827: * </table>
1828: * @exception DOMException
1829: * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
1830: * @exception DOMException
1831: * DOMSTRING_SIZE_ERR: Raised when it would return more characters than
1832: * fit in a <code>DOMString</code> variable on the implementation
1833: * platform.
1834: * @since DOM Level 3
1835: */
1836: public String getTextContent() throws DOMException {
1837: return getNodeValue(); // overriden in some subclasses
1838: }
1839:
1840: /**
1841: * Compares a node with this node with regard to their position in the
1842: * document.
1843: * @param other The node to compare against this node.
1844: * @return Returns how the given node is positioned relatively to this
1845: * node.
1846: * @since DOM Level 3
1847: */
1848: public short compareDocumentPosition(Node other)
1849: throws DOMException {
1850: return 0;
1851: }
1852:
1853: /**
1854: * The absolute base URI of this node or <code>null</code> if undefined.
1855: * This value is computed according to . However, when the
1856: * <code>Document</code> supports the feature "HTML" , the base URI is
1857: * computed using first the value of the href attribute of the HTML BASE
1858: * element if any, and the value of the <code>documentURI</code>
1859: * attribute from the <code>Document</code> interface otherwise.
1860: * <br> When the node is an <code>Element</code>, a <code>Document</code>
1861: * or a a <code>ProcessingInstruction</code>, this attribute represents
1862: * the properties [base URI] defined in . When the node is a
1863: * <code>Notation</code>, an <code>Entity</code>, or an
1864: * <code>EntityReference</code>, this attribute represents the
1865: * properties [declaration base URI] in the . How will this be affected
1866: * by resolution of relative namespace URIs issue?It's not.Should this
1867: * only be on Document, Element, ProcessingInstruction, Entity, and
1868: * Notation nodes, according to the infoset? If not, what is it equal to
1869: * on other nodes? Null? An empty string? I think it should be the
1870: * parent's.No.Should this be read-only and computed or and actual
1871: * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and
1872: * teleconference 30 May 2001).If the base HTML element is not yet
1873: * attached to a document, does the insert change the Document.baseURI?
1874: * Yes. (F2F 26 Sep 2001)
1875: * @since DOM Level 3
1876: */
1877: public String getBaseURI() {
1878: return null;
1879: }
1880:
1881: /**
1882: * DOM Level 3
1883: * Renaming node
1884: */
1885: public Node renameNode(Node n, String namespaceURI, String name)
1886: throws DOMException {
1887: return n;
1888: }
1889:
1890: /**
1891: * DOM Level 3
1892: * Normalize document.
1893: */
1894: public void normalizeDocument() {
1895:
1896: }
1897:
1898: /**
1899: * The configuration used when <code>Document.normalizeDocument</code> is
1900: * invoked.
1901: * @since DOM Level 3
1902: */
1903: public DOMConfiguration getDomConfig() {
1904: return null;
1905: }
1906:
1907: /** DOM Level 3 feature: documentURI */
1908: protected String fDocumentURI;
1909:
1910: /**
1911: * DOM Level 3
1912: */
1913: public void setDocumentURI(String documentURI) {
1914:
1915: fDocumentURI = documentURI;
1916: }
1917:
1918: /**
1919: * DOM Level 3
1920: * The location of the document or <code>null</code> if undefined.
1921: * <br>Beware that when the <code>Document</code> supports the feature
1922: * "HTML" , the href attribute of the HTML BASE element takes precedence
1923: * over this attribute.
1924: * @since DOM Level 3
1925: */
1926: public String getDocumentURI() {
1927: return fDocumentURI;
1928: }
1929:
1930: /** DOM Level 3 feature: Document actualEncoding */
1931: protected String actualEncoding;
1932:
1933: /**
1934: * DOM Level 3
1935: * An attribute specifying the actual encoding of this document. This is
1936: * <code>null</code> otherwise.
1937: * <br> This attribute represents the property [character encoding scheme]
1938: * defined in .
1939: * @since DOM Level 3
1940: */
1941: public String getActualEncoding() {
1942: return actualEncoding;
1943: }
1944:
1945: /**
1946: * DOM Level 3
1947: * An attribute specifying the actual encoding of this document. This is
1948: * <code>null</code> otherwise.
1949: * <br> This attribute represents the property [character encoding scheme]
1950: * defined in .
1951: * @since DOM Level 3
1952: */
1953: public void setActualEncoding(String value) {
1954: actualEncoding = value;
1955: }
1956:
1957: /**
1958: * DOM Level 3
1959: */
1960: public Text replaceWholeText(String content) throws DOMException {
1961: /*
1962:
1963: if (needsSyncData()) {
1964: synchronizeData();
1965: }
1966:
1967: // make sure we can make the replacement
1968: if (!canModify(nextSibling)) {
1969: throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
1970: DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
1971: }
1972:
1973: Node parent = this.getParentNode();
1974: if (content == null || content.length() == 0) {
1975: // remove current node
1976: if (parent !=null) { // check if node in the tree
1977: parent.removeChild(this);
1978: return null;
1979: }
1980: }
1981: Text currentNode = null;
1982: if (isReadOnly()){
1983: Text newNode = this.ownerDocument().createTextNode(content);
1984: if (parent !=null) { // check if node in the tree
1985: parent.insertBefore(newNode, this);
1986: parent.removeChild(this);
1987: currentNode = newNode;
1988: } else {
1989: return newNode;
1990: }
1991: } else {
1992: this.setData(content);
1993: currentNode = this;
1994: }
1995: Node sibling = currentNode.getNextSibling();
1996: while ( sibling !=null) {
1997: parent.removeChild(sibling);
1998: sibling = currentNode.getNextSibling();
1999: }
2000:
2001: return currentNode;
2002: */
2003: return null; //Pending
2004: }
2005:
2006: /**
2007: * DOM Level 3
2008: * Returns all text of <code>Text</code> nodes logically-adjacent text
2009: * nodes to this node, concatenated in document order.
2010: * @since DOM Level 3
2011: */
2012: public String getWholeText() {
2013:
2014: /*
2015: if (needsSyncData()) {
2016: synchronizeData();
2017: }
2018: if (nextSibling == null) {
2019: return data;
2020: }
2021: StringBuffer buffer = new StringBuffer();
2022: if (data != null && data.length() != 0) {
2023: buffer.append(data);
2024: }
2025: getWholeText(nextSibling, buffer);
2026: return buffer.toString();
2027: */
2028: return null; // PENDING
2029: }
2030:
2031: /**
2032: * DOM Level 3
2033: * Returns whether this text node contains whitespace in element content,
2034: * often abusively called "ignorable whitespace".
2035: */
2036: public boolean isElementContentWhitespace() {
2037: return false;
2038: }
2039:
2040: /**
2041: * NON-DOM: set the type of this attribute to be ID type.
2042: *
2043: * @param id
2044: */
2045: public void setIdAttribute(boolean id) {
2046: //PENDING
2047: }
2048:
2049: /**
2050: * DOM Level 3: register the given attribute node as an ID attribute
2051: */
2052: public void setIdAttribute(String name, boolean makeId) {
2053: //PENDING
2054: }
2055:
2056: /**
2057: * DOM Level 3: register the given attribute node as an ID attribute
2058: */
2059: public void setIdAttributeNode(Attr at, boolean makeId) {
2060: //PENDING
2061: }
2062:
2063: /**
2064: * DOM Level 3: register the given attribute node as an ID attribute
2065: */
2066: public void setIdAttributeNS(String namespaceURI, String localName,
2067: boolean makeId) {
2068: //PENDING
2069: }
2070:
2071: public TypeInfo getSchemaTypeInfo() {
2072: return null; //PENDING
2073: }
2074:
2075: public boolean isId() {
2076: return false; //PENDING
2077: }
2078:
2079: private String xmlEncoding;
2080:
2081: public String getXmlEncoding() {
2082: return xmlEncoding;
2083: }
2084:
2085: public void setXmlEncoding(String xmlEncoding) {
2086: this .xmlEncoding = xmlEncoding;
2087: }
2088:
2089: private boolean xmlStandalone;
2090:
2091: public boolean getXmlStandalone() {
2092: return xmlStandalone;
2093: }
2094:
2095: public void setXmlStandalone(boolean xmlStandalone)
2096: throws DOMException {
2097: this .xmlStandalone = xmlStandalone;
2098: }
2099:
2100: private String xmlVersion;
2101:
2102: public String getXmlVersion() {
2103: return xmlVersion;
2104: }
2105:
2106: public void setXmlVersion(String xmlVersion) throws DOMException {
2107: this.xmlVersion = xmlVersion;
2108: }
2109: }
|