Source Code Cross Referenced for Element.java in  » Web-Server » Rimfaxe-Web-Server » com » rimfaxe » xml » xmlreader » 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 » Web Server » Rimfaxe Web Server » com.rimfaxe.xml.xmlreader 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.rimfaxe.xml.xmlreader;
002:
003:        import java.io.*;
004:        import java.util.*;
005:        import com.rimfaxe.xml.xmlreader.xpath.*;
006:
007:        /**
008:         A type of Node with a particular tagName that has a set of attributes and
009:         can contain other nodes as children.  An example of its form in XML in the form <PRE>
010:         &lt;tagName attr1="value1" attr2="value2">
011:         text
012:         &lt;childTag...>
013:         &lt;childTag...>
014:         text
015:         &lt;childTag...>
016:         text
017:         &lt;/tagName>
018:         </PRE>
019:        
020:
021:         <blockquote><small> Copyright (C) 2002 Hewlett-Packard Company.
022:         This file is part of Sparta, an XML Parser, DOM, and XPath library.
023:         This library is free software; you can redistribute it and/or
024:         modify it under the terms of the GNU Lesser General Public License
025:         as published by the Free Software Foundation; either version 2.1 of
026:         the License, or (at your option) any later version.  This library
027:         is distributed in the hope that it will be useful, but WITHOUT ANY
028:         WARRANTY; without even the implied warranty of MERCHANTABILITY or
029:         FITNESS FOR A PARTICULAR PURPOSE.</small></blockquote>
030:         @see <a "href="doc-files/LGPL.txt">GNU Lesser General Public License</a>
031:         @version  $Date: 2003/01/27 23:30:58 $  $Revision: 1.5 $
032:         @author Eamonn O'Brien-Strain
033:
034:
035:         @see org.w3c.dom.Element
036:         * @stereotype container
037:         */
038:        public class Element extends Node {
039:
040:            public Element(String tagName) {
041:                tagName_ = tagName;
042:            }
043:
044:            Element() {
045:            }
046:
047:            /** Create a deep clone of this Element.  It will have the tagname
048:             *  and attributes as this node.  This method will be called
049:             *  recursively to copy the while subtree of child Elements and
050:             *  Text nodes. */
051:            public Object clone() {
052:                return cloneElement(true);
053:            }
054:
055:            /** Create a shallow clone of this Element.  It will have the
056:             *  tagname and attributes as this Element but will not have child
057:             *  Elements or Nodes. */
058:            public Element cloneShallow() {
059:                return cloneElement(false);
060:            }
061:
062:            /** Create a clone of this node.  It will
063:             *  have the tagname and attributes as this node.  If deep is
064:             *  true, this method will be called recursively to copy the while
065:             *  subtree of child Elements and text nodes. */
066:            public Element cloneElement(boolean deep) {
067:                Element result = new Element(tagName_);
068:                for (Enumeration i = attributeNames_.elements(); i
069:                        .hasMoreElements();) {
070:                    String name = (String) i.nextElement();
071:                    result.setAttribute(name, (String) attributes_.get(name));
072:                }
073:                if (deep)
074:                    for (Node n = firstChild_; n != null; n = n
075:                            .getNextSibling())
076:                        result.appendChild((Node) n.clone());
077:                return result;
078:
079:            }
080:
081:            public String getTagName() {
082:                return tagName_;
083:            }
084:
085:            public void setTagName(String tagName) {
086:                tagName_ = tagName;
087:                notifyObservers();
088:            }
089:
090:            /**
091:             * @return either an Element or a Text node
092:             */
093:            public Node getFirstChild() {
094:                return firstChild_;
095:            }
096:
097:            /**
098:             * @return either an Element or a Text node
099:             */
100:            public Node getLastChild() {
101:                return lastChild_;
102:            }
103:
104:            /** Return enumeration of Strings */
105:            public Enumeration getAttributeNames() {
106:                return attributeNames_.elements();
107:            }
108:
109:            /**
110:             * @return value of attribute that has this name or null if no such attribute.
111:             */
112:            public String getAttribute(String name) {
113:                return (String) attributes_.get(name);
114:            }
115:
116:            /** @param name attribute name which must be non-null, non empty
117:                @param value attribue value.
118:                @precondition non zero-length name
119:             */
120:            public void setAttribute(String name, String value) {
121:                if (attributes_.get(name) == null)
122:                    attributeNames_.addElement(name);
123:                attributes_.put(name, value);
124:                notifyObservers();
125:            }
126:
127:            public void removeAttribute(String name) {
128:                attributes_.remove(name);
129:                attributeNames_.removeElement(name);
130:                notifyObservers();
131:            }
132:
133:            void appendChildNoChecking(Node addedChild) {
134:                Object contained = childrenSet_.get(addedChild);
135:                if (contained != null)
136:                    removeChildNoChecking(addedChild);
137:                addedChild.insertAtEndOfLinkedList(lastChild_);
138:                if (firstChild_ == null)
139:                    firstChild_ = addedChild;
140:                addedChild.setParentNode(this );
141:                children_.addElement(addedChild);
142:                childrenSet_.put(addedChild, addedChild);
143:                lastChild_ = addedChild;
144:                addedChild.setOwnerDocument(getOwnerDocument());
145:            }
146:
147:            /** Add node as child of this element, cloning node if it is this element or
148:             *  an ancestor.
149:             */
150:            public void appendChild(Node addedChild) {
151:                if (!canHaveAsDescendent(addedChild))
152:                    addedChild = (Element) addedChild.clone();
153:                appendChildNoChecking(addedChild);
154:                notifyObservers();
155:            }
156:
157:            boolean canHaveAsDescendent(Node node) {
158:                if (node == this )
159:                    return false;
160:                Element parent = getParentNode();
161:                if (parent == null)
162:                    return true;
163:                return parent.canHaveAsDescendent(node);
164:            }
165:
166:            private boolean removeChildNoChecking(Node childToRemove) {
167:                int i = 0;
168:                for (Node child = firstChild_; child != null; child = child
169:                        .getNextSibling()) {
170:                    if (child.equals(childToRemove)) {
171:
172:                        //Fix up list endpoints if necessary
173:                        if (firstChild_ == child)
174:                            firstChild_ = child.getNextSibling();
175:                        if (lastChild_ == child)
176:                            lastChild_ = child.getPreviousSibling();
177:
178:                        child.removeFromLinkedList();
179:                        child.setParentNode(null);
180:
181:                        children_.removeElementAt(i);
182:                        childrenSet_.remove(child);
183:                        child.setOwnerDocument(null);
184:
185:                        return true;
186:                    }
187:                    ++i;
188:                }
189:                return false;
190:            }
191:
192:            public void removeChild(Node childToRemove) throws DOMException {
193:                boolean found = removeChildNoChecking(childToRemove);
194:                if (!found)
195:                    throw new DOMException(DOMException.NOT_FOUND_ERR,
196:                            "Cannot find " + childToRemove + " in " + this );
197:                notifyObservers();
198:            }
199:
200:            /** Replace oldChild with newChild.
201:             *  @throws DOMException if oldChild object is not a child.
202:             *    */
203:            public void replaceChild(Element newChild, Node oldChild)
204:                    throws DOMException {
205:                replaceChild_(newChild, oldChild);
206:                notifyObservers();
207:            }
208:
209:            /** Replace oldChild with newChild.
210:             *  @throws DOMException if oldChild object is not a child.
211:             *    */
212:            public void replaceChild(Text newChild, Node oldChild)
213:                    throws DOMException {
214:                replaceChild_(newChild, oldChild);
215:                notifyObservers();
216:            }
217:
218:            private void replaceChild_(Node newChild, Node oldChild)
219:                    throws DOMException {
220:                int i = 0;
221:                for (Node child = firstChild_; child != null; child = child
222:                        .getNextSibling()) {
223:                    if (child == oldChild) {
224:
225:                        //Fix up list endpoints if necessary
226:                        if (firstChild_ == oldChild)
227:                            firstChild_ = newChild;
228:                        if (lastChild_ == oldChild)
229:                            lastChild_ = newChild;
230:
231:                        //Make oldChild's neighbouring siblings point to newChild
232:                        oldChild.replaceInLinkedList(newChild);
233:
234:                        //Fix parent pointers
235:                        newChild.setParentNode(this );
236:                        oldChild.setParentNode(null);
237:
238:                        //Update children collections
239:                        children_.setElementAt(newChild, i);
240:                        childrenSet_.remove(oldChild);
241:                        childrenSet_.put(newChild, newChild);
242:
243:                        return;
244:                    }
245:                    ++i;
246:                }
247:                throw new DOMException(DOMException.NOT_FOUND_ERR,
248:                        "Cannot find " + oldChild + " in " + this );
249:            }
250:
251:            /** Accumlate text nodes hierarchically. */
252:            void toString(Writer writer) throws IOException {
253:                for (Node i = firstChild_; i != null; i = i.getNextSibling())
254:                    i.toString(writer);
255:            }
256:
257:            /** Write XML representation to character stream. */
258:            public void toXml(Writer writer) throws IOException {
259:                writer.write("<" + tagName_);
260:                for (Enumeration i = attributeNames_.elements(); i
261:                        .hasMoreElements();) {
262:                    String name = (String) i.nextElement();
263:                    String value = (String) attributes_.get(name);
264:                    writer.write(" " + name + "=\"");
265:                    htmlEncode(writer, value);
266:                    writer.write("\"");
267:                }
268:                if (firstChild_ == null)
269:                    writer.write("/>");
270:                else {
271:                    writer.write(">");
272:                    for (Node i = firstChild_; i != null; i = i
273:                            .getNextSibling())
274:                        i.toXml(writer);
275:                    writer.write("</" + tagName_ + ">");
276:                }
277:            }
278:
279:            private XPathVisitor visitor(String xpath, boolean expectStringValue)
280:                    throws XPathException {
281:                XPath parseTree = XPath.get(xpath);
282:                if (parseTree.isStringValue() != expectStringValue) {
283:                    String msg = expectStringValue ? "evaluates to element not string"
284:                            : "evaluates to string not element";
285:                    throw new XPathException(parseTree, "\"" + parseTree
286:                            + "\" evaluates to " + msg);
287:                }
288:                return new XPathVisitor(this , parseTree);
289:            }
290:
291:            /** Select all the elements that match the relative XPath
292:                expression with respect to this element. */
293:            public Enumeration xpathSelectElements(String xpath)
294:                    throws ParseException {
295:                try {
296:
297:                    return visitor(xpath, false).getResultEnumeration();
298:
299:                } catch (XPathException e) {
300:                    throw new ParseException("XPath problem", e);
301:                }
302:            }
303:
304:            /** Select all the strings that match the relative XPath
305:                expression with respect to this element. */
306:            public Enumeration xpathSelectStrings(String xpath)
307:                    throws ParseException {
308:                try {
309:
310:                    return visitor(xpath, true).getResultEnumeration();
311:
312:                } catch (XPathException e) {
313:                    throw new ParseException("XPath problem", e);
314:                }
315:            }
316:
317:            /** Make sure this XPath exists, creating nodes if necessary,
318:             *  returning true if any nodes created.  Xpath must of the type that
319:             *  returns an element (not a string).
320:             *  */
321:            public boolean xpathEnsure(String xpath) throws ParseException {
322:                try {
323:
324:                    //Quick exit for common case
325:                    if (xpathSelectElement(xpath) != null)
326:                        return false;
327:
328:                    //Split XPath into parent steps and last step
329:                    final XPath parseTree = XPath.get(xpath);
330:                    int stepCount = 0;
331:                    for (Enumeration i = parseTree.getSteps(); i
332:                            .hasMoreElements();) {
333:                        i.nextElement();
334:                        ++stepCount;
335:                    }
336:                    Step[] parentSteps = new Step[stepCount - 1];
337:                    Enumeration i = parseTree.getSteps();
338:                    for (int j = 0; j < parentSteps.length; ++j)
339:                        parentSteps[j] = (Step) i.nextElement();
340:                    Step lastStep = (Step) i.nextElement();
341:
342:                    Element parent;
343:                    if (parentSteps.length == 0) {
344:                        parent = this ;
345:                    } else {
346:                        String parentXPath = XPath.get(parseTree.isAbsolute(),
347:                                parentSteps).toString();
348:                        xpathEnsure(parentXPath.toString()); //recursion
349:                        parent = xpathSelectElement(parentXPath);
350:                    }
351:
352:                    Element newChild = makeMatching(parent, lastStep, xpath);
353:                    parent.appendChildNoChecking(newChild);
354:                    return true;
355:
356:                } catch (XPathException e) {
357:                    throw new ParseException(xpath, e);
358:                }
359:            }
360:
361:            /** Select the first element that matches the relative XPath
362:                expression with respect to this element, or null if
363:                there is no match.
364:
365:                @todo make more efficient by short-circuiting the search.*/
366:            public Element xpathSelectElement(String xpath)
367:                    throws ParseException {
368:                try {
369:
370:                    return visitor(xpath, false).getFirstResultElement();
371:
372:                } catch (XPathException e) {
373:                    throw new ParseException("XPath problem", e);
374:                }
375:            }
376:
377:            /** Select the first element that matches the relative XPath
378:                expression with respect to this element, or null if
379:                there is no match. */
380:            public String xpathSelectString(String xpath) throws ParseException {
381:                try {
382:
383:                    return visitor(xpath, true).getFirstResultString();
384:
385:                } catch (XPathException e) {
386:                    throw new ParseException("XPath problem", e);
387:                }
388:            }
389:
390:            /** To be equal elements must have the same tagname, they must
391:             *  have the same children (applying equals recursivly) in the
392:             *  same order and they must have the same attributes in any
393:             *  order.  Elements can be equal even if they are in different
394:             *  documents, have different parents, have different siblings, or
395:             *  have different annotations.
396:             *   */
397:            public boolean equals(Object thatO) {
398:
399:                //Do cheap tests first
400:                if (this  == thatO)
401:                    return true;
402:                if (!(thatO instanceof  Element))
403:                    return false;
404:                Element that = (Element) thatO;
405:                if (!this .tagName_.equals(that.tagName_))
406:                    return false;
407:                if (this .children_.size() != that.children_.size())
408:                    return false;
409:                if (this .attributes_.size() != that.attributes_.size())
410:                    return false;
411:
412:                //Compare attributes ignoring order (we already know the
413:                //number is the same)
414:                for (Iterator i = this .attributes_.keySet().iterator(); i
415:                        .hasNext();) {
416:                    String key = (String) i.next();
417:                    String this Value = (String) this .attributes_.get(key); //non-null
418:                    String thatValue = (String) that.attributes_.get(key); //maybe null
419:                    if (!this Value.equals(thatValue))
420:                        return false;
421:                }
422:
423:                //Compare children in order (we already know the number is the same)
424:                Node this Child = this .firstChild_;
425:                Node thatChild = that.firstChild_;
426:                while (this Child != null) {
427:                    if (!this Child.equals(thatChild))
428:                        return false;
429:                    this Child = this Child.getNextSibling();
430:                    thatChild = thatChild.getNextSibling();
431:                }
432:
433:                return true;
434:            }
435:
436:            /**
437:             * @link aggregation
438:             * @label firstChild
439:             */
440:            private Node firstChild_ = null;
441:
442:            /**
443:             * @link aggregation
444:             * @label lastChild
445:             */
446:            private Node lastChild_ = null;
447:            private final Map attributes_ = new HashMap();
448:            private final Vector attributeNames_ = new Vector();
449:            /** @associates Node
450:             * @link aggregationByValue
451:             * @label children*/
452:            private final Vector children_ = new Vector();
453:            private final Map childrenSet_ = new HashMap();
454:            private String tagName_ = null;
455:
456:        }
457:
458:        // $Log: Element.java,v $
459:        // Revision 1.5  2003/01/27 23:30:58  yuhongx
460:        // Replaced Hashtable with HashMap.
461:        //
462:        // Revision 1.4  2002/12/13 23:09:24  eobrain
463:        // Fix javadoc.
464:        //
465:        // Revision 1.3  2002/12/13 18:12:17  eobrain
466:        // Fix xpathEnsure to handle case when the XPath given specifies a root node tagname that conflicts with the existing root node.  Extend xpathEnsure to work with any type of predicate.  Replace hacky string manipulation code with code that works on the XPath parse tree.
467:        //
468:        // Revision 1.2  2002/10/30 16:37:25  eobrain
469:        // Fix Element.appendChild so that it cannot create invalid loop by
470:        // adding ancestor.  No longer throw DOMException.  (WARNING: This breaks
471:        // backwards compatibility. Client code that catches or propagates
472:        // DOMException because of this call will now give a compile error.)
473:        //
474:        // Revision 1.1.1.1  2002/08/19 05:03:55  eobrain
475:        // import from HP Labs internal CVS
476:        //
477:        // Revision 1.23  2002/08/18 04:20:52  eob
478:        // Sparta no longer throws XPathException -- it throws ParseException
479:        // instead.
480:        //
481:        // Revision 1.22  2002/08/15 23:40:22  sermarti
482:        //
483:        // Revision 1.21  2002/08/15 21:29:00  eob
484:        // Constructor no longer needs documenent.
485:        //
486:        // Revision 1.20  2002/08/15 05:08:21  eob
487:        // Notify observers.
488:        //
489:        // Revision 1.19  2002/07/25 21:10:15  sermarti
490:        // Adding files that mysteriously weren't added from Sparta before.
491:        //
492:        // Revision 1.18  2002/06/21 00:25:47  eob
493:        // Make work with old JDK 1.1.*
494:        //
495:        // Revision 1.17  2002/06/15 22:16:49  eob
496:        // Comment change only.  Fix javadoc problem.
497:        //
498:        // Revision 1.16  2002/06/14 19:37:15  eob
499:        // Make toString of Node do the same as in XSLT -- recursive
500:        // concatenation of all text in text nodes.
501:        //
502:        // Revision 1.15  2002/05/23 21:22:44  eob
503:        // Better error reporting.
504:        //
505:        // Revision 1.14  2002/05/11 00:10:18  eob
506:        // Remove stub method that is now implemented with a slightly different
507:        // name in Node.
508:        //
509:        // Revision 1.13  2002/05/10 21:03:19  eob
510:        // Add equals method.
511:        //
512:        // Revision 1.12  2002/05/09 16:48:40  eob
513:        // Add replaceChild.  Fix cloneChild.
514:        //
515:        // Revision 1.11  2002/03/28 01:23:18  jrowson
516:        // fixed bugs related to client side caching
517:        //
518:        // Revision 1.10  2002/03/26 01:45:39  eob
519:        // Deprecate XPathAPI
520:        //
521:        // Revision 1.9  2002/02/23 02:04:44  eob
522:        // Add clone method.  Tweak toXml API.
523:        //
524:        // Revision 1.8  2002/02/15 21:20:10  eob
525:        // Rename xpath* methods to xpathSelect* to make more obvious.
526:        //
527:        // Revision 1.7  2002/02/15 21:05:55  eob
528:        // Add convenient xpath* methods, allowing a more object-oriented use than
529:        // XPathAPI.
530:        //
531:        // Revision 1.6  2002/02/01 21:50:27  eob
532:        // Move toXml up to Node
533:        //
534:        // Revision 1.5  2002/01/05 07:53:28  eob
535:        // Factor out some functionality into Node.
536:        //
537:        // Revision 1.4  2002/01/04 00:37:50  eob
538:        // add annotation
539:        //
540:        // Revision 1.3  2002/01/04 16:49:17  eob
541:        // Fix indentation.
542:        //
543:        // Revision 1.2  2002/01/04 16:47:59  eob
544:        // Move parse functionality functionality to ParseSource.
545:        //
546:        // Revision 1.1  2001/12/19 05:52:38  eob
547:        // initial
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.