Source Code Cross Referenced for DOMStreamer.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » xml » dom » 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 » Content Management System » apache lenya 2.0 » org.apache.cocoon.xml.dom 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.xml.dom;
018:
019:        import org.apache.avalon.excalibur.pool.Recyclable;
020:
021:        import org.apache.cocoon.xml.AbstractXMLProducer;
022:        import org.apache.cocoon.xml.EmbeddedXMLPipe;
023:        import org.apache.cocoon.xml.XMLConsumer;
024:        import org.apache.cocoon.xml.XMLProducer;
025:
026:        import org.apache.commons.lang.StringUtils;
027:        import org.w3c.dom.Attr;
028:        import org.w3c.dom.Comment;
029:        import org.w3c.dom.Element;
030:        import org.w3c.dom.EntityReference;
031:        import org.w3c.dom.NamedNodeMap;
032:        import org.w3c.dom.Node;
033:        import org.w3c.dom.ProcessingInstruction;
034:        import org.w3c.dom.Text;
035:        import org.xml.sax.ContentHandler;
036:        import org.xml.sax.SAXException;
037:        import org.xml.sax.ext.LexicalHandler;
038:        import org.xml.sax.helpers.AttributesImpl;
039:
040:        import javax.xml.transform.Transformer;
041:        import javax.xml.transform.TransformerConfigurationException;
042:        import javax.xml.transform.TransformerException;
043:        import javax.xml.transform.TransformerFactory;
044:        import javax.xml.transform.dom.DOMSource;
045:        import javax.xml.transform.sax.SAXResult;
046:        import java.util.HashMap;
047:        import java.util.Iterator;
048:        import java.util.Map;
049:
050:        /**
051:         * The <code>DOMStreamer</code> is a utility class that will generate SAX
052:         * events from a W3C DOM Document.
053:         *
054:         * <p>The DOMStreamer uses a different strategy based on the value of the
055:         * normalizeNamespaces property:
056:         * <ul>
057:         * <li>if true (the default), the DOMStreamer will normalize namespace
058:         * declarations (i.e. add missing xmlns attributes or correct them). See
059:         * also {@link NamespaceNormalizingDOMStreamer}.
060:         * <li>if false, the standard JAXP identity transformer is used.
061:         * </ul>
062:         *
063:         * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
064:         * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
065:         *         (Apache Software Foundation)
066:         * @version $Id: DOMStreamer.java 433543 2006-08-22 06:22:54Z crossley $
067:         */
068:        public class DOMStreamer implements  XMLProducer, Recyclable {
069:
070:            /** The transformer factory shared by all instances (only used by DefaultDOMStreamer) */
071:            private static final TransformerFactory FACTORY = TransformerFactory
072:                    .newInstance();
073:
074:            /** Default value for normalizeNamespaces. */
075:            private static final boolean DEFAULT_NORMALIZE_NAMESPACES = true;
076:
077:            /** Indicates whether namespace normalization should happen. */
078:            protected boolean normalizeNamespaces = DEFAULT_NORMALIZE_NAMESPACES;
079:
080:            /** DOMStreamer used in case of namespace normalization. */
081:            protected NamespaceNormalizingDOMStreamer namespaceNormalizingDOMStreamer = new NamespaceNormalizingDOMStreamer();
082:
083:            /** DOMStreamer used when namespace normalization should not explicitely happen. */
084:            protected DefaultDOMStreamer defaultDOMStreamer = new DefaultDOMStreamer();
085:
086:            /**
087:             * Create a new <code>DOMStreamer</code> instance.
088:             */
089:            public DOMStreamer() {
090:                super ();
091:            }
092:
093:            /**
094:             * Create a new <code>DOMStreamer</code> instance.
095:             */
096:            public DOMStreamer(ContentHandler content, LexicalHandler lexical) {
097:                this ();
098:                setContentHandler(content);
099:                setLexicalHandler(lexical);
100:            }
101:
102:            /**
103:             * Create a new <code>DOMStreamer</code> instance.
104:             */
105:            public DOMStreamer(XMLConsumer consumer) {
106:                this (consumer, consumer);
107:            }
108:
109:            /**
110:             * Create a new <code>DOMStreamer</code> instance.
111:             */
112:            public DOMStreamer(ContentHandler content) {
113:                this (
114:                        content,
115:                        content instanceof  LexicalHandler ? (LexicalHandler) content
116:                                : null);
117:            }
118:
119:            /**
120:             * Set the <code>XMLConsumer</code> that will receive XML data.
121:             */
122:            public void setConsumer(XMLConsumer consumer) {
123:                setContentHandler(consumer);
124:                setLexicalHandler(consumer);
125:            }
126:
127:            /**
128:             * Set the <code>ContentHandler</code> that will receive XML data.
129:             */
130:            public void setContentHandler(ContentHandler handler) {
131:                defaultDOMStreamer.setContentHandler(handler);
132:                namespaceNormalizingDOMStreamer.setContentHandler(handler);
133:            }
134:
135:            /**
136:             * Set the <code>LexicalHandler</code> that will receive XML data.
137:             */
138:            public void setLexicalHandler(LexicalHandler handler) {
139:                defaultDOMStreamer.setLexicalHandler(handler);
140:                namespaceNormalizingDOMStreamer.setLexicalHandler(handler);
141:            }
142:
143:            /**
144:             * Start the production of SAX events.
145:             */
146:            public void stream(Node node) throws SAXException {
147:                if (normalizeNamespaces) {
148:                    namespaceNormalizingDOMStreamer.stream(node);
149:                } else {
150:                    defaultDOMStreamer.stream(node);
151:                }
152:            }
153:
154:            public boolean isNormalizeNamespaces() {
155:                return normalizeNamespaces;
156:            }
157:
158:            public void setNormalizeNamespaces(boolean normalizeNamespaces) {
159:                this .normalizeNamespaces = normalizeNamespaces;
160:            }
161:
162:            public void recycle() {
163:                defaultDOMStreamer.recycle();
164:                namespaceNormalizingDOMStreamer.recycle();
165:                normalizeNamespaces = DEFAULT_NORMALIZE_NAMESPACES;
166:            }
167:
168:            /**
169:             * Streams a DOM tree to SAX events and normalizes namespace declarations on the way.
170:             *
171:             * <p>The code in this class is based on the org.apache.xml.utils.TreeWalker class from Xalan,
172:             * though it differs in some important ways.
173:             *
174:             * <p>This class will automatically fix up ("normalize") namespace declarations
175:             * while streaming to SAX. The original DOM-tree is not modified. The algorithm
176:             * used is described in
177:             * <a href="http://www.w3.org/TR/2002/WD-DOM-Level-3-Core-20021022/namespaces-algorithms.html#normalizeDocumentAlgo">an appendix of the DOM Level 3 spec</a>.
178:             *
179:             * <p>This class will NOT check the correctness of namespaces, e.g. it will not
180:             * check that the "xml" prefix is not misused etc.
181:             *
182:             * @author Bruno Dumon (bruno at outerthought dot org)
183:             * @author Xalan team
184:             */
185:            public static class NamespaceNormalizingDOMStreamer extends
186:                    AbstractXMLProducer {
187:                /**
188:                 * Information about the current element. Used to remember the localName, qName
189:                 * and namespaceURI for generating the endElement event, and holds the namespaces
190:                 * declared on the element. This extra class is needed because we don't want to
191:                 * modify the DOM-tree itself. The currentElementInfo has a pointer to its parent
192:                 * elementInfo.
193:                 */
194:                protected NamespaceNormalizingDOMStreamer.ElementInfo currentElementInfo;
195:
196:                /** Counter used when generating new namespace prefixes. */
197:                protected int newPrefixCounter;
198:
199:                public void recycle() {
200:                    super .recycle();
201:                    currentElementInfo = null;
202:                    newPrefixCounter = 0;
203:                }
204:
205:                /**
206:                 * Start the production of SAX events.
207:                 *
208:                 * <p>Perform a pre-order traversal non-recursive style.
209:                 *
210:                 * <p>Note that TreeWalker assumes that the subtree is intended to represent
211:                 * a complete (though not necessarily well-formed) document and, during a
212:                 * traversal, startDocument and endDocument will always be issued to the
213:                 * SAX listener.
214:                 *
215:                 * @param pos Node in the tree where to start traversal
216:                 */
217:                protected void stream(Node pos) throws SAXException {
218:
219:                    // Start document only if we're streaming a document
220:                    boolean isDoc = (pos.getNodeType() == Node.DOCUMENT_NODE);
221:                    if (isDoc) {
222:                        contentHandler.startDocument();
223:                    }
224:
225:                    Node top = pos;
226:                    while (null != pos) {
227:                        startNode(pos);
228:
229:                        Node nextNode = pos.getFirstChild();
230:                        while (null == nextNode) {
231:                            endNode(pos);
232:
233:                            if (top.equals(pos)) {
234:                                break;
235:                            }
236:
237:                            nextNode = pos.getNextSibling();
238:                            if (null == nextNode) {
239:                                pos = pos.getParentNode();
240:
241:                                if ((null == pos) || (top.equals(pos))) {
242:                                    if (null != pos) {
243:                                        endNode(pos);
244:                                    }
245:                                    nextNode = null;
246:
247:                                    break;
248:                                }
249:                            }
250:                        }
251:
252:                        pos = nextNode;
253:                    }
254:
255:                    if (isDoc) {
256:                        contentHandler.endDocument();
257:                    }
258:                }
259:
260:                private final void dispatchChars(Node node) throws SAXException {
261:                    final String data = ((Text) node).getData();
262:                    if (data != null) {
263:                        contentHandler.characters(data.toCharArray(), 0, data
264:                                .length());
265:                    }
266:                }
267:
268:                /**
269:                 * Start processing given node
270:                 *
271:                 * @param node Node to process
272:                 */
273:                protected void startNode(Node node) throws SAXException {
274:
275:                    switch (node.getNodeType()) {
276:                    case Node.COMMENT_NODE: {
277:                        if (lexicalHandler != null) {
278:                            final String data = ((Comment) node).getData();
279:                            if (data != null) {
280:                                lexicalHandler.comment(data.toCharArray(), 0,
281:                                        data.length());
282:                            }
283:                        }
284:                    }
285:                        break;
286:                    case Node.DOCUMENT_FRAGMENT_NODE:
287:                        // ??;
288:                    case Node.DOCUMENT_NODE:
289:                        break;
290:                    case Node.ELEMENT_NODE:
291:                        NamedNodeMap atts = node.getAttributes();
292:                        int nAttrs = atts.getLength();
293:
294:                        // create a list of localy declared namespace prefixes
295:                        currentElementInfo = new NamespaceNormalizingDOMStreamer.ElementInfo(
296:                                currentElementInfo);
297:                        for (int i = 0; i < nAttrs; i++) {
298:                            Node attr = atts.item(i);
299:                            String attrName = attr.getNodeName();
300:
301:                            if (attrName.equals("xmlns")
302:                                    || attrName.startsWith("xmlns:")) {
303:                                int index;
304:                                String prefix = (index = attrName.indexOf(":")) < 0 ? ""
305:                                        : attrName.substring(index + 1);
306:
307:                                currentElementInfo.put(prefix, attr
308:                                        .getNodeValue());
309:                            }
310:                        }
311:
312:                        String namespaceURI = node.getNamespaceURI();
313:                        String prefix = node.getPrefix();
314:                        String localName = node.getLocalName();
315:
316:                        if (localName == null) {
317:                            // this is an element created with createElement instead of createElementNS
318:                            String[] prefixAndLocalName = getPrefixAndLocalName(node
319:                                    .getNodeName());
320:                            prefix = prefixAndLocalName[0];
321:                            localName = prefixAndLocalName[1];
322:                            // note: if prefix is null, there can still be a default namespace...
323:                            namespaceURI = getNamespaceForPrefix(prefix,
324:                                    (Element) node);
325:                        }
326:
327:                        if (namespaceURI != null) {
328:                            // no prefix means: make this the default namespace
329:                            if (prefix == null) {
330:                                prefix = "";
331:                            }
332:                            // check that is declared
333:                            String uri = currentElementInfo
334:                                    .findNamespaceURI(prefix);
335:                            if (StringUtils.equals(uri, namespaceURI)) {
336:                                // System.out.println("namespace is declared");
337:                                // prefix is declared correctly, do nothing
338:                                //} else if (uri != null) {
339:                                // System.out.println("prefix is declared with other namespace, overwriting it");
340:                                // prefix exists but is bound to another namespace, overwrite it
341:                                // currentElementInfo.put(prefix, namespaceURI);
342:                            } else {
343:                                // System.out.println("prefix is not yet declared, declaring it now");
344:                                currentElementInfo.put(prefix, namespaceURI);
345:                            }
346:                        } else {
347:                            // element has no namespace
348:                            // check if there is a default namespace, if so undeclare it
349:                            String uri = currentElementInfo
350:                                    .findNamespaceURI("");
351:                            if (StringUtils.isNotEmpty(uri)) {
352:                                // System.out.println("undeclaring default namespace");
353:                                currentElementInfo.put("", "");
354:                            }
355:                        }
356:
357:                        // SAX uses empty string to denote no namespace, while DOM uses null.
358:                        if (namespaceURI == null)
359:                            namespaceURI = "";
360:
361:                        String qName;
362:                        if (StringUtils.isNotEmpty(prefix)) {
363:                            qName = prefix + ":" + localName;
364:                        } else {
365:                            qName = localName;
366:                        }
367:
368:                        // make the attributes
369:                        AttributesImpl newAttrs = new AttributesImpl();
370:                        for (int i = 0; i < nAttrs; i++) {
371:                            Node attr = atts.item(i);
372:                            String attrName = attr.getNodeName();
373:                            String assignedAttrPrefix = null;
374:
375:                            // only do non-namespace attributes
376:                            if (!(attrName.equals("xmlns") || attrName
377:                                    .startsWith("xmlns:"))) {
378:                                String attrPrefix;
379:                                String attrLocalName;
380:                                String attrNsURI;
381:
382:                                if (attr.getLocalName() == null) {
383:                                    // this is an attribute created with setAttribute instead of setAttributeNS
384:                                    String[] prefixAndLocalName = getPrefixAndLocalName(attrName);
385:                                    attrPrefix = prefixAndLocalName[0];
386:                                    // the statement below causes the attribute to keep its prefix even if it is not
387:                                    // bound to a namespace (to support pre-namespace XML).
388:                                    assignedAttrPrefix = attrPrefix;
389:                                    attrLocalName = prefixAndLocalName[1];
390:                                    // note: if prefix is null, the attribute has no namespace (namespace defaulting
391:                                    // does not apply to attributes)
392:                                    if (attrPrefix != null)
393:                                        attrNsURI = getNamespaceForPrefix(
394:                                                attrPrefix, (Element) node);
395:                                    else
396:                                        attrNsURI = null;
397:                                } else {
398:                                    attrLocalName = attr.getLocalName();
399:                                    attrPrefix = attr.getPrefix();
400:                                    attrNsURI = attr.getNamespaceURI();
401:                                }
402:
403:                                if (attrNsURI != null) {
404:                                    String declaredUri = currentElementInfo
405:                                            .findNamespaceURI(attrPrefix);
406:                                    // if the prefix is null, or the prefix has not been declared, or conflicts with an in-scope binding
407:                                    if (declaredUri == null
408:                                            || !declaredUri.equals(attrNsURI)) {
409:                                        String availablePrefix = currentElementInfo
410:                                                .findPrefix(attrNsURI);
411:                                        if (availablePrefix != null
412:                                                && !availablePrefix.equals(""))
413:                                            assignedAttrPrefix = availablePrefix;
414:                                        else {
415:                                            if (attrPrefix != null
416:                                                    && declaredUri == null) {
417:                                                // prefix is not null and is not yet declared: declare it
418:                                                assignedAttrPrefix = attrPrefix;
419:                                                currentElementInfo.put(
420:                                                        assignedAttrPrefix,
421:                                                        attrNsURI);
422:                                            } else {
423:                                                // attribute has no prefix (which is not allowed for namespaced attributes) or
424:                                                // the prefix is already bound to something else: generate a new prefix
425:                                                newPrefixCounter++;
426:                                                assignedAttrPrefix = "NS"
427:                                                        + newPrefixCounter;
428:                                                currentElementInfo.put(
429:                                                        assignedAttrPrefix,
430:                                                        attrNsURI);
431:                                            }
432:                                        }
433:                                    } else {
434:                                        assignedAttrPrefix = attrPrefix;
435:                                    }
436:                                }
437:
438:                                String assignedAttrNsURI = attrNsURI != null ? attrNsURI
439:                                        : "";
440:                                String attrQName;
441:                                if (assignedAttrPrefix != null) {
442:                                    attrQName = assignedAttrPrefix + ":"
443:                                            + attrLocalName;
444:                                } else {
445:                                    attrQName = attrLocalName;
446:                                }
447:                                newAttrs.addAttribute(assignedAttrNsURI,
448:                                        attrLocalName, attrQName, "CDATA", attr
449:                                                .getNodeValue());
450:                            }
451:                        }
452:
453:                        // add local namespace declaration and fire startPrefixMapping events
454:                        if (currentElementInfo.namespaceDeclarations != null
455:                                && currentElementInfo.namespaceDeclarations
456:                                        .size() > 0) {
457:                            Iterator localNsDeclIt = currentElementInfo.namespaceDeclarations
458:                                    .entrySet().iterator();
459:                            while (localNsDeclIt.hasNext()) {
460:                                Map.Entry entry = (Map.Entry) localNsDeclIt
461:                                        .next();
462:                                String pr = (String) entry.getKey();
463:                                String ns = (String) entry.getValue();
464:                                // the following lines enable the creation of explicit xmlns attributes
465:                                //String pr1 = pr.equals("") ? "xmlns" : pr;
466:                                //String qn = pr.equals("") ? "xmlns" : "xmlns:" + pr;
467:                                //newAttrs.addAttribute("", pr1, qn, "CDATA", ns);
468:                                // System.out.println("starting prefix mapping  for prefix " + pr + " for " + ns);
469:                                contentHandler.startPrefixMapping(pr, ns);
470:                            }
471:                        }
472:
473:                        contentHandler.startElement(namespaceURI, localName,
474:                                qName, newAttrs);
475:
476:                        currentElementInfo.localName = localName;
477:                        currentElementInfo.namespaceURI = namespaceURI;
478:                        currentElementInfo.qName = qName;
479:                        break;
480:                    case Node.PROCESSING_INSTRUCTION_NODE: {
481:                        ProcessingInstruction pi = (ProcessingInstruction) node;
482:                        contentHandler.processingInstruction(pi.getNodeName(),
483:                                pi.getData());
484:                    }
485:                        break;
486:                    case Node.CDATA_SECTION_NODE: {
487:                        if (lexicalHandler != null)
488:                            lexicalHandler.startCDATA();
489:
490:                        dispatchChars(node);
491:
492:                        if (lexicalHandler != null)
493:                            lexicalHandler.endCDATA();
494:                    }
495:                        break;
496:                    case Node.TEXT_NODE: {
497:                        dispatchChars(node);
498:                    }
499:                        break;
500:                    case Node.ENTITY_REFERENCE_NODE: {
501:                        EntityReference eref = (EntityReference) node;
502:
503:                        if (lexicalHandler != null) {
504:                            lexicalHandler.startEntity(eref.getNodeName());
505:                        } else {
506:                            // warning("Can not output entity to a pure SAX ContentHandler");
507:                        }
508:                    }
509:                        break;
510:                    default:
511:                    }
512:                }
513:
514:                /**
515:                 * Searches the namespace for a given namespace prefix starting from a
516:                 * given Element.
517:                 *
518:                 * <p>Note that this resolves the prefix in the orginal DOM-tree, not in
519:                 * the {@link ElementInfo} objects. This is used to resolve prefixes
520:                 * of elements or attributes created with createElement or setAttribute
521:                 * instead of createElementNS or setAttributeNS.
522:                 *
523:                 * <p>The code in this method is largely based on
524:                 * org.apache.xml.utils.DOMHelper.getNamespaceForPrefix() (from Xalan).
525:                 *
526:                 * @param prefix the prefix to look for, can be empty or null to find the
527:                 * default namespace
528:                 *
529:                 * @return the namespace, or null if not found.
530:                 */
531:                public String getNamespaceForPrefix(String prefix,
532:                        Element namespaceContext) {
533:                    int type;
534:                    Node parent = namespaceContext;
535:                    String namespace = null;
536:
537:                    if (prefix == null)
538:                        prefix = "";
539:
540:                    if (prefix.equals("xml")) {
541:                        namespace = "http://www.w3.org/XML/1998/namespace";
542:                    } else if (prefix.equals("xmlns")) {
543:                        namespace = "http://www.w3.org/2000/xmlns/";
544:                    } else {
545:                        // Attribute name for this prefix's declaration
546:                        String declname = (prefix.length() == 0) ? "xmlns"
547:                                : "xmlns:" + prefix;
548:
549:                        // Scan until we run out of Elements or have resolved the namespace
550:                        while ((null != parent)
551:                                && (((type = parent.getNodeType()) == Node.ELEMENT_NODE) || (type == Node.ENTITY_REFERENCE_NODE))) {
552:                            if (type == Node.ELEMENT_NODE) {
553:                                Attr attr = ((Element) parent)
554:                                        .getAttributeNode(declname);
555:                                if (attr != null) {
556:                                    namespace = attr.getNodeValue();
557:                                    break;
558:                                }
559:                            }
560:                            parent = parent.getParentNode();
561:                        }
562:                    }
563:                    return namespace;
564:                }
565:
566:                /**
567:                 * Splits a nodeName into a prefix and a localName
568:                 *
569:                 * @return an array containing two elements, the first one is the prefix (can be null), the
570:                 * second one is the localName
571:                 */
572:                private String[] getPrefixAndLocalName(String nodeName) {
573:                    String prefix, localName;
574:                    int colonPos = nodeName.indexOf(":");
575:                    if (colonPos != -1) {
576:                        prefix = nodeName.substring(0, colonPos);
577:                        localName = nodeName.substring(colonPos + 1, nodeName
578:                                .length());
579:                    } else {
580:                        prefix = null;
581:                        localName = nodeName;
582:                    }
583:                    return new String[] { prefix, localName };
584:                }
585:
586:                /**
587:                 * End processing of given node
588:                 *
589:                 * @param node Node we just finished processing
590:                 */
591:                protected void endNode(Node node)
592:                        throws org.xml.sax.SAXException {
593:
594:                    switch (node.getNodeType()) {
595:                    case Node.ELEMENT_NODE:
596:                        contentHandler.endElement(
597:                                currentElementInfo.namespaceURI,
598:                                currentElementInfo.localName,
599:                                currentElementInfo.qName);
600:
601:                        // generate endPrefixMapping events if needed
602:                        if (currentElementInfo.namespaceDeclarations != null
603:                                && currentElementInfo.namespaceDeclarations
604:                                        .size() > 0) {
605:                            Iterator namespaceIt = currentElementInfo.namespaceDeclarations
606:                                    .entrySet().iterator();
607:                            while (namespaceIt.hasNext()) {
608:                                Map.Entry entry = (Map.Entry) namespaceIt
609:                                        .next();
610:                                contentHandler.endPrefixMapping((String) entry
611:                                        .getKey());
612:                                //System.out.println("ending prefix mapping " + (String) entry.getKey());
613:                            }
614:                        }
615:                        currentElementInfo = currentElementInfo.parent;
616:                        break;
617:                    case Node.DOCUMENT_NODE:
618:                    case Node.CDATA_SECTION_NODE:
619:                        break;
620:                    case Node.ENTITY_REFERENCE_NODE: {
621:                        EntityReference eref = (EntityReference) node;
622:
623:                        if (lexicalHandler != null) {
624:                            lexicalHandler.endEntity(eref.getNodeName());
625:                        }
626:                    }
627:                        break;
628:                    default:
629:                    }
630:                }
631:
632:                public static class ElementInfo {
633:                    public String localName;
634:                    public String namespaceURI;
635:                    public String qName;
636:                    public Map namespaceDeclarations = null;
637:                    public ElementInfo parent;
638:
639:                    public ElementInfo(ElementInfo parent) {
640:                        this .parent = parent;
641:                    }
642:
643:                    /**
644:                     * Declare a new namespace prefix on this element, possibly overriding
645:                     * an existing one.
646:                     */
647:                    public void put(String prefix, String namespaceURI) {
648:                        if (namespaceDeclarations == null)
649:                            namespaceDeclarations = new HashMap();
650:                        namespaceDeclarations.put(prefix, namespaceURI);
651:                    }
652:
653:                    /**
654:                     * Finds a prefix declared on this element.
655:                     */
656:                    public String getPrefix(String namespaceURI) {
657:                        if (namespaceDeclarations == null
658:                                || namespaceDeclarations.size() == 0)
659:                            return null;
660:                        // note: there could be more than one prefix for the same namespaceURI, but
661:                        // we return the first found one.
662:                        Iterator it = namespaceDeclarations.entrySet()
663:                                .iterator();
664:                        while (it.hasNext()) {
665:                            Map.Entry entry = (Map.Entry) it.next();
666:                            if (entry.getValue().equals(namespaceURI))
667:                                return (String) entry.getKey();
668:                        }
669:                        return null;
670:                    }
671:
672:                    /**
673:                     * Finds a namespace URI declared on this element.
674:                     */
675:                    public String getNamespaceURI(String prefix) {
676:                        if (namespaceDeclarations == null
677:                                || namespaceDeclarations.size() == 0)
678:                            return null;
679:
680:                        return (String) namespaceDeclarations.get(prefix);
681:                    }
682:
683:                    /**
684:                     * Finds a prefix declaration on this element or containing elements.
685:                     */
686:                    public String findPrefix(String namespaceURI) {
687:                        if (namespaceDeclarations != null
688:                                && namespaceDeclarations.size() != 0) {
689:                            String prefix = getPrefix(namespaceURI);
690:                            if (prefix != null) {
691:                                return prefix;
692:                            }
693:                        }
694:                        if (parent != null) {
695:                            return parent.findPrefix(namespaceURI);
696:                        }
697:                        return null;
698:                    }
699:
700:                    /**
701:                     * Finds a namespace declaration on this element or containing elements.
702:                     */
703:                    public String findNamespaceURI(String prefix) {
704:                        if (namespaceDeclarations != null
705:                                && namespaceDeclarations.size() != 0) {
706:                            String uri = (String) namespaceDeclarations
707:                                    .get(prefix);
708:                            if (uri != null) {
709:                                return uri;
710:                            }
711:                        }
712:                        if (parent != null) {
713:                            return parent.findNamespaceURI(prefix);
714:                        }
715:                        return null;
716:                    }
717:                }
718:            }
719:
720:            /**
721:             * The <code>DefaultDOMStreamer</code> is a utility class that will generate SAX
722:             * events from a W3C DOM Document.
723:             *
724:             * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
725:             * @author <a href="mailto:pier@apache.org">Pierpaolo Fumagalli</a>
726:             *         (Apache Software Foundation)
727:             */
728:            public static class DefaultDOMStreamer extends AbstractXMLProducer {
729:
730:                /** The private transformer for this instance */
731:                protected Transformer transformer;
732:
733:                /**
734:                 * Start the production of SAX events.
735:                 */
736:                public void stream(Node node) throws SAXException {
737:                    if (this .transformer == null) {
738:                        try {
739:                            this .transformer = FACTORY.newTransformer();
740:                        } catch (TransformerConfigurationException e) {
741:                            throw new SAXException(e);
742:                        }
743:                    }
744:                    DOMSource source = new DOMSource(node);
745:
746:                    ContentHandler handler;
747:                    if (node.getNodeType() == Node.DOCUMENT_NODE) {
748:                        // Pass all SAX events
749:                        handler = contentHandler;
750:                    } else {
751:                        // Strip start/endDocument
752:                        handler = new EmbeddedXMLPipe(contentHandler);
753:                    }
754:
755:                    SAXResult result = new SAXResult(handler);
756:                    result.setLexicalHandler(lexicalHandler);
757:
758:                    try {
759:                        transformer.transform(source, result);
760:                    } catch (TransformerException e) {
761:                        throw new SAXException(e);
762:                    }
763:                }
764:            }
765:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.