Source Code Cross Referenced for SAXHandler.java in  » XML » jdom » org » jdom » input » 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 » XML » jdom » org.jdom.input 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*--
002:
003:         $Id: SAXHandler.java,v 1.68 2004/08/31 06:14:05 jhunter Exp $
004:
005:         Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
006:         All rights reserved.
007:
008:         Redistribution and use in source and binary forms, with or without
009:         modification, are permitted provided that the following conditions
010:         are met:
011:
012:         1. Redistributions of source code must retain the above copyright
013:            notice, this list of conditions, and the following disclaimer.
014:
015:         2. Redistributions in binary form must reproduce the above copyright
016:            notice, this list of conditions, and the disclaimer that follows
017:            these conditions in the documentation and/or other materials
018:            provided with the distribution.
019:
020:         3. The name "JDOM" must not be used to endorse or promote products
021:            derived from this software without prior written permission.  For
022:            written permission, please contact <request_AT_jdom_DOT_org>.
023:
024:         4. Products derived from this software may not be called "JDOM", nor
025:            may "JDOM" appear in their name, without prior written permission
026:            from the JDOM Project Management <request_AT_jdom_DOT_org>.
027:
028:         In addition, we request (but do not require) that you include in the
029:         end-user documentation provided with the redistribution and/or in the
030:         software itself an acknowledgement equivalent to the following:
031:             "This product includes software developed by the
032:              JDOM Project (http://www.jdom.org/)."
033:         Alternatively, the acknowledgment may be graphical using the logos
034:         available at http://www.jdom.org/images/logos.
035:
036:         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037:         WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038:         OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039:         DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
040:         CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041:         SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042:         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043:         USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044:         ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045:         OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046:         OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047:         SUCH DAMAGE.
048:
049:         This software consists of voluntary contributions made by many
050:         individuals on behalf of the JDOM Project and was originally
051:         created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
052:         Brett McLaughlin <brett_AT_jdom_DOT_org>.  For more information
053:         on the JDOM Project, please see <http://www.jdom.org/>.
054:
055:         */
056:
057:        package org.jdom.input;
058:
059:        import java.util.*;
060:
061:        import org.jdom.*;
062:        import org.xml.sax.*;
063:        import org.xml.sax.ext.*;
064:        import org.xml.sax.helpers.*;
065:
066:        /**
067:         * A support class for {@link SAXBuilder}.
068:         *
069:         * @version $Revision: 1.68 $, $Date: 2004/08/31 06:14:05 $
070:         * @author  Brett McLaughlin
071:         * @author  Jason Hunter
072:         * @author  Philip Nelson
073:         * @author  Bradley S. Huffman
074:         * @author  phil@triloggroup.com
075:         */
076:        public class SAXHandler extends DefaultHandler implements 
077:                LexicalHandler, DeclHandler, DTDHandler {
078:
079:            private static final String CVS_ID = "@(#) $RCSfile: SAXHandler.java,v $ $Revision: 1.68 $ $Date: 2004/08/31 06:14:05 $ $Name: jdom_1_0 $";
080:
081:            /** Hash table to map SAX attribute type names to JDOM attribute types. */
082:            private static final Map attrNameToTypeMap = new HashMap(13);
083:
084:            /** <code>Document</code> object being built */
085:            private Document document;
086:
087:            /** <code>Element</code> object being built */
088:            private Element currentElement;
089:
090:            /** Indicator of where in the document we are */
091:            private boolean atRoot;
092:
093:            /** Indicator of whether we are in the DocType. Note that the DTD consists
094:             * of both the internal subset (inside the <!DOCTYPE> tag) and the
095:             * external subset (in a separate .dtd file). */
096:            private boolean inDTD = false;
097:
098:            /** Indicator of whether we are in the internal subset */
099:            private boolean inInternalSubset = false;
100:
101:            /** Indicator of whether we previously were in a CDATA */
102:            private boolean previousCDATA = false;
103:
104:            /** Indicator of whether we are in a CDATA */
105:            private boolean inCDATA = false;
106:
107:            /** Indicator of whether we should expand entities */
108:            private boolean expand = true;
109:
110:            /** Indicator of whether we are actively suppressing (non-expanding) a
111:                current entity */
112:            private boolean suppress = false;
113:
114:            /** How many nested entities we're currently within */
115:            private int entityDepth = 0; // XXX may not be necessary anymore?
116:
117:            /** Temporary holder for namespaces that have been declared with
118:             * startPrefixMapping, but are not yet available on the element */
119:            private List declaredNamespaces;
120:
121:            /** Temporary holder for the internal subset */
122:            private StringBuffer internalSubset = new StringBuffer();
123:
124:            /** Temporary holder for Text and CDATA */
125:            private TextBuffer textBuffer = new TextBuffer();
126:
127:            /** The external entities defined in this document */
128:            private Map externalEntities;
129:
130:            /** The JDOMFactory used for JDOM object creation */
131:            private JDOMFactory factory;
132:
133:            /** Whether to ignore ignorable whitespace */
134:            private boolean ignoringWhite = false;
135:
136:            /** The SAX Locator object provided by the parser */
137:            private Locator locator;
138:
139:            /**
140:             * Class initializer: Populate a table to translate SAX attribute
141:             * type names into JDOM attribute type value (integer).
142:             * <p>
143:             * <b>Note that all the mappings defined below are compliant with
144:             * the SAX 2.0 specification exception for "ENUMERATION" with is
145:             * specific to Crimson 1.1.X and Xerces 2.0.0-betaX which report
146:             * attributes of enumerated types with a type "ENUMERATION"
147:             * instead of the expected "NMTOKEN".
148:             * </p>
149:             * <p>
150:             * Note also that Xerces 1.4.X is not SAX 2.0 compliant either
151:             * but handling its case requires
152:             * {@link #getAttributeType specific code}.
153:             * </p>
154:             */
155:            static {
156:                attrNameToTypeMap.put("CDATA",
157:                        new Integer(Attribute.CDATA_TYPE));
158:                attrNameToTypeMap.put("ID", new Integer(Attribute.ID_TYPE));
159:                attrNameToTypeMap.put("IDREF",
160:                        new Integer(Attribute.IDREF_TYPE));
161:                attrNameToTypeMap.put("IDREFS", new Integer(
162:                        Attribute.IDREFS_TYPE));
163:                attrNameToTypeMap.put("ENTITY", new Integer(
164:                        Attribute.ENTITY_TYPE));
165:                attrNameToTypeMap.put("ENTITIES", new Integer(
166:                        Attribute.ENTITIES_TYPE));
167:                attrNameToTypeMap.put("NMTOKEN", new Integer(
168:                        Attribute.NMTOKEN_TYPE));
169:                attrNameToTypeMap.put("NMTOKENS", new Integer(
170:                        Attribute.NMTOKENS_TYPE));
171:                attrNameToTypeMap.put("NOTATION", new Integer(
172:                        Attribute.NOTATION_TYPE));
173:                attrNameToTypeMap.put("ENUMERATION", new Integer(
174:                        Attribute.ENUMERATED_TYPE));
175:            }
176:
177:            /**
178:             * This will create a new <code>SAXHandler</code> that listens to SAX
179:             * events and creates a JDOM Document.  The objects will be constructed
180:             * using the default factory.
181:             */
182:            public SAXHandler() {
183:                this (null);
184:            }
185:
186:            /**
187:             * This will create a new <code>SAXHandler</code> that listens to SAX
188:             * events and creates a JDOM Document.  The objects will be constructed
189:             * using the provided factory.
190:             *
191:             * @param factory <code>JDOMFactory</code> to be used for constructing
192:             * objects
193:             */
194:            public SAXHandler(JDOMFactory factory) {
195:                if (factory != null) {
196:                    this .factory = factory;
197:                } else {
198:                    this .factory = new DefaultJDOMFactory();
199:                }
200:
201:                atRoot = true;
202:                declaredNamespaces = new ArrayList();
203:                externalEntities = new HashMap();
204:
205:                document = this .factory.document(null);
206:            }
207:
208:            /**
209:             * Pushes an element onto the tree under construction.  Allows subclasses
210:             * to put content under a dummy root element which is useful for building
211:             * content that would otherwise be a non-well formed document.
212:             *
213:             * @param element root element under which content will be built
214:             */
215:            protected void pushElement(Element element) {
216:                if (atRoot) {
217:                    document.setRootElement(element); // XXX should we use a factory call?
218:                    atRoot = false;
219:                } else {
220:                    factory.addContent(currentElement, element);
221:                }
222:                currentElement = element;
223:            }
224:
225:            /**
226:             * Returns the document.  Should be called after parsing is complete.
227:             *
228:             * @return <code>Document</code> - Document that was built
229:             */
230:            public Document getDocument() {
231:                return document;
232:            }
233:
234:            /**
235:             * Returns the factory used for constructing objects.
236:             *
237:             * @return <code>JDOMFactory</code> - the factory used for
238:             * constructing objects.
239:             *
240:             * @see #SAXHandler(org.jdom.JDOMFactory)
241:             */
242:            public JDOMFactory getFactory() {
243:                return factory;
244:            }
245:
246:            /**
247:             * This sets whether or not to expand entities during the build.
248:             * A true means to expand entities as normal content.  A false means to
249:             * leave entities unexpanded as <code>EntityRef</code> objects.  The
250:             * default is true.
251:             *
252:             * @param expand <code>boolean</code> indicating whether entity expansion
253:             * should occur.
254:             */
255:            public void setExpandEntities(boolean expand) {
256:                this .expand = expand;
257:            }
258:
259:            /**
260:             * Returns whether or not entities will be expanded during the
261:             * build.
262:             *
263:             * @return <code>boolean</code> - whether entity expansion
264:             * will occur during build.
265:             *
266:             * @see #setExpandEntities
267:             */
268:            public boolean getExpandEntities() {
269:                return expand;
270:            }
271:
272:            /**
273:             * Specifies whether or not the parser should elminate whitespace in
274:             * element content (sometimes known as "ignorable whitespace") when
275:             * building the document.  Only whitespace which is contained within
276:             * element content that has an element only content model will be
277:             * eliminated (see XML Rec 3.2.1).  For this setting to take effect
278:             * requires that validation be turned on.  The default value of this
279:             * setting is <code>false</code>.
280:             *
281:             * @param ignoringWhite Whether to ignore ignorable whitespace
282:             */
283:            public void setIgnoringElementContentWhitespace(
284:                    boolean ignoringWhite) {
285:                this .ignoringWhite = ignoringWhite;
286:            }
287:
288:            /**
289:             * Returns whether or not the parser will elminate whitespace in
290:             * element content (sometimes known as "ignorable whitespace") when
291:             * building the document.
292:             *
293:             * @return <code>boolean</code> - whether ignorable whitespace will
294:             * be ignored during build.
295:             *
296:             * @see #setIgnoringElementContentWhitespace
297:             */
298:            public boolean getIgnoringElementContentWhitespace() {
299:                return ignoringWhite;
300:            }
301:
302:            public void startDocument() {
303:                if (locator != null) {
304:                    document.setBaseURI(locator.getSystemId());
305:                }
306:            }
307:
308:            /**
309:             * This is called when the parser encounters an external entity
310:             * declaration.
311:             *
312:             * @param name entity name
313:             * @param publicID public id
314:             * @param systemID system id
315:             * @throws SAXException when things go wrong
316:             */
317:            public void externalEntityDecl(String name, String publicID,
318:                    String systemID) throws SAXException {
319:                // Store the public and system ids for the name
320:                externalEntities.put(name, new String[] { publicID, systemID });
321:
322:                if (!inInternalSubset)
323:                    return;
324:
325:                internalSubset.append("  <!ENTITY ").append(name);
326:                appendExternalId(publicID, systemID);
327:                internalSubset.append(">\n");
328:            }
329:
330:            /**
331:             * This handles an attribute declaration in the internal subset.
332:             *
333:             * @param eName <code>String</code> element name of attribute
334:             * @param aName <code>String</code> attribute name
335:             * @param type <code>String</code> attribute type
336:             * @param valueDefault <code>String</code> default value of attribute
337:             * @param value <code>String</code> value of attribute
338:             * @throws SAXException
339:             */
340:            public void attributeDecl(String eName, String aName, String type,
341:                    String valueDefault, String value) throws SAXException {
342:
343:                if (!inInternalSubset)
344:                    return;
345:
346:                internalSubset.append("  <!ATTLIST ").append(eName).append(' ')
347:                        .append(aName).append(' ').append(type).append(' ');
348:                if (valueDefault != null) {
349:                    internalSubset.append(valueDefault);
350:                } else {
351:                    internalSubset.append('\"').append(value).append('\"');
352:                }
353:                if ((valueDefault != null) && (valueDefault.equals("#FIXED"))) {
354:                    internalSubset.append(" \"").append(value).append('\"');
355:                }
356:                internalSubset.append(">\n");
357:            }
358:
359:            /**
360:             * Handle an element declaration in a DTD.
361:             *
362:             * @param name <code>String</code> name of element
363:             * @param model <code>String</code> model of the element in DTD syntax
364:             * @throws SAXException
365:             */
366:            public void elementDecl(String name, String model)
367:                    throws SAXException {
368:                // Skip elements that come from the external subset
369:                if (!inInternalSubset)
370:                    return;
371:
372:                internalSubset.append("  <!ELEMENT ").append(name).append(' ')
373:                        .append(model).append(">\n");
374:            }
375:
376:            /**
377:             * Handle an internal entity declaration in a DTD.
378:             *
379:             * @param name <code>String</code> name of entity
380:             * @param value <code>String</code> value of the entity
381:             * @throws SAXException
382:             */
383:            public void internalEntityDecl(String name, String value)
384:                    throws SAXException {
385:
386:                // Skip entities that come from the external subset
387:                if (!inInternalSubset)
388:                    return;
389:
390:                internalSubset.append("  <!ENTITY ");
391:                if (name.startsWith("%")) {
392:                    internalSubset.append("% ").append(name.substring(1));
393:                } else {
394:                    internalSubset.append(name);
395:                }
396:                internalSubset.append(" \"").append(value).append("\">\n");
397:            }
398:
399:            /**
400:             * This will indicate that a processing instruction has been encountered.
401:             * (The XML declaration is not a processing instruction and will not
402:             * be reported.)
403:             *
404:             * @param target <code>String</code> target of PI
405:             * @param data <code>String</code> containing all data sent to the PI.
406:             *             This typically looks like one or more attribute value
407:             *             pairs.
408:             * @throws SAXException when things go wrong
409:             */
410:            public void processingInstruction(String target, String data)
411:                    throws SAXException {
412:
413:                if (suppress)
414:                    return;
415:
416:                flushCharacters();
417:
418:                if (atRoot) {
419:                    factory.addContent(document, factory.processingInstruction(
420:                            target, data));
421:                } else {
422:                    factory.addContent(getCurrentElement(), factory
423:                            .processingInstruction(target, data));
424:                }
425:            }
426:
427:            /**
428:             * This indicates that an unresolvable entity reference has been
429:             * encountered, normally because the external DTD subset has not been
430:             * read.
431:             *
432:             * @param name <code>String</code> name of entity
433:             * @throws SAXException when things go wrong
434:             */
435:            public void skippedEntity(String name) throws SAXException {
436:
437:                // We don't handle parameter entity references.
438:                if (name.startsWith("%"))
439:                    return;
440:
441:                flushCharacters();
442:
443:                factory
444:                        .addContent(getCurrentElement(), factory
445:                                .entityRef(name));
446:            }
447:
448:            /**
449:             * This will add the prefix mapping to the JDOM
450:             * <code>Document</code> object.
451:             *
452:             * @param prefix <code>String</code> namespace prefix.
453:             * @param uri <code>String</code> namespace URI.
454:             */
455:            public void startPrefixMapping(String prefix, String uri)
456:                    throws SAXException {
457:
458:                if (suppress)
459:                    return;
460:
461:                Namespace ns = Namespace.getNamespace(prefix, uri);
462:                declaredNamespaces.add(ns);
463:            }
464:
465:            /**
466:             * This reports the occurrence of an actual element.  It will include
467:             * the element's attributes, with the exception of XML vocabulary
468:             * specific attributes, such as
469:             * <code>xmlns:[namespace prefix]</code> and
470:             * <code>xsi:schemaLocation</code>.
471:             *
472:             * @param namespaceURI <code>String</code> namespace URI this element
473:             *                     is associated with, or an empty
474:             *                     <code>String</code>
475:             * @param localName <code>String</code> name of element (with no
476:             *                  namespace prefix, if one is present)
477:             * @param qName <code>String</code> XML 1.0 version of element name:
478:             *                [namespace prefix]:[localName]
479:             * @param atts <code>Attributes</code> list for this element
480:             * @throws SAXException when things go wrong
481:             */
482:            public void startElement(String namespaceURI, String localName,
483:                    String qName, Attributes atts) throws SAXException {
484:                if (suppress)
485:                    return;
486:
487:                Element element = null;
488:
489:                if ((namespaceURI != null) && (!namespaceURI.equals(""))) {
490:                    String prefix = "";
491:
492:                    // Determine any prefix on the Element
493:                    if (!qName.equals(localName)) {
494:                        int split = qName.indexOf(":");
495:                        prefix = qName.substring(0, split);
496:                    }
497:                    Namespace elementNamespace = Namespace.getNamespace(prefix,
498:                            namespaceURI);
499:                    element = factory.element(localName, elementNamespace);
500:                } else {
501:                    element = factory.element(localName);
502:                }
503:
504:                // Take leftover declared namespaces and add them to this element's
505:                // map of namespaces
506:                if (declaredNamespaces.size() > 0) {
507:                    transferNamespaces(element);
508:                }
509:
510:                // Handle attributes
511:                for (int i = 0, len = atts.getLength(); i < len; i++) {
512:                    Attribute attribute = null;
513:
514:                    String attLocalName = atts.getLocalName(i);
515:                    String attQName = atts.getQName(i);
516:                    int attType = getAttributeType(atts.getType(i));
517:
518:                    // Bypass any xmlns attributes which might appear, as we got
519:                    // them already in startPrefixMapping().
520:                    // This is sometimes necessary when SAXHandler is used with
521:                    // another source than SAXBuilder, as with JDOMResult.
522:                    if (attQName.startsWith("xmlns:")
523:                            || attQName.equals("xmlns")) {
524:                        continue;
525:                    }
526:
527:                    if (!attQName.equals(attLocalName)) {
528:                        String attPrefix = attQName.substring(0, attQName
529:                                .indexOf(":"));
530:                        Namespace attNs = Namespace.getNamespace(attPrefix,
531:                                atts.getURI(i));
532:
533:                        attribute = factory.attribute(attLocalName, atts
534:                                .getValue(i), attType, attNs);
535:                    } else {
536:                        attribute = factory.attribute(attLocalName, atts
537:                                .getValue(i), attType);
538:                    }
539:                    factory.setAttribute(element, attribute);
540:                }
541:
542:                flushCharacters();
543:
544:                if (atRoot) {
545:                    document.setRootElement(element); // XXX should we use a factory call?
546:                    atRoot = false;
547:                } else {
548:                    factory.addContent(getCurrentElement(), element);
549:                }
550:                currentElement = element;
551:            }
552:
553:            /**
554:             * This will take the supplied <code>{@link Element}</code> and
555:             * transfer its namespaces to the global namespace storage.
556:             *
557:             * @param element <code>Element</code> to read namespaces from.
558:             */
559:            private void transferNamespaces(Element element) {
560:                Iterator i = declaredNamespaces.iterator();
561:                while (i.hasNext()) {
562:                    Namespace ns = (Namespace) i.next();
563:                    if (ns != element.getNamespace()) {
564:                        element.addNamespaceDeclaration(ns);
565:                    }
566:                }
567:                declaredNamespaces.clear();
568:            }
569:
570:            /**
571:             * This will report character data (within an element).
572:             *
573:             * @param ch <code>char[]</code> character array with character data
574:             * @param start <code>int</code> index in array where data starts.
575:             * @param length <code>int</code> length of data.
576:             * @throws SAXException
577:             */
578:            public void characters(char[] ch, int start, int length)
579:                    throws SAXException {
580:
581:                if (suppress || (length == 0))
582:                    return;
583:
584:                if (previousCDATA != inCDATA) {
585:                    flushCharacters();
586:                }
587:
588:                textBuffer.append(ch, start, length);
589:            }
590:
591:            /**
592:             * Capture ignorable whitespace as text.  If
593:             * setIgnoringElementContentWhitespace(true) has been called then this
594:             * method does nothing.
595:             *
596:             * @param ch <code>[]</code> - char array of ignorable whitespace
597:             * @param start <code>int</code> - starting position within array
598:             * @param length <code>int</code> - length of whitespace after start
599:             * @throws SAXException when things go wrong
600:             */
601:            public void ignorableWhitespace(char[] ch, int start, int length)
602:                    throws SAXException {
603:                if (!ignoringWhite) {
604:                    characters(ch, start, length);
605:                }
606:            }
607:
608:            /**
609:             * This will flush any characters from SAX character calls we've
610:             * been buffering.
611:             *
612:             * @throws SAXException when things go wrong
613:             */
614:            protected void flushCharacters() throws SAXException {
615:                flushCharacters(textBuffer.toString());
616:                textBuffer.clear();
617:            }
618:
619:            /**
620:             * Flush the given string into the document.  This is a protected method
621:             * so subclassers can control text handling without knowledge of the
622:             * internals of this class.
623:             *
624:             * @param data string to flush
625:             */
626:            protected void flushCharacters(String data) throws SAXException {
627:                if (data.length() == 0) {
628:                    previousCDATA = inCDATA;
629:                    return;
630:                }
631:
632:                /**
633:                 * This is commented out because of some problems with
634:                 * the inline DTDs that Xerces seems to have.
635:                 if (!inDTD) {
636:                 if (inEntity) {
637:                 getCurrentElement().setContent(factory.text(data));
638:                 } else {
639:                 getCurrentElement().addContent(factory.text(data));
640:                 }
641:                 */
642:
643:                if (previousCDATA) {
644:                    factory
645:                            .addContent(getCurrentElement(), factory
646:                                    .cdata(data));
647:                } else {
648:                    factory.addContent(getCurrentElement(), factory.text(data));
649:                }
650:
651:                previousCDATA = inCDATA;
652:            }
653:
654:            /**
655:             * Indicates the end of an element
656:             * (<code>&lt;/[element name]&gt;</code>) is reached.  Note that
657:             * the parser does not distinguish between empty
658:             * elements and non-empty elements, so this will occur uniformly.
659:             *
660:             * @param namespaceURI <code>String</code> URI of namespace this
661:             *                     element is associated with
662:             * @param localName <code>String</code> name of element without prefix
663:             * @param qName <code>String</code> name of element in XML 1.0 form
664:             * @throws SAXException when things go wrong
665:             */
666:            public void endElement(String namespaceURI, String localName,
667:                    String qName) throws SAXException {
668:
669:                if (suppress)
670:                    return;
671:
672:                flushCharacters();
673:
674:                if (!atRoot) {
675:                    Parent p = currentElement.getParent();
676:                    if (p instanceof  Document) {
677:                        atRoot = true;
678:                    } else {
679:                        currentElement = (Element) p;
680:                    }
681:                } else {
682:                    throw new SAXException(
683:                            "Ill-formed XML document (missing opening tag for "
684:                                    + localName + ")");
685:                }
686:            }
687:
688:            /**
689:             * This will signify that a DTD is being parsed, and can be
690:             * used to ensure that comments and other lexical structures
691:             * in the DTD are not added to the JDOM <code>Document</code>
692:             * object.
693:             *
694:             * @param name <code>String</code> name of element listed in DTD
695:             * @param publicID <code>String</code> public ID of DTD
696:             * @param systemID <code>String</code> system ID of DTD
697:             */
698:            public void startDTD(String name, String publicID, String systemID)
699:                    throws SAXException {
700:
701:                flushCharacters(); // Is this needed here?
702:
703:                factory.addContent(document, factory.docType(name, publicID,
704:                        systemID));
705:                inDTD = true;
706:                inInternalSubset = true;
707:            }
708:
709:            /**
710:             * This signifies that the reading of the DTD is complete.
711:             *
712:             * @throws SAXException
713:             */
714:            public void endDTD() throws SAXException {
715:
716:                document.getDocType().setInternalSubset(
717:                        internalSubset.toString());
718:                inDTD = false;
719:                inInternalSubset = false;
720:            }
721:
722:            public void startEntity(String name) throws SAXException {
723:                entityDepth++;
724:
725:                if (expand || entityDepth > 1) {
726:                    // Short cut out if we're expanding or if we're nested
727:                    return;
728:                }
729:
730:                // A "[dtd]" entity indicates the beginning of the external subset
731:                if (name.equals("[dtd]")) {
732:                    inInternalSubset = false;
733:                    return;
734:                }
735:
736:                // Ignore DTD references, and translate the standard 5
737:                if ((!inDTD) && (!name.equals("amp")) && (!name.equals("lt"))
738:                        && (!name.equals("gt")) && (!name.equals("apos"))
739:                        && (!name.equals("quot"))) {
740:
741:                    if (!expand) {
742:                        String pub = null;
743:                        String sys = null;
744:                        String[] ids = (String[]) externalEntities.get(name);
745:                        if (ids != null) {
746:                            pub = ids[0]; // may be null, that's OK
747:                            sys = ids[1]; // may be null, that's OK
748:                        }
749:                        /**
750:                         * if no current element, this entity belongs to an attribute
751:                         * in these cases, it is an error on the part of the parser
752:                         * to call startEntity but this will help in some cases.
753:                         * See org/xml/sax/ext/LexicalHandler.html#startEntity(java.lang.String)
754:                         * for more information
755:                         */
756:                        if (!atRoot) {
757:                            flushCharacters();
758:                            EntityRef entity = factory
759:                                    .entityRef(name, pub, sys);
760:
761:                            // no way to tell if the entity was from an attribute or element so just assume element
762:                            factory.addContent(getCurrentElement(), entity);
763:                        }
764:                        suppress = true;
765:                    }
766:                }
767:            }
768:
769:            public void endEntity(String name) throws SAXException {
770:                entityDepth--;
771:                if (entityDepth == 0) {
772:                    // No way are we suppressing if not in an entity,
773:                    // regardless of the "expand" value
774:                    suppress = false;
775:                }
776:                if (name.equals("[dtd]")) {
777:                    inInternalSubset = true;
778:                }
779:            }
780:
781:            /**
782:             * Report a CDATA section
783:             *
784:             * @throws SAXException
785:             */
786:            public void startCDATA() throws SAXException {
787:                if (suppress)
788:                    return;
789:
790:                inCDATA = true;
791:            }
792:
793:            /**
794:             * Report a CDATA section
795:             */
796:            public void endCDATA() throws SAXException {
797:                if (suppress)
798:                    return;
799:
800:                previousCDATA = true;
801:                inCDATA = false;
802:            }
803:
804:            /**
805:             * This reports that a comments is parsed.  If not in the
806:             * DTD, this comment is added to the current JDOM
807:             * <code>Element</code>, or the <code>Document</code> itself
808:             * if at that level.
809:             *
810:             * @param ch <code>ch[]</code> array of comment characters.
811:             * @param start <code>int</code> index to start reading from.
812:             * @param length <code>int</code> length of data.
813:             * @throws SAXException
814:             */
815:            public void comment(char[] ch, int start, int length)
816:                    throws SAXException {
817:
818:                if (suppress)
819:                    return;
820:
821:                flushCharacters();
822:
823:                String commentText = new String(ch, start, length);
824:                if (inDTD && inInternalSubset && (expand == false)) {
825:                    internalSubset.append("  <!--").append(commentText).append(
826:                            "-->\n");
827:                    return;
828:                }
829:                if ((!inDTD) && (!commentText.equals(""))) {
830:                    if (atRoot) {
831:                        factory.addContent(document, factory
832:                                .comment(commentText));
833:                    } else {
834:                        factory.addContent(getCurrentElement(), factory
835:                                .comment(commentText));
836:                    }
837:                }
838:            }
839:
840:            /**
841:             * Handle the declaration of a Notation in a DTD
842:             *
843:             * @param name name of the notation
844:             * @param publicID the public ID of the notation
845:             * @param systemID the system ID of the notation
846:             */
847:            public void notationDecl(String name, String publicID,
848:                    String systemID) throws SAXException {
849:
850:                if (!inInternalSubset)
851:                    return;
852:
853:                internalSubset.append("  <!NOTATION ").append(name);
854:                appendExternalId(publicID, systemID);
855:                internalSubset.append(">\n");
856:            }
857:
858:            /**
859:             * Handler for unparsed entity declarations in the DTD
860:             *
861:             * @param name <code>String</code> of the unparsed entity decl
862:             * @param publicID <code>String</code> of the unparsed entity decl
863:             * @param systemID <code>String</code> of the unparsed entity decl
864:             * @param notationName <code>String</code> of the unparsed entity decl
865:             */
866:            public void unparsedEntityDecl(String name, String publicID,
867:                    String systemID, String notationName) throws SAXException {
868:
869:                if (!inInternalSubset)
870:                    return;
871:
872:                internalSubset.append("  <!ENTITY ").append(name);
873:                appendExternalId(publicID, systemID);
874:                internalSubset.append(" NDATA ").append(notationName);
875:                internalSubset.append(">\n");
876:            }
877:
878:            /**
879:             * Appends an external ID to the internal subset buffer. Either publicID
880:             * or systemID may be null, but not both.
881:             *
882:             * @param publicID the public ID
883:             * @param systemID the system ID
884:             */
885:            private void appendExternalId(String publicID, String systemID) {
886:                if (publicID != null) {
887:                    internalSubset.append(" PUBLIC \"").append(publicID)
888:                            .append('\"');
889:                }
890:                if (systemID != null) {
891:                    if (publicID == null) {
892:                        internalSubset.append(" SYSTEM ");
893:                    } else {
894:                        internalSubset.append(' ');
895:                    }
896:                    internalSubset.append('\"').append(systemID).append('\"');
897:                }
898:            }
899:
900:            /**
901:             * Returns the being-parsed element.
902:             *
903:             * @return <code>Element</code> - element being built.
904:             * @throws SAXException
905:             */
906:            public Element getCurrentElement() throws SAXException {
907:                if (currentElement == null) {
908:                    throw new SAXException(
909:                            "Ill-formed XML document (multiple root elements detected)");
910:                }
911:                return currentElement;
912:            }
913:
914:            /**
915:             * Returns the the JDOM Attribute type value from the SAX 2.0
916:             * attribute type string provided by the parser.
917:             *
918:             * @param typeName <code>String</code> the SAX 2.0 attribute
919:             * type string.
920:             *
921:             * @return <code>int</code> the JDOM attribute type.
922:             *
923:             * @see Attribute#setAttributeType
924:             * @see Attributes#getType
925:             */
926:            private static int getAttributeType(String typeName) {
927:                Integer type = (Integer) (attrNameToTypeMap.get(typeName));
928:                if (type == null) {
929:                    if (typeName != null && typeName.length() > 0
930:                            && typeName.charAt(0) == '(') {
931:                        // Xerces 1.4.X reports attributes of enumerated type with
932:                        // a type string equals to the enumeration definition, i.e.
933:                        // starting with a parenthesis.
934:                        return Attribute.ENUMERATED_TYPE;
935:                    } else {
936:                        return Attribute.UNDECLARED_TYPE;
937:                    }
938:                } else {
939:                    return type.intValue();
940:                }
941:            }
942:
943:            /**
944:             * Receives an object for locating the origin of SAX document
945:             * events.  This method is invoked by the SAX parser.
946:             * <p>
947:             * {@link org.jdom.JDOMFactory} implementations can use the
948:             * {@link #getDocumentLocator} method to get access to the
949:             * {@link Locator} during parse.
950:             * </p>
951:             *
952:             * @param locator <code>Locator</code> an object that can return
953:             * the location of any SAX document event.
954:             */
955:            public void setDocumentLocator(Locator locator) {
956:                this .locator = locator;
957:            }
958:
959:            /**
960:             * Provides access to the {@link Locator} object provided by the
961:             * SAX parser.
962:             *
963:             * @return <code>Locator</code> an object that can return
964:             * the location of any SAX document event.
965:             */
966:            public Locator getDocumentLocator() {
967:                return locator;
968:            }
969:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.