Source Code Cross Referenced for XmlNode.java in  » Scripting » rhino » org » mozilla » javascript » xmlimpl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » rhino » org.mozilla.javascript.xmlimpl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* ***** BEGIN LICENSE BLOCK *****
002:         * Version: MPL 1.1/GPL 2.0
003:         *
004:         * The contents of this file are subject to the Mozilla Public License Version
005:         * 1.1 (the "License"); you may not use this file except in compliance with
006:         * the License. You may obtain a copy of the License at
007:         * http://www.mozilla.org/MPL/
008:         *
009:         * Software distributed under the License is distributed on an "AS IS" basis,
010:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011:         * for the specific language governing rights and limitations under the
012:         * License.
013:         *
014:         * The Original Code is Rhino DOM-only E4X implementation.
015:         *
016:         * The Initial Developer of the Original Code is
017:         * David P. Caldwell.
018:         * Portions created by David P. Caldwell are Copyright (C)
019:         * 2007 David P. Caldwell. All Rights Reserved.
020:         *
021:         *
022:         * Contributor(s):
023:         *   David P. Caldwell <inonit@inonit.com>
024:         *
025:         * Alternatively, the contents of this file may be used under the terms of
026:         * the GNU General Public License Version 2 or later (the "GPL"), in which
027:         * case the provisions of the GPL are applicable instead of those above. If
028:         * you wish to allow use of your version of this file only under the terms of
029:         * the GPL and not to allow others to use your version of this file under the
030:         * MPL, indicate your decision by deleting the provisions above and replacing
031:         * them with the notice and other provisions required by the GPL. If you do
032:         * not delete the provisions above, a recipient may use your version of this
033:         * file under either the MPL or the GPL.
034:         *
035:         * ***** END LICENSE BLOCK ***** */
036:
037:        package org.mozilla.javascript.xmlimpl;
038:
039:        import java.util.*;
040:
041:        import org.w3c.dom.*;
042:
043:        import org.mozilla.javascript.*;
044:
045:        //    Disambiguate with org.mozilla.javascript
046:        import org.w3c.dom.Node;
047:
048:        class XmlNode {
049:            private static final String XML_NAMESPACES_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
050:
051:            private static final String USER_DATA_XMLNODE_KEY = XmlNode.class
052:                    .getName();
053:
054:            private static final boolean DOM_LEVEL_3 = true;
055:
056:            private static XmlNode getUserData(Node node) {
057:                if (DOM_LEVEL_3) {
058:                    return (XmlNode) node.getUserData(USER_DATA_XMLNODE_KEY);
059:                }
060:                return null;
061:            }
062:
063:            private static void setUserData(Node node, XmlNode wrap) {
064:                if (DOM_LEVEL_3) {
065:                    node.setUserData(USER_DATA_XMLNODE_KEY, wrap, wrap.events);
066:                }
067:            }
068:
069:            private static XmlNode createImpl(Node node) {
070:                if (node instanceof  Document)
071:                    throw new IllegalArgumentException();
072:                XmlNode rv = null;
073:                if (getUserData(node) == null) {
074:                    rv = new XmlNode();
075:                    rv.dom = node;
076:                    setUserData(node, rv);
077:                } else {
078:                    rv = getUserData(node);
079:                }
080:                return rv;
081:            }
082:
083:            static XmlNode newElementWithText(XmlProcessor processor,
084:                    XmlNode reference, XmlNode.QName qname, String value) {
085:                if (reference instanceof  org.w3c.dom.Document)
086:                    throw new IllegalArgumentException(
087:                            "Cannot use Document node as reference");
088:                Document document = null;
089:                if (reference != null) {
090:                    document = reference.dom.getOwnerDocument();
091:                } else {
092:                    document = processor.newDocument();
093:                }
094:                Node referenceDom = (reference != null) ? reference.dom : null;
095:                Element e = document.createElementNS(qname.getUri(), qname
096:                        .qualify(referenceDom));
097:                if (value != null) {
098:                    e.appendChild(document.createTextNode(value));
099:                }
100:                return XmlNode.createImpl(e);
101:            }
102:
103:            static XmlNode createText(XmlProcessor processor, String value) {
104:                return createImpl(processor.newDocument().createTextNode(value));
105:            }
106:
107:            static XmlNode createElementFromNode(Node node) {
108:                if (node instanceof  Document)
109:                    node = ((Document) node).getDocumentElement();
110:                return createImpl(node);
111:            }
112:
113:            static XmlNode createElement(XmlProcessor processor,
114:                    String namespaceUri, String xml)
115:                    throws org.xml.sax.SAXException {
116:                return createImpl(processor.toXml(namespaceUri, xml));
117:            }
118:
119:            static XmlNode createEmpty(XmlProcessor processor) {
120:                return createText(processor, "");
121:            }
122:
123:            private static XmlNode copy(XmlNode other) {
124:                return createImpl(other.dom.cloneNode(true));
125:            }
126:
127:            private static final long serialVersionUID = 1L;
128:
129:            private UserDataHandler events = new UserDataHandler() {
130:                public void handle(short operation, String key, Object data,
131:                        Node src, Node dest) {
132:                }
133:            };
134:
135:            private Node dom;
136:
137:            private XML xml;
138:
139:            private XmlNode() {
140:            }
141:
142:            String debug() {
143:                XmlProcessor raw = new XmlProcessor();
144:                raw.setIgnoreComments(false);
145:                raw.setIgnoreProcessingInstructions(false);
146:                raw.setIgnoreWhitespace(false);
147:                raw.setPrettyPrinting(false);
148:                return raw.ecmaToXmlString(this .dom);
149:            }
150:
151:            public String toString() {
152:                return "XmlNode: type=" + dom.getNodeType() + " dom="
153:                        + dom.toString();
154:            }
155:
156:            XML getXml() {
157:                return xml;
158:            }
159:
160:            void setXml(XML xml) {
161:                this .xml = xml;
162:            }
163:
164:            int getChildCount() {
165:                return this .dom.getChildNodes().getLength();
166:            }
167:
168:            XmlNode parent() {
169:                Node domParent = dom.getParentNode();
170:                if (domParent instanceof  Document)
171:                    return null;
172:                if (domParent == null)
173:                    return null;
174:                return createImpl(domParent);
175:            }
176:
177:            int getChildIndex() {
178:                if (this .isAttributeType())
179:                    return -1;
180:                if (parent() == null)
181:                    return -1;
182:                org.w3c.dom.NodeList siblings = this .dom.getParentNode()
183:                        .getChildNodes();
184:                for (int i = 0; i < siblings.getLength(); i++) {
185:                    if (siblings.item(i) == dom) {
186:                        return i;
187:                    }
188:                }
189:                //    Either the parent is -1 or one of the this node's parent's children is this node.
190:                throw new RuntimeException("Unreachable.");
191:            }
192:
193:            void removeChild(int index) {
194:                this .dom.removeChild(this .dom.getChildNodes().item(index));
195:            }
196:
197:            String toXmlString(XmlProcessor processor) {
198:                return processor.ecmaToXmlString(this .dom);
199:            }
200:
201:            String ecmaValue() {
202:                //    TODO    See ECMA 357 Section 9.1
203:                if (isTextType()) {
204:                    return ((org.w3c.dom.Text) dom).getData();
205:                } else if (isAttributeType()) {
206:                    return ((org.w3c.dom.Attr) dom).getValue();
207:                } else if (isProcessingInstructionType()) {
208:                    return ((org.w3c.dom.ProcessingInstruction) dom).getData();
209:                } else if (isCommentType()) {
210:                    return ((org.w3c.dom.Comment) dom).getNodeValue();
211:                } else if (isElementType()) {
212:                    throw new RuntimeException(
213:                            "Unimplemented ecmaValue() for elements.");
214:                } else {
215:                    throw new RuntimeException("Unimplemented for node " + dom);
216:                }
217:            }
218:
219:            void deleteMe() {
220:                if (dom instanceof  Attr) {
221:                    Attr attr = (Attr) this .dom;
222:                    attr.getOwnerElement().getAttributes().removeNamedItemNS(
223:                            attr.getNamespaceURI(), attr.getLocalName());
224:                } else {
225:                    if (this .dom.getParentNode() != null) {
226:                        this .dom.getParentNode().removeChild(this .dom);
227:                    } else {
228:                        //    This case can be exercised at least when executing the regression
229:                        //    tests under https://bugzilla.mozilla.org/show_bug.cgi?id=354145
230:                    }
231:                }
232:            }
233:
234:            void normalize() {
235:                this .dom.normalize();
236:            }
237:
238:            void insertChildAt(int index, XmlNode node) {
239:                Node parent = this .dom;
240:                Node child = parent.getOwnerDocument().importNode(node.dom,
241:                        true);
242:                if (parent.getChildNodes().getLength() < index) {
243:                    //    TODO    Check ECMA for what happens here
244:                    throw new IllegalArgumentException("index=" + index
245:                            + " length=" + parent.getChildNodes().getLength());
246:                }
247:                if (parent.getChildNodes().getLength() == index) {
248:                    parent.appendChild(child);
249:                } else {
250:                    parent.insertBefore(child, parent.getChildNodes().item(
251:                            index));
252:                }
253:            }
254:
255:            void insertChildrenAt(int index, XmlNode[] nodes) {
256:                for (int i = 0; i < nodes.length; i++) {
257:                    insertChildAt(index + i, nodes[i]);
258:                }
259:            }
260:
261:            XmlNode getChild(int index) {
262:                Node child = dom.getChildNodes().item(index);
263:                return createImpl(child);
264:            }
265:
266:            //    Helper method for XML.hasSimpleContent()
267:            boolean hasChildElement() {
268:                org.w3c.dom.NodeList nodes = this .dom.getChildNodes();
269:                for (int i = 0; i < nodes.getLength(); i++) {
270:                    if (nodes.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE)
271:                        return true;
272:                }
273:                return false;
274:            }
275:
276:            boolean isSameNode(XmlNode other) {
277:                //    TODO    May need to be changed if we allow XmlNode to refer to several Node objects
278:                return this .dom == other.dom;
279:            }
280:
281:            private String toUri(String ns) {
282:                return (ns == null) ? "" : ns;
283:            }
284:
285:            private void addNamespaces(Namespaces rv, Element element) {
286:                if (element == null)
287:                    throw new RuntimeException("element must not be null");
288:                String myDefaultNamespace = toUri(element
289:                        .lookupNamespaceURI(null));
290:                String parentDefaultNamespace = "";
291:                if (element.getParentNode() != null) {
292:                    parentDefaultNamespace = toUri(element.getParentNode()
293:                            .lookupNamespaceURI(null));
294:                }
295:                if (!myDefaultNamespace.equals(parentDefaultNamespace)
296:                        || !(element.getParentNode() instanceof  Element)) {
297:                    rv.declare(Namespace.create("", myDefaultNamespace));
298:                }
299:                NamedNodeMap attributes = element.getAttributes();
300:                for (int i = 0; i < attributes.getLength(); i++) {
301:                    Attr attr = (Attr) attributes.item(i);
302:                    if (attr.getPrefix() != null
303:                            && attr.getPrefix().equals("xmlns")) {
304:                        rv.declare(Namespace.create(attr.getLocalName(), attr
305:                                .getValue()));
306:                    }
307:                }
308:            }
309:
310:            private Namespaces getAllNamespaces() {
311:                Namespaces rv = new Namespaces();
312:
313:                Node target = this .dom;
314:                if (target instanceof  Attr) {
315:                    target = ((Attr) target).getOwnerElement();
316:                }
317:                while (target != null) {
318:                    if (target instanceof  Element) {
319:                        addNamespaces(rv, (Element) target);
320:                    }
321:                    target = target.getParentNode();
322:                }
323:                //    Fallback in case no namespace was declared
324:                rv.declare(Namespace.create("", ""));
325:                return rv;
326:            }
327:
328:            Namespace[] getInScopeNamespaces() {
329:                Namespaces rv = getAllNamespaces();
330:                return rv.getNamespaces();
331:            }
332:
333:            Namespace[] getNamespaceDeclarations() {
334:                //    ECMA357 13.4.4.24
335:                if (this .dom instanceof  Element) {
336:                    Namespaces rv = new Namespaces();
337:                    addNamespaces(rv, (Element) this .dom);
338:                    return rv.getNamespaces();
339:                } else {
340:                    return new Namespace[0];
341:                }
342:            }
343:
344:            Namespace getNamespaceDeclaration(String prefix) {
345:                if (prefix.equals("") && dom instanceof  Attr) {
346:                    //    Default namespaces do not apply to attributes; see XML Namespaces section 5.2
347:                    return Namespace.create("", "");
348:                }
349:                Namespaces rv = getAllNamespaces();
350:                return rv.getNamespace(prefix);
351:            }
352:
353:            Namespace getNamespaceDeclaration() {
354:                if (dom.getPrefix() == null)
355:                    return getNamespaceDeclaration("");
356:                return getNamespaceDeclaration(dom.getPrefix());
357:            }
358:
359:            private static class Namespaces {
360:                private HashMap map = new HashMap();
361:                private HashMap uriToPrefix = new HashMap();
362:
363:                Namespaces() {
364:                }
365:
366:                void declare(Namespace n) {
367:                    if (map.get(n.prefix) == null) {
368:                        map.put(n.prefix, n.uri);
369:                    }
370:                    //    TODO    I think this is analogous to the other way, but have not really thought it through ... should local scope
371:                    //            matter more than outer scope?
372:                    if (uriToPrefix.get(n.uri) == null) {
373:                        uriToPrefix.put(n.uri, n.prefix);
374:                    }
375:                }
376:
377:                Namespace getNamespaceByUri(String uri) {
378:                    if (uriToPrefix.get(uri) == null)
379:                        return null;
380:                    return Namespace.create(uri, (String) uriToPrefix.get(uri));
381:                }
382:
383:                Namespace getNamespace(String prefix) {
384:                    if (map.get(prefix) == null)
385:                        return null;
386:                    return Namespace.create(prefix, (String) map.get(prefix));
387:                }
388:
389:                Namespace[] getNamespaces() {
390:                    Iterator i = map.keySet().iterator();
391:                    ArrayList rv = new ArrayList();
392:                    while (i.hasNext()) {
393:                        String prefix = (String) i.next();
394:                        String uri = (String) map.get(prefix);
395:                        Namespace n = Namespace.create(prefix, uri);
396:                        if (!n.isEmpty()) {
397:                            rv.add(n);
398:                        }
399:                    }
400:                    return (Namespace[]) rv.toArray(new Namespace[0]);
401:                }
402:            }
403:
404:            final XmlNode copy() {
405:                return copy(this );
406:            }
407:
408:            //    Returns whether this node is capable of being a parent
409:            final boolean isParentType() {
410:                return isElementType();
411:            }
412:
413:            final boolean isTextType() {
414:                return dom.getNodeType() == Node.TEXT_NODE
415:                        || dom.getNodeType() == Node.CDATA_SECTION_NODE;
416:            }
417:
418:            final boolean isAttributeType() {
419:                return dom.getNodeType() == Node.ATTRIBUTE_NODE;
420:            }
421:
422:            final boolean isProcessingInstructionType() {
423:                return dom.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE;
424:            }
425:
426:            final boolean isCommentType() {
427:                return dom.getNodeType() == Node.COMMENT_NODE;
428:            }
429:
430:            final boolean isElementType() {
431:                return dom.getNodeType() == Node.ELEMENT_NODE;
432:            }
433:
434:            final void renameNode(QName qname) {
435:                this .dom = dom.getOwnerDocument().renameNode(dom,
436:                        qname.getUri(), qname.qualify(dom));
437:            }
438:
439:            void invalidateNamespacePrefix() {
440:                if (!(dom instanceof  Element))
441:                    throw new IllegalStateException();
442:                String prefix = this .dom.getPrefix();
443:                QName after = QName.create(this .dom.getNamespaceURI(), this .dom
444:                        .getLocalName(), null);
445:                renameNode(after);
446:                NamedNodeMap attrs = this .dom.getAttributes();
447:                for (int i = 0; i < attrs.getLength(); i++) {
448:                    if (attrs.item(i).getPrefix().equals(prefix)) {
449:                        createImpl(attrs.item(i)).renameNode(
450:                                QName.create(attrs.item(i).getNamespaceURI(),
451:                                        attrs.item(i).getLocalName(), null));
452:                    }
453:                }
454:            }
455:
456:            private void declareNamespace(Element e, String prefix, String uri) {
457:                if (prefix.length() > 0) {
458:                    e.setAttributeNS(XML_NAMESPACES_NAMESPACE_URI, "xmlns:"
459:                            + prefix, uri);
460:                } else {
461:                    e.setAttribute("xmlns", uri);
462:                }
463:            }
464:
465:            void declareNamespace(String prefix, String uri) {
466:                if (!(dom instanceof  Element))
467:                    throw new IllegalStateException();
468:                if (dom.lookupNamespaceURI(uri) != null
469:                        && dom.lookupNamespaceURI(uri).equals(prefix)) {
470:                    //    do nothing
471:                } else {
472:                    Element e = (Element) dom;
473:                    declareNamespace(e, prefix, uri);
474:                }
475:            }
476:
477:            private Namespace getDefaultNamespace() {
478:                String prefix = "";
479:                String uri = (dom.lookupNamespaceURI(null) == null) ? "" : dom
480:                        .lookupNamespaceURI(null);
481:                return Namespace.create(prefix, uri);
482:            }
483:
484:            private String getExistingPrefixFor(Namespace namespace) {
485:                if (getDefaultNamespace().getUri().equals(namespace.getUri())) {
486:                    return "";
487:                }
488:                return dom.lookupPrefix(namespace.getUri());
489:            }
490:
491:            private Namespace getNodeNamespace() {
492:                String uri = dom.getNamespaceURI();
493:                String prefix = dom.getPrefix();
494:                if (uri == null)
495:                    uri = "";
496:                if (prefix == null)
497:                    prefix = "";
498:                return Namespace.create(prefix, uri);
499:            }
500:
501:            Namespace getNamespace() {
502:                return getNodeNamespace();
503:            }
504:
505:            void removeNamespace(Namespace namespace) {
506:                Namespace current = getNodeNamespace();
507:
508:                //    Do not remove in-use namespace
509:                if (namespace.is(current))
510:                    return;
511:                NamedNodeMap attrs = this .dom.getAttributes();
512:                for (int i = 0; i < attrs.getLength(); i++) {
513:                    XmlNode attr = XmlNode.createImpl(attrs.item(i));
514:                    if (namespace.is(attr.getNodeNamespace()))
515:                        return;
516:                }
517:
518:                //    TODO    I must confess I am not sure I understand the spec fully.  See ECMA357 13.4.4.31
519:                String existingPrefix = getExistingPrefixFor(namespace);
520:                if (existingPrefix != null) {
521:                    if (namespace.isUnspecifiedPrefix()) {
522:                        //    we should remove any namespace with this URI from scope; we do this by declaring a namespace with the same
523:                        //    prefix as the existing prefix and setting its URI to the default namespace
524:                        declareNamespace(existingPrefix, getDefaultNamespace()
525:                                .getUri());
526:                    } else {
527:                        if (existingPrefix.equals(namespace.getPrefix())) {
528:                            declareNamespace(existingPrefix,
529:                                    getDefaultNamespace().getUri());
530:                        }
531:                    }
532:                } else {
533:                    //    the argument namespace is not declared in this scope, so do nothing.
534:                }
535:            }
536:
537:            private void setProcessingInstructionName(String localName) {
538:                org.w3c.dom.ProcessingInstruction pi = (ProcessingInstruction) this .dom;
539:                //    We cannot set the node name; Document.renameNode() only supports elements and attributes.  So we replace it
540:                pi.getParentNode().replaceChild(
541:                        pi,
542:                        pi.getOwnerDocument().createProcessingInstruction(
543:                                localName, pi.getData()));
544:            }
545:
546:            final void setLocalName(String localName) {
547:                if (dom instanceof  ProcessingInstruction) {
548:                    setProcessingInstructionName(localName);
549:                } else {
550:                    String prefix = dom.getPrefix();
551:                    if (prefix == null)
552:                        prefix = "";
553:                    this .dom = dom.getOwnerDocument().renameNode(dom,
554:                            dom.getNamespaceURI(),
555:                            QName.qualify(prefix, localName));
556:                }
557:            }
558:
559:            final QName getQname() {
560:                String uri = (dom.getNamespaceURI()) == null ? "" : dom
561:                        .getNamespaceURI();
562:                String prefix = (dom.getPrefix() == null) ? "" : dom
563:                        .getPrefix();
564:                return QName.create(uri, dom.getLocalName(), prefix);
565:            }
566:
567:            void addMatchingChildren(XMLList result, XmlNode.Filter filter) {
568:                Node node = this .dom;
569:                NodeList children = node.getChildNodes();
570:                for (int i = 0; i < children.getLength(); i++) {
571:                    Node childnode = children.item(i);
572:                    XmlNode child = XmlNode.createImpl(childnode);
573:                    if (filter.accept(childnode)) {
574:                        result.addToList(child);
575:                    }
576:                }
577:            }
578:
579:            XmlNode[] getMatchingChildren(Filter filter) {
580:                ArrayList rv = new ArrayList();
581:                NodeList nodes = this .dom.getChildNodes();
582:                for (int i = 0; i < nodes.getLength(); i++) {
583:                    Node node = nodes.item(i);
584:                    if (filter.accept(node)) {
585:                        rv.add(createImpl(node));
586:                    }
587:                }
588:                return (XmlNode[]) rv.toArray(new XmlNode[0]);
589:            }
590:
591:            XmlNode[] getAttributes() {
592:                NamedNodeMap attrs = this .dom.getAttributes();
593:                //    TODO    Or could make callers handle null?
594:                if (attrs == null)
595:                    throw new IllegalStateException("Must be element.");
596:                XmlNode[] rv = new XmlNode[attrs.getLength()];
597:                for (int i = 0; i < attrs.getLength(); i++) {
598:                    rv[i] = createImpl(attrs.item(i));
599:                }
600:                return rv;
601:            }
602:
603:            String getAttributeValue() {
604:                return ((Attr) dom).getValue();
605:            }
606:
607:            void setAttribute(QName name, String value) {
608:                if (!(dom instanceof  Element))
609:                    throw new IllegalStateException(
610:                            "Can only set attribute on elements.");
611:                name.setAttribute((Element) dom, value);
612:            }
613:
614:            void replaceWith(XmlNode other) {
615:                Node replacement = other.dom;
616:                if (replacement.getOwnerDocument() != this .dom
617:                        .getOwnerDocument()) {
618:                    replacement = this .dom.getOwnerDocument().importNode(
619:                            replacement, true);
620:                }
621:                this .dom.getParentNode().replaceChild(replacement, this .dom);
622:            }
623:
624:            String ecmaToXMLString(XmlProcessor processor) {
625:                if (this .isElementType()) {
626:                    Element copy = (Element) this .dom.cloneNode(true);
627:                    Namespace[] inScope = this .getInScopeNamespaces();
628:                    for (int i = 0; i < inScope.length; i++) {
629:                        declareNamespace(copy, inScope[i].getPrefix(),
630:                                inScope[i].getUri());
631:                    }
632:                    return processor.ecmaToXmlString(copy);
633:                } else {
634:                    return processor.ecmaToXmlString(dom);
635:                }
636:            }
637:
638:            static class Namespace {
639:                static Namespace create(String prefix, String uri) {
640:                    if (prefix == null)
641:                        throw new IllegalArgumentException(
642:                                "Empty string represents default namespace prefix");
643:                    if (uri == null)
644:                        throw new IllegalArgumentException(
645:                                "Namespace may not lack a URI");
646:                    Namespace rv = new Namespace();
647:                    rv.prefix = prefix;
648:                    rv.uri = uri;
649:                    return rv;
650:                }
651:
652:                static Namespace create(String uri) {
653:                    Namespace rv = new Namespace();
654:                    rv.uri = uri;
655:                    return rv;
656:                }
657:
658:                static final Namespace GLOBAL = create("", "");
659:
660:                private String prefix;
661:                private String uri;
662:
663:                private Namespace() {
664:                }
665:
666:                public String toString() {
667:                    if (prefix == null)
668:                        return "XmlNode.Namespace [" + uri + "]";
669:                    return "XmlNode.Namespace [" + prefix + "{" + uri + "}]";
670:                }
671:
672:                boolean isUnspecifiedPrefix() {
673:                    return prefix == null;
674:                }
675:
676:                boolean is(Namespace other) {
677:                    return this .prefix != null && other.prefix != null
678:                            && this .prefix.equals(other.prefix)
679:                            && this .uri.equals(other.uri);
680:                }
681:
682:                boolean isEmpty() {
683:                    return prefix != null && prefix.equals("")
684:                            && uri.equals("");
685:                }
686:
687:                boolean isDefault() {
688:                    return prefix != null && prefix.equals("");
689:                }
690:
691:                boolean isGlobal() {
692:                    return uri != null && uri.equals("");
693:                }
694:
695:                //    Called by QName
696:                //    TODO    Move functionality from QName lookupPrefix to here
697:                private void setPrefix(String prefix) {
698:                    if (prefix == null)
699:                        throw new IllegalArgumentException();
700:                    this .prefix = prefix;
701:                }
702:
703:                String getPrefix() {
704:                    return prefix;
705:                }
706:
707:                String getUri() {
708:                    return uri;
709:                }
710:            }
711:
712:            //    TODO    Where is this class used?  No longer using it in QName implementation
713:            static class QName {
714:                static QName create(Namespace namespace, String localName) {
715:                    //    A null namespace indicates a wild-card match for any namespace
716:                    //    A null localName indicates "*" from the point of view of ECMA357
717:                    if (localName != null && localName.equals("*"))
718:                        throw new RuntimeException("* is not valid localName");
719:                    QName rv = new QName();
720:                    rv.namespace = namespace;
721:                    rv.localName = localName;
722:                    return rv;
723:                }
724:
725:                /** @deprecated */
726:                static QName create(String uri, String localName, String prefix) {
727:                    return create(Namespace.create(prefix, uri), localName);
728:                }
729:
730:                static String qualify(String prefix, String localName) {
731:                    if (prefix == null)
732:                        throw new IllegalArgumentException(
733:                                "prefix must not be null");
734:                    if (prefix.length() > 0)
735:                        return prefix + ":" + localName;
736:                    return localName;
737:                }
738:
739:                private Namespace namespace;
740:                private String localName;
741:
742:                private QName() {
743:                }
744:
745:                public String toString() {
746:                    return "XmlNode.QName [" + localName + "," + namespace
747:                            + "]";
748:                }
749:
750:                private boolean equals(String one, String two) {
751:                    if (one == null && two == null)
752:                        return true;
753:                    if (one == null || two == null)
754:                        return false;
755:                    return one.equals(two);
756:                }
757:
758:                private boolean namespacesEqual(Namespace one, Namespace two) {
759:                    if (one == null && two == null)
760:                        return true;
761:                    if (one == null || two == null)
762:                        return false;
763:                    return equals(one.getUri(), two.getUri());
764:                }
765:
766:                final boolean isEqualTo(QName other) {
767:                    if (!namespacesEqual(this .namespace, other.namespace))
768:                        return false;
769:                    if (!equals(this .localName, other.localName))
770:                        return false;
771:                    return true;
772:                }
773:
774:                void lookupPrefix(org.w3c.dom.Node node) {
775:                    if (node == null)
776:                        throw new IllegalArgumentException(
777:                                "node must not be null");
778:                    String prefix = node.lookupPrefix(namespace.getUri());
779:                    if (prefix == null) {
780:                        //    check to see if we match the default namespace
781:                        String defaultNamespace = node.lookupNamespaceURI(null);
782:                        if (defaultNamespace == null)
783:                            defaultNamespace = "";
784:                        String nodeNamespace = namespace.getUri();
785:                        if (nodeNamespace.equals(defaultNamespace)) {
786:                            prefix = "";
787:                        }
788:                    }
789:                    int i = 0;
790:                    while (prefix == null) {
791:                        String generatedPrefix = "e4x_" + i++;
792:                        String generatedUri = node
793:                                .lookupNamespaceURI(generatedPrefix);
794:                        if (generatedUri == null) {
795:                            prefix = generatedPrefix;
796:                            org.w3c.dom.Node top = node;
797:                            while (top.getParentNode() != null
798:                                    && top.getParentNode() instanceof  org.w3c.dom.Element) {
799:                                top = top.getParentNode();
800:                            }
801:                            ((org.w3c.dom.Element) top).setAttributeNS(
802:                                    "http://www.w3.org/2000/xmlns/", "xmlns:"
803:                                            + prefix, namespace.getUri());
804:                        }
805:                    }
806:                    namespace.setPrefix(prefix);
807:                }
808:
809:                String qualify(org.w3c.dom.Node node) {
810:                    if (namespace.getPrefix() == null) {
811:                        if (node != null) {
812:                            lookupPrefix(node);
813:                        } else {
814:                            if (namespace.getUri().equals("")) {
815:                                namespace.setPrefix("");
816:                            } else {
817:                                //    TODO    I am not sure this is right, but if we are creating a standalone node, I think we can set the
818:                                //            default namespace on the node itself and not worry about setting a prefix for that namespace.
819:                                namespace.setPrefix("");
820:                            }
821:                        }
822:                    }
823:                    return qualify(namespace.getPrefix(), localName);
824:                }
825:
826:                void setAttribute(org.w3c.dom.Element element, String value) {
827:                    if (namespace.getPrefix() == null)
828:                        lookupPrefix(element);
829:                    element.setAttributeNS(namespace.getUri(), qualify(
830:                            namespace.getPrefix(), localName), value);
831:                }
832:
833:                /** @deprecated Use getNamespace() */
834:                String getUri() {
835:                    return namespace.getUri();
836:                }
837:
838:                /** @deprecated Use getNamespace() */
839:                String getPrefix() {
840:                    return namespace.getPrefix();
841:                }
842:
843:                Namespace getNamespace() {
844:                    return namespace;
845:                }
846:
847:                String getLocalName() {
848:                    return localName;
849:                }
850:            }
851:
852:            static class List {
853:                private java.util.Vector v;
854:
855:                List() {
856:                    v = new java.util.Vector();
857:                }
858:
859:                private void _add(XmlNode n) {
860:                    v.add(n);
861:                }
862:
863:                XmlNode item(int index) {
864:                    return (XmlNode) (v.get(index));
865:                }
866:
867:                void remove(int index) {
868:                    v.remove(index);
869:                }
870:
871:                void add(List other) {
872:                    for (int i = 0; i < other.length(); i++) {
873:                        _add(other.item(i));
874:                    }
875:                }
876:
877:                void add(List from, int startInclusive, int endExclusive) {
878:                    for (int i = startInclusive; i < endExclusive; i++) {
879:                        _add(from.item(i));
880:                    }
881:                }
882:
883:                void add(XmlNode node) {
884:                    _add(node);
885:                }
886:
887:                /** @deprecated */
888:                void add(XML xml) {
889:                    _add(xml.getAnnotation());
890:                }
891:
892:                /** @deprecated */
893:                void addToList(Object toAdd) {
894:                    if (toAdd instanceof  Undefined) {
895:                        // Missing argument do nothing...
896:                        return;
897:                    }
898:
899:                    if (toAdd instanceof  XMLList) {
900:                        XMLList xmlSrc = (XMLList) toAdd;
901:                        for (int i = 0; i < xmlSrc.length(); i++) {
902:                            this ._add((xmlSrc.item(i)).getAnnotation());
903:                        }
904:                    } else if (toAdd instanceof  XML) {
905:                        this ._add(((XML) (toAdd)).getAnnotation());
906:                    } else if (toAdd instanceof  XmlNode) {
907:                        this ._add((XmlNode) toAdd);
908:                    }
909:                }
910:
911:                int length() {
912:                    return v.size();
913:                }
914:            }
915:
916:            static abstract class Filter {
917:                static final Filter COMMENT = new Filter() {
918:                    boolean accept(Node node) {
919:                        return node.getNodeType() == Node.COMMENT_NODE;
920:                    }
921:                };
922:                static final Filter TEXT = new Filter() {
923:                    boolean accept(Node node) {
924:                        return node.getNodeType() == Node.TEXT_NODE;
925:                    }
926:                };
927:
928:                static Filter PROCESSING_INSTRUCTION(final XMLName name) {
929:                    return new Filter() {
930:                        boolean accept(Node node) {
931:                            if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
932:                                ProcessingInstruction pi = (ProcessingInstruction) node;
933:                                return name.matchesLocalName(pi.getTarget());
934:                            }
935:                            return false;
936:                        }
937:                    };
938:                }
939:
940:                static Filter ELEMENT = new Filter() {
941:                    boolean accept(Node node) {
942:                        return node.getNodeType() == Node.ELEMENT_NODE;
943:                    }
944:                };
945:                static Filter TRUE = new Filter() {
946:                    boolean accept(Node node) {
947:                        return true;
948:                    }
949:                };
950:
951:                abstract boolean accept(Node node);
952:            }
953:
954:            //    Support experimental Java interface
955:            org.w3c.dom.Node toDomNode() {
956:                return this.dom;
957:            }
958:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.