Source Code Cross Referenced for XNIBuilder.java in  » IDE-Netbeans » xml » org » netbeans » tax » io » 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 » IDE Netbeans » xml » org.netbeans.tax.io 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.tax.io;
0043:
0044:        import java.io.*;
0045:        import java.net.URL;
0046:        import java.util.*;
0047:        import java.text.MessageFormat;
0048:        import java.lang.reflect.*;
0049:
0050:        import org.xml.sax.*;
0051:        import org.xml.sax.helpers.LocatorImpl;
0052:
0053:        import org.apache.xerces.xni.*;
0054:        import org.apache.xerces.xni.parser.XMLDTDSource;
0055:        import org.apache.xerces.xni.parser.XMLDTDContentModelSource;
0056:        import org.apache.xerces.xni.parser.XMLDocumentSource;
0057:        import org.apache.xerces.parsers.*;
0058:
0059:        import org.netbeans.tax.*;
0060:        import org.netbeans.tax.io.*;
0061:        import org.netbeans.tax.decl.*;
0062:        import java.util.List;
0063:
0064:        /**
0065:         * Xerces Native Interface ("XNI") based implementation. It sets
0066:         * namespace non-aware and non-validating features.
0067:         * <p>
0068:         * Do instantiate it directly, prefer TreeBuilder interface loaded  by TreeStreamSource
0069:         * (i.e. ParserLoader). It will do necessary implementation isolation.
0070:         * <p>
0071:         * Every well-formed source must be possible to convert to tree structure.
0072:         * //!!! A mechanism of supressing particular implemenation constrains will
0073:         * be needed (JAXP validation on request could be a good approach).
0074:         *
0075:         * @author  Petr Kuzel
0076:         * @version rewritten to XNI 2.4.0
0077:         */
0078:        public final class XNIBuilder implements  TreeBuilder {
0079:
0080:            private static final boolean ASSERT = false;
0081:
0082:            //      private static final PrintStream dbg = System.err;
0083:
0084:            private static final String DTD_WRAPPER = "<!DOCTYPE DTD PUBLIC \"{0}\" \"{1}\">"; // NOI18N
0085:
0086:            // TreeStreamSource defines
0087:            private Class buildClass; //DTD or XML [or Fragment]
0088:
0089:            private InputSource inputSource;
0090:
0091:            // interface for reporting errors during the tree construction
0092:            private TreeStreamBuilderErrorHandler errorHandler;
0093:
0094:            // do not forget to set to the parser
0095:            private EntityResolver entityResolver;
0096:
0097:            /** Creates new TreeStreamBuilderXercesImpl */
0098:            public XNIBuilder(Class buildClass, InputSource inputSource,
0099:                    EntityResolver entityResolver,
0100:                    TreeStreamBuilderErrorHandler errorHandler) {
0101:                init(buildClass, inputSource, entityResolver, errorHandler);
0102:            }
0103:
0104:            /** Initialize it */
0105:            private void init(Class buildClass, InputSource inputSource,
0106:                    EntityResolver entityResolver,
0107:                    TreeStreamBuilderErrorHandler errorHandler) {
0108:                this .inputSource = inputSource;
0109:                this .buildClass = buildClass;
0110:                this .errorHandler = errorHandler;
0111:                this .entityResolver = entityResolver;
0112:            }
0113:
0114:            /**
0115:             * Build new TreeDocument by delegating to private class (hiding its
0116:             * public XNI interfaces implementation).
0117:             */
0118:            public TreeDocumentRoot buildDocument() throws TreeException {
0119:
0120:                boolean buildXML = true;
0121:                InputSource builderSource = inputSource;
0122:                EntityResolver builderResolver = entityResolver;
0123:
0124:                /*
0125:                 * We are building DTD so wrap into auxiliary InputSource that
0126:                 * can be passed to XML parser.
0127:                 */
0128:                if (buildClass == TreeDTD.class) {
0129:
0130:                    String src = MessageFormat.format(DTD_WRAPPER,
0131:                            new Object[] { DTDEntityResolver.DTD_ID,
0132:                                    inputSource.getSystemId() });
0133:
0134:                    builderSource = new InputSource(inputSource.getSystemId());
0135:                    builderSource.setCharacterStream(new StringReader(src));
0136:
0137:                    builderResolver = new DTDEntityResolver();
0138:                    buildXML = false;
0139:                }
0140:
0141:                XMLBuilder builder = this .new XMLBuilder(buildXML);
0142:
0143:                try {
0144:                    final String SAX_FEATURE = "http://xml.org/sax/features/"; // NOI18N
0145:                    final String XERCES_FEATURE = "http://apache.org/xml/features/"; // NOI18N
0146:
0147:                    builder.setFeature(SAX_FEATURE + "namespaces", false); //!!! // NOI18N
0148:                    builder.setFeature(SAX_FEATURE + "validation", false); //!!! // NOI18N
0149:                    builder.setFeature(SAX_FEATURE
0150:                            + "external-general-entities", true); // NOI18N
0151:                    builder.setFeature(SAX_FEATURE
0152:                            + "external-parameter-entities", true); // NOI18N
0153:                    builder.setFeature(XERCES_FEATURE
0154:                            + "validation/warn-on-duplicate-attdef", true); // NOI18N
0155:                    // unrecognized in Xerces 2.4.0
0156:                    //builder.setFeature (XERCES_FEATURE + "validation/warn-on-undeclared-elemdef", true); // NOI18N
0157:                    builder.setFeature(XERCES_FEATURE + "allow-java-encodings",
0158:                            true); // NOI18N
0159:                    builder.setFeature(XERCES_FEATURE
0160:                            + "scanner/notify-char-refs", true); // NOI18N
0161:                    builder.setFeature(XERCES_FEATURE
0162:                            + "scanner/notify-builtin-refs", true); // NOI18N
0163:
0164:                    //            final String XERCES_PROPERTY = "http://apache.org/xml/properties/"; // NOI18N
0165:                    //            builder.setProperty(XERCES_PROPERTY + "internal/entity-resolver", builderResolver); // NOI18N
0166:
0167:                    builder.setEntityResolver(builderResolver);
0168:
0169:                    // the builder extends XNIDocumentParser that receives
0170:                    // error events directly
0171:
0172:                    builder.setErrorHandler(new ErrorHandler() {
0173:                        public void error(org.xml.sax.SAXParseException e) {
0174:                        }
0175:
0176:                        public void warning(org.xml.sax.SAXParseException e) {
0177:                        }
0178:
0179:                        public void fatalError(org.xml.sax.SAXParseException e) {
0180:                        }
0181:                    });
0182:                    builder.parse(builderSource);
0183:
0184:                } catch (DTDStopException stop) {
0185:
0186:                    // we just stopped the parser at the end of standalone DTD
0187:
0188:                } catch (SAXException sax) {
0189:
0190:                    // test whether wrapped exception is XNI one
0191:                    // if so it wrrap actual exception
0192:
0193:                    Exception exception = sax.getException();
0194:
0195:                    if ((exception instanceof  DTDStopException) == false) {
0196:
0197:                        if (Util.THIS.isLoggable()) /* then */
0198:                            Util.THIS.debug("sax", sax); // NOI18N
0199:                        if (Util.THIS.isLoggable()) /* then */
0200:                            Util.THIS.debug("exception", exception); // NOI18N
0201:
0202:                        if (exception instanceof  XNIException) {
0203:                            exception = ((XNIException) exception)
0204:                                    .getException();
0205:                        }
0206:                        if (exception != null) {
0207:                            if (!!!(exception instanceof  TreeException)) {
0208:                                exception = new TreeException(sax);
0209:                            }
0210:                        } else {
0211:                            exception = new TreeException(sax);
0212:                        }
0213:                        throw (TreeException) exception;
0214:                    }
0215:
0216:                } catch (IOException exc) {
0217:                    if (Util.THIS.isLoggable()) /* then */
0218:                        Util.THIS.debug("exc", exc); // NOI18N
0219:
0220:                    throw new TreeException(exc);
0221:                }
0222:
0223:                return builder.getDocumentRoot();
0224:            }
0225:
0226:            /*
0227:             * Resolve DTD to original InputSource, forward others.
0228:             * DTD builder uses wrapping InputSource so XML parser can be used as DTD one.
0229:             */
0230:            private class DTDEntityResolver implements  EntityResolver {
0231:
0232:                static final String DTD_ID = "PRIVATE//AUXILIARY DTD ID//PRIVATE"; // NOI18N
0233:
0234:                public InputSource resolveEntity(String publicId,
0235:                        String systemId) throws SAXException, IOException {
0236:
0237:                    if (DTD_ID.equals(publicId)) {
0238:                        return inputSource;
0239:                    } else {
0240:                        return entityResolver.resolveEntity(publicId, systemId);
0241:                    }
0242:                }
0243:
0244:            }
0245:
0246:            /*
0247:             * It is used to signal that we are parsing a DTD and we reached end of it.
0248:             * So we can stop the parser by throwing it.
0249:             */
0250:            private class DTDStopException extends XNIException {
0251:
0252:                /** Serial Version UID */
0253:                private static final long serialVersionUID = 4994054007367982021L;
0254:
0255:                public DTDStopException() {
0256:                    super ("This exception is used to signal end of DTD."); // NOI18N
0257:                };
0258:
0259:                //
0260:                // Look like wrapping exception, so it be converted so SAXException
0261:                // that wraps this one.
0262:                //
0263:                public Exception getException() {
0264:                    return this ;
0265:                }
0266:
0267:                public Throwable fillInStackTrace() {
0268:                    return this ;
0269:                }
0270:            }
0271:
0272:            // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0273:
0274:            /*
0275:             * A pipeline of document components starts with a document source; is
0276:             * followed by zero or more document filters; and ends with a document
0277:             * handler.
0278:             *
0279:             * The document handler follows.
0280:             */
0281:
0282:            /**
0283:             * Listens on XNI creating XML structure. It uses mini XNI pipe
0284:             * featuring just with scanner. A validator is used but validity
0285:             * are discarded since tree must be just well-formed ("WF").
0286:             */
0287:            private class XMLBuilder extends SAXParser implements 
0288:                    XMLDTDContentModelHandler, XMLDocumentHandler,
0289:                    XMLDTDHandler {
0290:
0291:                private TreeDocumentRoot returnDocument; // initial parent
0292:                private TreeDocumentRoot document; // tmp variable
0293:
0294:                private TreeDocumentType doctype; // it will become parent node of DTD content
0295:                private TreeNode tempNode; // current working node
0296:
0297:                private Stack parentObjectListStack; // parents' child lists stack
0298:                private TreeObjectList parentObjectList; // top of the stack
0299:                private Stack parentNodeStack; // some times we need nodes directly
0300:
0301:                private Stack elementStack; // ??? it could be avoided
0302:                private int entityCounter; // how deep we entered
0303:
0304:                private boolean isXMLDocument; // do we parser XML or standalone DTD
0305:                private boolean inCDATASection; // we are in the middle of CDATA
0306:                private boolean inDTD; // we are in DTD
0307:                private boolean isCorrect; // builder internal error
0308:                private boolean inCharacterRef; //
0309:
0310:                private StringBuffer cdataSectionBuffer; // working CDATA section buffer
0311:                private QName tmpQName = new QName(); // working Qname
0312:                private TreeAttlistDecl attlistDecl = null; // latest attlistdecl
0313:
0314:                private int errors = 0; // fatal error counter
0315:
0316:                private final String XML_ENTITY = "[xml]"; // name of entity that precedes startDocument call // NOI18N
0317:                private final String DTD_ENTITY = "[dtd]"; // external DTD entity name // NOI18N
0318:
0319:                private XMLLocator locator;
0320:
0321:                private boolean hasExternalDTD = false;
0322:
0323:                private RememberingReader rememberingReader;
0324:
0325:                private XMLDTDSource xmldtdSource; // XMLDTDHandler 2.4.0
0326:
0327:                private XMLDTDContentModelSource xmldtdContentModelSource; // XMLDTDContentModelHandler 2.4.0
0328:
0329:                private XMLDocumentSource xmlDocumentSource; // XMLDocumentHanlder 2.4.0
0330:
0331:                /**
0332:                 * Create a parser with standard configuration.
0333:                 * @param xmlDocument false if building standalone DTD
0334:                 */
0335:                public XMLBuilder(boolean xmlDocument) {
0336:                    isXMLDocument = xmlDocument;
0337:                    entityCounter = 0;
0338:                    isCorrect = false;
0339:                    inCDATASection = false;
0340:                    inDTD = false;
0341:                    parentObjectListStack = new Stack();
0342:                    parentNodeStack = new Stack();
0343:                    elementStack = new Stack(); //stacks all non-empty elements
0344:                    cdataSectionBuffer = new StringBuffer();
0345:                    inCharacterRef = false;
0346:                }
0347:
0348:                /**
0349:                 * Sample user reader replacing it by remebering one suitable for
0350:                 * internal DTD remebering.
0351:                 */
0352:                public void parse(InputSource in) throws IOException,
0353:                        SAXException {
0354:                    Reader reader = in.getCharacterStream();
0355:                    if (reader != null) {
0356:                        rememberingReader = new RememberingReader(reader);
0357:                        in.setCharacterStream(rememberingReader);
0358:                        rememberingReader.startRemembering(); //remember internal DTD see startElement for end
0359:                    }
0360:
0361:                    super .parse(in);
0362:                }
0363:
0364:                //
0365:                // XMLDocumentHandler methods
0366:                //
0367:
0368:                public XMLDocumentSource getDocumentSource() {
0369:                    return xmlDocumentSource;
0370:                }
0371:
0372:                public void setDocumentSource(XMLDocumentSource src) {
0373:                    xmlDocumentSource = src;
0374:                }
0375:
0376:                // XMLDocumentHandler 2.4.0
0377:                public void startDocument(XMLLocator locator, String encoding,
0378:                        NamespaceContext nsCtx, Augmentations a) {
0379:                    startDocument(locator, encoding, a);
0380:                }
0381:
0382:                /**
0383:                 * The start of the document.
0384:                 *
0385:                 * @throws SAXException Thrown by handler to signal an error.
0386:                 */
0387:                // XMLDocumentHandler 2.0.0b4
0388:                public void startDocument(XMLLocator locator, String encoding,
0389:                        Augmentations a) {
0390:
0391:                    trace("startDocument()"); // NOI18N
0392:
0393:                    this .locator = locator;
0394:                    try {
0395:                        returnDocument = document = new TreeDocument(null,
0396:                                null, null);
0397:                        pushParentNode((TreeDocument) document);
0398:                    } catch (TreeException exc) {
0399:                        throw new XNIException(exc);
0400:                    }
0401:                } // startDocument()
0402:
0403:                /**
0404:                 * Notifies of the presence of an XMLDecl line in the document. If
0405:                 * present, this method will be called immediately following the
0406:                 * startDocument call.
0407:                 *
0408:                 * @param version    The XML version.
0409:                 * @param encoding   The IANA encoding name of the document, or null if
0410:                 *                   not specified.
0411:                 * @param standalone The standalone value, or null if not specified.
0412:                 *
0413:                 * @throws SAXException Thrown by handler to signal an error.
0414:                 */
0415:                public void xmlDecl(String version, String encoding,
0416:                        String standalone, Augmentations a) {
0417:
0418:                    trace("xmlDecl()"); // NOI18N
0419:
0420:                    try {
0421:                        ((TreeDocument) document).setHeader(version, encoding,
0422:                                standalone);
0423:                    } catch (TreeException exc) {
0424:                        throw new XNIException(exc);
0425:                    }
0426:                } // xmlDecl(String,String,String)
0427:
0428:                // XMLDTDHandler 2.4.0 and XMLDocumentHandler > 2.0.0b4
0429:                public void textDecl(String version, String encoding,
0430:                        Augmentations a) {
0431:
0432:                    trace("textDecl()"); // NOI18N
0433:
0434:                    // if we are DTD parser scanning base DTD document entity
0435:                    if (isXMLDocument == false && inDTD && inEntity() == false) {
0436:                        try {
0437:                            ((TreeDTD) document).setHeader(version, encoding);
0438:                        } catch (TreeException ex) {
0439:                            throw new XNIException(ex);
0440:                        }
0441:                    }
0442:                }
0443:
0444:                // XMLDTDHAndler 2.0.0b4
0445:                public void textDecl(String version, String encoding) {
0446:                    textDecl(version, encoding, null);
0447:                }
0448:
0449:                /**
0450:                 * Notifies of the presence of the DOCTYPE line in the document.
0451:                 */
0452:                public void doctypeDecl(String rootElement, String publicId,
0453:                        String systemId, Augmentations a) {
0454:
0455:                    trace("doctypeDecl(" + rootElement + "," + publicId + ")"); // NOI18N
0456:
0457:                    try {
0458:                        TreeDocumentType _doctype = new TreeDocumentType(
0459:                                rootElement, publicId, systemId);
0460:                        setBeginPosition(_doctype);
0461:                        ((TreeDocument) document).setDocumentType(_doctype);
0462:
0463:                        doctype = _doctype;
0464:                    } catch (TreeException exc) {
0465:                        throw new XNIException(exc);
0466:                    }
0467:                } // doctypeDecl(String,String,String)
0468:
0469:                /**
0470:                 * The start of an element.
0471:                 */
0472:                public void startElement(QName element,
0473:                        XMLAttributes attributes, Augmentations a) {
0474:
0475:                    trace("startElement(" + element + ")"); // NOI18N
0476:
0477:                    try {
0478:                        tempNode = new TreeElement(element.rawname);
0479:                        startElementImpl((TreeElement) tempNode, attributes);
0480:
0481:                        pushParentNode((TreeElement) tempNode);
0482:                        elementStack.push(tempNode);
0483:
0484:                    } catch (TreeException exc) {
0485:                        throw new XNIException(exc);
0486:                    }
0487:                } // startElement(QName,XMLAttributes)
0488:
0489:                /**
0490:                 * This callback represents &lt;.....<b>/</b>&gt;.
0491:                 */
0492:                public void emptyElement(QName qName, XMLAttributes attributes,
0493:                        Augmentations a) {
0494:
0495:                    trace("emptyElement(" + qName + ")"); // NOI18N
0496:
0497:                    try {
0498:                        tempNode = new TreeElement(qName.rawname, true);
0499:                        startElementImpl((TreeElement) tempNode, attributes);
0500:                    } catch (TreeException exc) {
0501:                        throw new XNIException(exc);
0502:                    }
0503:                }
0504:
0505:                /**
0506:                 * Insert element and its attributes at hiearchy
0507:                 */
0508:                private void startElementImpl(TreeElement elem,
0509:                        XMLAttributes attributes) throws TreeException {
0510:
0511:                    setBeginPosition(elem);
0512:
0513:                    //??? is it really neccessary
0514:                    if (currentParentNode() instanceof  TreeDocument) {
0515:                        ((TreeDocument) currentParentNode())
0516:                                .setDocumentElement(elem);
0517:                    } else {
0518:                        appendChild(elem);
0519:                    }
0520:
0521:                    // handle attributes
0522:
0523:                    int attrCount = attributes.getLength();
0524:                    for (int i = 0; i < attrCount; i++) {
0525:                        boolean specified = attributes.isSpecified(i);
0526:
0527:                        if (specified == true) { // TEMPORARY -- not specified nodes will not be added into element
0528:
0529:                            attributes.getName(i, tmpQName); //fill tmpQName
0530:                            String val = attributes.getNonNormalizedValue(i); //???getNonNormalizedValue
0531:
0532:                            TreeAttribute attr; // to be filled
0533:
0534:                            if (val.indexOf('&') < 0) {
0535:
0536:                                attr = new TreeAttribute(tmpQName.rawname, val,
0537:                                        specified);
0538:
0539:                            } else {
0540:
0541:                                attr = new TreeAttribute(tmpQName.rawname, "",
0542:                                        specified); // NOI18N
0543:                                List list = attr.getValueList();
0544:                                list.clear();
0545:
0546:                                // build attribute value, split content as refs and text
0547:
0548:                                int lastOffset = 0; // offset
0549:                                for (int offset = val.indexOf('&'); offset >= 0; offset = val
0550:                                        .indexOf('&', offset + 1)) {
0551:
0552:                                    int endOffset = val.indexOf(';', offset);
0553:                                    String name = val.substring(offset + 1,
0554:                                            endOffset);
0555:
0556:                                    if (offset > lastOffset) {
0557:                                        // insert text
0558:                                        TreeText text = new TreeText(val
0559:                                                .substring(lastOffset, offset));
0560:                                        list.add(text);
0561:                                    }
0562:
0563:                                    if (name.startsWith("#")) { // NOI18N
0564:                                        TreeCharacterReference chref = new TreeCharacterReference(
0565:                                                name);
0566:                                        list.add(chref);
0567:                                    } else {
0568:                                        TreeGeneralEntityReference gref = new TreeGeneralEntityReference(
0569:                                                name);
0570:                                        list.add(gref);
0571:                                    }
0572:
0573:                                    lastOffset = endOffset + 1;
0574:                                }
0575:
0576:                                if (val.length() > lastOffset) {
0577:                                    String lastText = val.substring(lastOffset);
0578:                                    list.add(new TreeText(lastText));
0579:                                }
0580:                            }
0581:
0582:                            if (!!!specified) {
0583:                                setReadOnly(attr);
0584:                            }
0585:                            elem.addAttribute(attr);
0586:
0587:                        } // if ( specified == true )
0588:                    }
0589:
0590:                    // recall remenbered internal DTD  //!!!
0591:
0592:                    if (rememberingReader == null) {
0593:                        return;
0594:                    }
0595:                    StringBuffer mem = rememberingReader.stopRemembering();
0596:                    if (mem == null)
0597:                        return;
0598:
0599:                    String idtd = mem.toString();
0600:                    int start = -1, end = -1; // results
0601:                    int now, last = -1; // tmps
0602:                    char delimiter;
0603:
0604:                    if (Util.THIS.isLoggable()) /* then */
0605:                        Util.THIS
0606:                                .debug("TreeStreamBuilderXercesImpl: going to inspect:\n"
0607:                                        + idtd);
0608:
0609:                    // find out DOCTYPE declaration
0610:                    // #23197 eliminate doctypes in comment (simple aproximation)
0611:
0612:                    final String DOCTYPE = "<!DOCTYPE"; // NOI18N
0613:                    int pos = -1;
0614:                    DOCTYPE_LOOP: while (true) {
0615:                        pos = idtd.indexOf(DOCTYPE, ++pos);
0616:                        if (pos == -1) {
0617:                            Util.THIS.debug("XNIBuilder: no DOCTYPE detected."); // NOI18N
0618:                            return;
0619:                        } else {
0620:                            int comment = -1;
0621:                            while (true) {
0622:                                comment = idtd.indexOf("<!--", ++comment); // NOI18N
0623:                                if (comment != -1 && comment < pos) {
0624:                                    if (idtd.indexOf("-->", comment) > pos) { // NOI18N
0625:                                        // it is commented out, try another
0626:                                        break;
0627:                                    } else {
0628:                                        // commentd ends before, but it does not proof anything
0629:                                        continue;
0630:                                    }
0631:                                } else {
0632:                                    break DOCTYPE_LOOP;
0633:                                }
0634:                            }
0635:                        }
0636:                    }
0637:
0638:                    if (Util.THIS.isLoggable()) /* then */
0639:                        Util.THIS.debug("\nlast index = " + pos);
0640:
0641:                    // skip root element name
0642:
0643:                    pos += DOCTYPE.length();
0644:                    for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0645:                        ;
0646:                    for (; StringUtil.isWS(idtd.charAt(pos)) == false; pos++)
0647:                        ;
0648:                    for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0649:                        ;
0650:
0651:                    if (Util.THIS.isLoggable()) /* then */
0652:                        Util.THIS.debug("\nafter process index = " + pos);
0653:
0654:                    // SYSTEM or PUBLIC or [
0655:
0656:                    if (Util.THIS.isLoggable()) /* then */
0657:                        Util.THIS.debug("\nTesting DOCTYPE kind-----\n"
0658:                                + idtd.substring(pos));
0659:
0660:                    if (idtd.charAt(pos) == '[') { // just internal dtd
0661:                        start = ++pos;
0662:                    } else if (idtd.charAt(pos) == 'S') { //SYSTEM "" [
0663:                        for (; StringUtil.isWS(idtd.charAt(pos)) == false; pos++)
0664:                            ;
0665:                        for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0666:                            ;
0667:                        delimiter = idtd.charAt(pos++);
0668:                        for (; idtd.charAt(pos) != delimiter; pos++)
0669:                            ;
0670:                        pos++;
0671:                        for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0672:                            ;
0673:                        if (idtd.charAt(pos) == '[') {
0674:                            start = ++pos;
0675:                        }
0676:                    } else if (idtd.charAt(pos) == 'P') { // PUBLIC "" "" [
0677:                        for (; StringUtil.isWS(idtd.charAt(pos)) == false; pos++)
0678:                            ;
0679:                        for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0680:                            ;
0681:                        delimiter = idtd.charAt(pos++);
0682:                        for (; idtd.charAt(pos) != delimiter; pos++)
0683:                            ;
0684:                        pos++;
0685:                        for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0686:                            ;
0687:                        delimiter = idtd.charAt(pos++);
0688:                        for (; idtd.charAt(pos) != delimiter; pos++)
0689:                            ;
0690:                        pos++;
0691:                        for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0692:                            ;
0693:                        if (idtd.charAt(pos) == '[') {
0694:                            start = ++pos;
0695:                        }
0696:                    }
0697:
0698:                    if (start == -1) {
0699:                        if (Util.THIS.isLoggable()) /* then */
0700:                            Util.THIS
0701:                                    .debug("TreeStreamBuilderXercesImpl: it does not have internal DTD.");
0702:
0703:                        return;
0704:                    } else {
0705:                        if (Util.THIS.isLoggable()) /* then */
0706:                            Util.THIS.debug("\n---Analyzing internal DTD:\n"
0707:                                    + idtd.substring(start));
0708:                    }
0709:
0710:                    // search for internal DTD end
0711:
0712:                    for (last = pos - 1; idtd.startsWith("]>", pos) == false
0713:                            && last < pos;) {
0714:
0715:                        last = pos;
0716:
0717:                        // skip comments and WS
0718:                        for (; StringUtil.isWS(idtd.charAt(pos)); pos++)
0719:                            ;
0720:
0721:                        now = StringUtil
0722:                                .skipDelimited(idtd, pos, "<!--", "-->");
0723:                        if (now != -1) {
0724:                            pos = now;
0725:                            continue;
0726:                        }
0727:
0728:                        // skip PIs
0729:                        now = StringUtil.skipDelimited(idtd, pos, "<?", "?>");
0730:                        if (now != -1) {
0731:                            pos = now;
0732:                            continue;
0733:                        }
0734:
0735:                        // skip decls
0736:                        now = StringUtil.skipDelimited(idtd, pos, '<', '>',
0737:                                "\"'");
0738:                        if (now != -1) {
0739:                            pos = now;
0740:                            continue;
0741:                        }
0742:
0743:                        // skip references
0744:                        now = StringUtil.skipDelimited(idtd, pos, '%', ';', "");
0745:                        if (now != -1) {
0746:                            pos = now;
0747:                            continue;
0748:                        }
0749:
0750:                    }
0751:
0752:                    if (last == pos) {
0753:                        if (Util.THIS.isLoggable()) /* then */
0754:                            Util.THIS
0755:                                    .debug("TreeStreamBuilderXercesImpl: end not reached");
0756:
0757:                        return;
0758:                    }
0759:
0760:                    String internalDTDText = idtd.substring(start, pos);
0761:
0762:                    if (Util.THIS.isLoggable()) /* then */
0763:                        Util.THIS.debug("Internal DTD:" + internalDTDText
0764:                                + "\n--");
0765:
0766:                    // use introspectio to set it
0767:
0768:                    try {
0769:                        if (doctype == null)
0770:                            return;
0771:                        Class klass = doctype.getClass();
0772:                        Field field = klass.getDeclaredField("internalDTDText");
0773:                        field.setAccessible(true);
0774:                        field.set(doctype, internalDTDText);
0775:                    } catch (RuntimeException ex) {
0776:                        throw ex;
0777:                    } catch (Exception ex) {
0778:                        // ignore introspection exceptions
0779:                        if (Util.THIS.isLoggable()) /* then */
0780:                            Util.THIS
0781:                                    .debug(
0782:                                            "TreeStreamBuilderXercesImpl.settingInternaDTDText",
0783:                                            ex);
0784:                    }
0785:
0786:                }
0787:
0788:                /**
0789:                 * Character content.
0790:                 */
0791:                public void characters(XMLString text, Augmentations a) {
0792:
0793:                    try {
0794:                        if (inCharacterRef == true)
0795:                            return; // ignore resolved
0796:
0797:                        if (inDTD) {
0798:                            if (currentParentNode() instanceof  TreeConditionalSection) {
0799:                                if (Util.THIS.isLoggable()) /* then */
0800:                                    Util.THIS
0801:                                            .debug("\n*** TreeStreamBuilderXercesImpl::characters: XMLString = '"
0802:                                                    + text + "'"); // NOI18N
0803:
0804:                                ((TreeConditionalSection) currentParentNode())
0805:                                        .setIgnoredContent(text.toString());
0806:                            }
0807:                        } else if (inCDATASection) {
0808:                            cdataSectionBuffer.append(text.toString());
0809:                        } else {
0810:                            tempNode = new TreeText(text.toString());
0811:                            setBeginPosition(tempNode);
0812:                            appendChild((TreeText) tempNode);
0813:                        }
0814:                    } catch (TreeException exc) {
0815:                        throw new XNIException(exc);
0816:                    }
0817:                } // characters(XMLString)
0818:
0819:                // XMLDTDHandler 2.4.0
0820:                public void ignoredCharacters(XMLString text, Augmentations a) {
0821:                    characters(text, null);
0822:                }
0823:
0824:                // XMLDTDHandler 2.0.0b4
0825:                public void characters(XMLString text) {
0826:                    characters(text, null);
0827:                }
0828:
0829:                /**
0830:                 * Ignorable whitespace.
0831:                 */
0832:                public void ignorableWhitespace(XMLString text, Augmentations a) {
0833:                    try {
0834:                        tempNode = new TreeText(text.toString()); //???
0835:                        setBeginPosition(tempNode);
0836:                        appendChild((TreeText) tempNode);
0837:                    } catch (TreeException exc) {
0838:                        throw new XNIException(exc);
0839:                    }
0840:                } // ignorableWhitespace(XMLString)
0841:
0842:                /**
0843:                 * The end of an element.
0844:                 */
0845:                public void endElement(QName element, Augmentations a) {
0846:                    trace("endElement(" + element + ")"); // NOI18N
0847:
0848:                    try {
0849:                        TreeElement el = (TreeElement) elementStack.pop();
0850:                        el.normalize(); //??? parser return multiline text as multiple characters()
0851:                        popParentNode();
0852:                    } catch (TreeException exc) {
0853:                        throw new XNIException(exc);
0854:                    }
0855:                } // endElement(QName)
0856:
0857:                /**
0858:                 * The start of a CDATA section. Buffer its content.
0859:                 */
0860:                public void startCDATA(Augmentations a) {
0861:                    inCDATASection = true;
0862:                    cdataSectionBuffer.delete(0, cdataSectionBuffer.length());
0863:                    //!!! save position
0864:                } // startCDATA()
0865:
0866:                /**
0867:                 * The end of a CDATA section.
0868:                 */
0869:                public void endCDATA(Augmentations a) {
0870:
0871:                    inCDATASection = false;
0872:
0873:                    try {
0874:                        tempNode = new TreeCDATASection(cdataSectionBuffer
0875:                                .toString());
0876:                        setBeginPosition(tempNode); //!!! error
0877:                        appendChild((TreeCDATASection) tempNode);
0878:                    } catch (TreeException exc) {
0879:                        throw new XNIException(exc);
0880:                    }
0881:                } // endCDATA()
0882:
0883:                /**
0884:                 * The end of the document.
0885:                 */
0886:                public void endDocument(Augmentations a) {
0887:                    trace("endDocument()"); // NOI18N
0888:
0889:                    if (parentObjectListStack.isEmpty() == false) {
0890:                        if (Util.THIS.isLoggable()) /* then */
0891:                            Util.THIS.debug("Inconsistency at parentStack: "
0892:                                    + parentObjectListStack); // NOI18N
0893:                    } else if (elementStack.isEmpty() == false) {
0894:                        if (Util.THIS.isLoggable()) /* then */
0895:                            Util.THIS.debug("Inconsistency at elementStack: "
0896:                                    + parentObjectListStack); // NOI18N
0897:                    } else {
0898:                        isCorrect = true;
0899:                    }
0900:                } // endDocument()
0901:
0902:                //
0903:                // XMLDocumentHandler and XMLDTDHandler methods
0904:                //
0905:
0906:                public void endPrefixMapping(String prefix, Augmentations a) {
0907:                    // not interested
0908:                }
0909:
0910:                public void startPrefixMapping(String prefix, String uri,
0911:                        Augmentations a) {
0912:                    // not interested
0913:                }
0914:
0915:                // XMLDTDHandler 2.4.0
0916:                public void startExternalSubset(XMLResourceIdentifier entity,
0917:                        Augmentations a) {
0918:                    startEntity("[dtd]", entity.getPublicId(), entity
0919:                            .getLiteralSystemId(), entity.getBaseSystemId(),
0920:                            null, a);
0921:                }
0922:
0923:                public void startGeneralEntity(String name,
0924:                        XMLResourceIdentifier entity, String encoding,
0925:                        Augmentations a) {
0926:                    startEntity(name, entity.getPublicId(), entity
0927:                            .getLiteralSystemId(), entity.getBaseSystemId(),
0928:                            encoding, a);
0929:                }
0930:
0931:                /**
0932:                 * This method notifies of the start of an entity. The document entity
0933:                 * has the pseudo-name of "[xml]"; The DTD has the pseudo-name of "[dtd];
0934:                 * parameter entity names start with '%'; and general entity names are
0935:                 * just the entity name.
0936:                 *
0937:                 * @param encoding special value of "IGNORE" markg parameter
0938:                 *        entities in DTD markup (these are ignored)
0939:                 */
0940:                private void startEntity(String name, String publicId,
0941:                        String systemId, String baseSystemId, String encoding,
0942:                        Augmentations a) {
0943:
0944:                    trace("startEntity(" + name + ")"); // NOI18N
0945:
0946:                    try {
0947:
0948:                        // do not theat these as external entities
0949:                        // DTD is wrapped intentionally
0950:
0951:                        if (XML_ENTITY.equals(name))
0952:                            return;
0953:                        if (isXMLDocument == false && DTD_ENTITY.equals(name))
0954:                            return;
0955:
0956:                        if (DTD_ENTITY.equals(name) && isXMLDocument) {
0957:
0958:                            hasExternalDTD = true;
0959:
0960:                            // we are entering external DTD attach all to DOCTYPE ObjectList
0961:                            // There is performance optimalization: External DTD model
0962:                            // can be shared among several instances referring it.
0963:                            // It's currently managed by the TreeDocumentType class
0964:                            TreeObjectList external = doctype.getExternalDTD();
0965:                            if (external == null) {
0966:                                TreeDTDFragment entity = new TreeDTDFragment();
0967:                                TreeObjectList holder = entity.getChildNodes();
0968:                                pushParentObjectList(holder);
0969:                                doctype.setExternalDTD(entity);
0970:                            } else {
0971:                                // It was already parsed, ignore its content
0972:                                pushParentObjectList(null);
0973:                            }
0974:
0975:                        } else if (name.startsWith("#")) { // NOI18N
0976:
0977:                            tempNode = new TreeCharacterReference(name);
0978:                            appendChild(tempNode);
0979:                            setBeginPosition(tempNode);
0980:                            inCharacterRef = true;
0981:
0982:                        } else if ("lt".equals(name) || "gt".equals(name)
0983:                                || "amp".equals(name) // NOI18N
0984:                                || "apos".equals(name) || "quot".equals(name)) { // NOI18N
0985:
0986:                            tempNode = new TreeGeneralEntityReference(name);
0987:                            appendChild(tempNode);
0988:                            setBeginPosition(tempNode);
0989:                            inCharacterRef = true;
0990:
0991:                        } else if (name.startsWith("%")) { // NOI18N
0992:
0993:                            if ("IGNORE".equals(encoding)) { // NOI18N
0994:                                // skip entities in markup, place the into unattached list
0995:                                name = name.substring(1);
0996:                                pushParentNode(new TreeParameterEntityReference(
0997:                                        name));
0998:
0999:                            } else {
1000:                                name = name.substring(1);
1001:                                tempNode = new TreeParameterEntityReference(
1002:                                        name); //??? external entities
1003:                                appendChild((TreeParameterEntityReference) tempNode);
1004:                                setBeginPosition(tempNode);
1005:                                pushParentNode((TreeEntityReference) tempNode);
1006:                            }
1007:
1008:                        } else {
1009:
1010:                            tempNode = new TreeGeneralEntityReference(name); //??? external entities
1011:                            appendChild((TreeGeneralEntityReference) tempNode);
1012:                            setBeginPosition(tempNode);
1013:                            pushParentNode((TreeEntityReference) tempNode);
1014:
1015:                        }
1016:
1017:                        enterEntity();
1018:
1019:                    } catch (TreeException exc) {
1020:                        throw new XNIException(exc);
1021:                    }
1022:                } // startEntity(String,String,String,String)
1023:
1024:                // XMLDTDHandler 2.0.0b4
1025:                public void startEntity(String name, String publicId,
1026:                        String systemId, String baseSystemId, String encoding) {
1027:                    startEntity(name, publicId, systemId, baseSystemId,
1028:                            encoding, null);
1029:                }
1030:
1031:                // XMLDTDHanlder 2.4.0
1032:                public void startParameterEntity(String name,
1033:                        XMLResourceIdentifier entity, String encoding,
1034:                        Augmentations a) {
1035:                    String pname = name;
1036:                    if (false == name.startsWith("%")) {
1037:                        pname = "%" + name;
1038:                    }
1039:                    startEntity(pname, entity.getPublicId(), entity
1040:                            .getLiteralSystemId(), entity.getBaseSystemId(),
1041:                            encoding, a);
1042:                }
1043:
1044:                /**
1045:                 * A comment.
1046:                 */
1047:                // XMLDTDHandler 2.4.0 and XMLDocumentHandler
1048:                public void comment(XMLString text, Augmentations a) {
1049:
1050:                    trace("comment()"); // NOI18N
1051:
1052:                    try {
1053:                        tempNode = new TreeComment(text.toString());
1054:                        setBeginPosition(tempNode);
1055:                        appendChild((TreeComment) tempNode);
1056:                    } catch (TreeException exc) {
1057:                        throw new XNIException(exc);
1058:                    }
1059:                } // comment(XMLString)
1060:
1061:                // XMLDTDHandler 2.0.0b4
1062:                public void comment(XMLString text) {
1063:                    comment(text, null);
1064:                }
1065:
1066:                /**
1067:                 * A processing instruction. Processing instructions consist of a
1068:                 * target name and, optionally, text data. The data is only meaningful
1069:                 * to the application.
1070:                 */
1071:                // XMLDTDHandler 2.4.0 and XMLDocumentHandler > 2.0.0b4
1072:                public void processingInstruction(String target,
1073:                        XMLString data, Augmentations a) {
1074:
1075:                    trace("processingInstruction(" + target + ")"); // NOI18N
1076:
1077:                    try {
1078:                        tempNode = new TreeProcessingInstruction(target, data
1079:                                .toString());
1080:                        setBeginPosition(tempNode);
1081:                        appendChild((TreeProcessingInstruction) tempNode);
1082:                    } catch (TreeException exc) {
1083:                        throw new XNIException(exc);
1084:                    }
1085:                } // processingInstruction(String,XMLString)
1086:
1087:                // XMLDTDHandler 2.0.0b4
1088:                public void processingInstruction(String target, XMLString data) {
1089:                    processingInstruction(target, data, null);
1090:                }
1091:
1092:                // XMLDTDHandler 2.4.0
1093:                public void endExternalSubset(Augmentations a) {
1094:                    endEntity("[dtd]", a);
1095:                }
1096:
1097:                // XMLDTDHandler 2.4.0
1098:                public void endParameterEntity(String name, Augmentations a) {
1099:                    String pname = name;
1100:                    if (false == name.startsWith("%")) {
1101:                        pname = "%" + name;
1102:                    }
1103:                    endEntity(pname, a);
1104:                }
1105:
1106:                public void endGeneralEntity(String name, Augmentations a) {
1107:                    endEntity(name, a);
1108:                }
1109:
1110:                /**
1111:                 * This method notifies the end of an entity. The document entity has
1112:                 * the pseudo-name of "[xml]"; the DTD has the pseudo-name of "[dtd];
1113:                 * parameter entity names start with '%'; and general entity names are
1114:                 * just the entity name.
1115:                 */
1116:                private void endEntity(String name, Augmentations a) {
1117:                    trace("endEntity(" + name + ")"); // NOI18N
1118:
1119:                    // skip for root entities of XML documents and
1120:                    // standalone DTDs parsed by DTD parser
1121:
1122:                    if (XML_ENTITY.equals(name))
1123:                        return;
1124:                    if (isXMLDocument == false && DTD_ENTITY.equals(name))
1125:                        return;
1126:
1127:                    exitEntity();
1128:
1129:                    if (inCharacterRef == true) {
1130:                        inCharacterRef = false;
1131:                        return;
1132:                    }
1133:
1134:                    if (isXMLDocument && DTD_ENTITY.equals(name)) {
1135:                        popParentObjectList(); // DOCTYPE ObjectList
1136:                    } else {
1137:                        popParentNode();
1138:                    }
1139:
1140:                } // endEntity(String)
1141:
1142:                //??? DTDHandler
1143:                public void endEntity(String name) {
1144:                    endEntity(name, null);
1145:                }
1146:
1147:                // XMLDTDHandler methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1148:
1149:                // XMLDTDHandler 2.4.0
1150:                public XMLDTDSource getDTDSource() {
1151:                    return xmldtdSource;
1152:                }
1153:
1154:                // XMLDTDHandler 2.4.0
1155:                public void setDTDSource(XMLDTDSource src) {
1156:                    xmldtdSource = src;
1157:                }
1158:
1159:                // XMLDTDHandler 2.0.0b4
1160:                public void startDTD(XMLLocator locator, Augmentations a) {
1161:                    startDTD(locator);
1162:                }
1163:
1164:                /**
1165:                 * The start of the DTD (external part of it is reported by startEntity).
1166:                 */
1167:                // XMLDTDHandler 2.0.0b4
1168:                public void startDTD(XMLLocator locator) {
1169:                    trace("startDTD()"); // NOI18N
1170:
1171:                    try {
1172:                        inDTD = true;
1173:
1174:                        if (isXMLDocument) {
1175:
1176:                            pushParentNode(doctype);
1177:
1178:                        } else {
1179:
1180:                            // replace returnDocument
1181:                            returnDocument = document = new TreeDTD(null, null);
1182:                            pushParentNode((TreeDTD) document);
1183:                        }
1184:                    } catch (TreeException exc) {
1185:                        throw new XNIException(exc);
1186:                    }
1187:                } // startDTD()
1188:
1189:                // XMLDTDHandler 2.4.0
1190:                public void elementDecl(String name, String contentModel,
1191:                        Augmentations a) {
1192:                    elementDecl(name, contentModel);
1193:                }
1194:
1195:                /**
1196:                 * An element declaration.
1197:                 */
1198:                // XMLDTDHandler 2.0.0b4
1199:                public void elementDecl(String name, String cM) {
1200:                    trace("elementDecl(" + name + ")"); // NOI18N
1201:                    if (ASSERT)
1202:                        doAssert(inDTD);
1203:
1204:                    try {
1205:                        appendChild(new TreeElementDecl(name, this .contentModel));
1206:                        this .contentModel = null;
1207:                    } catch (TreeException exc) {
1208:                        throw new XNIException(exc);
1209:                    }
1210:
1211:                } // elementDecl(String,String)
1212:
1213:                // XMLDTDHandler 2.4.0
1214:                public void startAttlist(String elementName, Augmentations a) {
1215:                    startAttlist(elementName);
1216:                }
1217:
1218:                /**
1219:                 * The start of an attribute list.
1220:                 */
1221:                // XMLDTDHandler 2.0.0b4
1222:                public void startAttlist(String elementName) {
1223:
1224:                    trace("startAttlist(" + elementName + ")"); // NOI18N
1225:
1226:                    try {
1227:                        tempNode = new TreeAttlistDecl(elementName);
1228:                        attlistDecl = (TreeAttlistDecl) tempNode;
1229:                        appendChild(attlistDecl);
1230:                    } catch (TreeException exc) {
1231:                        throw new XNIException(exc);
1232:                    }
1233:                } // startAttlist(String)
1234:
1235:                // XMLDTDHandler 2.4.0
1236:                public void attributeDecl(String elementName,
1237:                        String attributeName, String type,
1238:                        String[] enumeration, String defaultType,
1239:                        XMLString defaultValue,
1240:                        XMLString nonNormalizedDefaultValue, Augmentations a) {
1241:                    attributeDecl(elementName, attributeName, type,
1242:                            enumeration, defaultType, defaultValue);
1243:                }
1244:
1245:                /**
1246:                 * An attribute declaration.
1247:                 */
1248:                // XMLDTDHandler 2.0.0b4
1249:                public void attributeDecl(String elementName,
1250:                        String attributeName, String type,
1251:                        String[] enumeration, String defaultType,
1252:                        XMLString defaultValue) {
1253:
1254:                    trace("attributeDecl(" + attributeName + ")"); // NOI18N
1255:
1256:                    try {
1257:                        TreeAttlistDecl list;
1258:
1259:                        if (attlistDecl != null) {
1260:                            list = attlistDecl;
1261:                        } else {
1262:                            list = new TreeAttlistDecl(elementName);
1263:                        }
1264:                        if (type.equals("ENUMERATION")) { // NOI18N
1265:                            type = null;
1266:                        }
1267:
1268:                        short shortDefaultType = TreeAttlistDeclAttributeDef
1269:                                .findDefaultType(defaultType);
1270:                        String newDefaultValue = null;
1271:                        if ((shortDefaultType == TreeAttlistDeclAttributeDef.DEFAULT_TYPE_NULL)
1272:                                || (shortDefaultType == TreeAttlistDeclAttributeDef.DEFAULT_TYPE_FIXED)) {
1273:                            newDefaultValue = defaultValue.toString();
1274:                        }
1275:                        TreeAttlistDeclAttributeDef decl = new TreeAttlistDeclAttributeDef(
1276:                                attributeName, TreeAttlistDeclAttributeDef
1277:                                        .findType(type), enumeration,
1278:                                shortDefaultType, newDefaultValue);
1279:
1280:                        list.setAttributeDef(decl);
1281:                    } catch (TreeException exc) {
1282:                        //Util.dumpContext("TreeAttlistDecl.setReadOnly(true)"); // NOI18N
1283:                        throw new XNIException(exc);
1284:                    }
1285:                } // attributeDecl(String,String,String,String[],String,XMLString)
1286:
1287:                // XMLDTDHandler 2.4.0
1288:                public void endAttlist(Augmentations a) {
1289:                    endAttlist();
1290:                }
1291:
1292:                /**
1293:                 * The end of an attribute list.
1294:                 */
1295:                // XMLDTDHandler 2.0.0b4
1296:                public void endAttlist() {
1297:
1298:                    trace("endAttlist()"); // NOI18N
1299:
1300:                    attlistDecl = null;
1301:                } // endAttlist()
1302:
1303:                // XMLDTDHandler 2.4.0
1304:                public void internalEntityDecl(String name, XMLString text,
1305:                        XMLString nonNormalizedText, Augmentations a) {
1306:                    internalEntityDecl(name, text, nonNormalizedText);
1307:                }
1308:
1309:                /**
1310:                 * An internal entity declaration.
1311:                 *
1312:                 * @param name The name of the entity. Parameter entity names start with
1313:                 *             '%', whereas the name of a general entity is just the
1314:                 *             entity name.
1315:                 */
1316:                // XMLDTDHandler 2.0.0b4
1317:                public void internalEntityDecl(String name, XMLString text,
1318:                        XMLString nonNormalizedText) {
1319:
1320:                    trace("internalEntityDecl(" + name + ")"); // NOI18N
1321:
1322:                    try {
1323:                        boolean par = name.startsWith("%"); // NOI18N
1324:                        if (par) {
1325:                            name = name.substring(1);
1326:                        }
1327:                        appendChild(new TreeEntityDecl(par, name, text
1328:                                .toString()));
1329:                    } catch (TreeException exc) {
1330:                        throw new XNIException(exc);
1331:                    }
1332:                } // internalEntityDecl(String,XMLString)
1333:
1334:                // XMLDTDHandler 2.4.0
1335:                public void externalEntityDecl(String name, String publicId,
1336:                        String systemId, String baseSystemId, Augmentations a) {
1337:                    externalEntityDecl(name, publicId, systemId, baseSystemId);
1338:                }
1339:
1340:                /**
1341:                 * An external entity declaration.
1342:                 *
1343:                 * @param name     The name of the entity. Parameter entity names start
1344:                 *                 with '%', whereas the name of a general entity is just
1345:                 *                 the entity name.
1346:                 */
1347:                // XMLDTDHandler 2.0.0b4
1348:                public void externalEntityDecl(String name, String publicId,
1349:                        String systemId, String baseSystemId) {
1350:
1351:                    trace("externalEntityDecl(" + name + ")"); // NOI18N
1352:
1353:                    try {
1354:                        boolean par = name.startsWith("%"); // NOI18N
1355:                        if (par) {
1356:                            name = name.substring(1);
1357:                        }
1358:
1359:                        appendChild(new TreeEntityDecl(par, name, publicId,
1360:                                systemId));
1361:                    } catch (TreeException exc) {
1362:                        throw new XNIException(exc);
1363:                    }
1364:                } // externalEntityDecl(String,String,String)
1365:
1366:                // XMLDTDHAnlder 2.4.0
1367:                public void unparsedEntityDecl(String name, String publicId,
1368:                        String systemId, String notation, Augmentations a) {
1369:                    unparsedEntityDecl(name, publicId, systemId, notation);
1370:                }
1371:
1372:                /**
1373:                 * An unparsed entity declaration.
1374:                 */
1375:                // XMLDTDHAnlder 2.0.0b4
1376:                public void unparsedEntityDecl(String name, String publicId,
1377:                        String systemId, String notation) {
1378:
1379:                    trace("unparsedEntityDecl(" + name + ")"); // NOI18N
1380:
1381:                    try {
1382:                        appendChild(new TreeEntityDecl(name, publicId,
1383:                                systemId, notation));
1384:                    } catch (TreeException exc) {
1385:                        throw new XNIException(exc);
1386:                    }
1387:                } // unparsedEntityDecl(String,String,String,String)
1388:
1389:                // XMLDTDHandler 2.4.0
1390:                public void notationDecl(String name, String publicId,
1391:                        String systemId, Augmentations a) {
1392:                    notationDecl(name, publicId, systemId);
1393:                }
1394:
1395:                /**
1396:                 * A notation declaration
1397:                 */
1398:                // XMLDTDHandler 2.0.0b4
1399:                public void notationDecl(String name, String publicId,
1400:                        String systemId) {
1401:
1402:                    trace("notationDecl(" + name + ")"); // NOI18N
1403:
1404:                    try {
1405:                        appendChild(new TreeNotationDecl(name, publicId,
1406:                                systemId));
1407:                    } catch (TreeException exc) {
1408:                        throw new XNIException(exc);
1409:                    }
1410:                } // notationDecl(String,String,String)
1411:
1412:                // XMLDTDHandler 2.4.0
1413:                public void startConditional(short type, Augmentations a) {
1414:                    startConditional(type);
1415:                }
1416:
1417:                /**
1418:                 * The start of a conditional section.
1419:                 *
1420:                 * @param type The type of the conditional section. This value will
1421:                 *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
1422:                 */
1423:                // XMLDTDHandler 2.0.0b4
1424:                public void startConditional(short type) {
1425:                    trace("startConditional(" + type + ")"); // NOI18N
1426:                    if (ASSERT)
1427:                        doAssert(inDTD);
1428:
1429:                    if (type == CONDITIONAL_INCLUDE) {
1430:                        tempNode = new TreeConditionalSection(true);
1431:                    } else {
1432:                        tempNode = new TreeConditionalSection(false);
1433:                    }
1434:
1435:                    appendChild((TreeConditionalSection) tempNode);
1436:                    setBeginPosition(tempNode);
1437:                    pushParentNode((TreeConditionalSection) tempNode);
1438:
1439:                } // startConditional(short)
1440:
1441:                // XMLDTDHandler 2.4.0
1442:                public void endConditional(Augmentations a) {
1443:                    endConditional();
1444:                }
1445:
1446:                /**
1447:                 * The end of a conditional section.
1448:                 */
1449:                // XMLDTDHandler 2.0.0b4
1450:                public void endConditional() {
1451:                    trace("endConditional()"); // NOI18N
1452:
1453:                    popParentNode();
1454:                } // endConditional()
1455:
1456:                // XMLDTDHandler 2.4.0
1457:                public void endDTD(Augmentations a) {
1458:                    endDTD();
1459:                }
1460:
1461:                /**
1462:                 * The end of the DTD.
1463:                 *
1464:                 * @throws SAXException Thrown by handler to signal an error.
1465:                 */
1466:                // XMLDTDHandler 2.0.0b4
1467:                public void endDTD() {
1468:                    trace("endDTD()"); // NOI18N
1469:
1470:                    if (isXMLDocument) {
1471:
1472:                        popParentNode();
1473:
1474:                    } else {
1475:
1476:                        popParentNode();
1477:
1478:                        //??? Xerces miss '<' at the end of entity
1479:                        // so such documents are reported as correct
1480:
1481:                        isCorrect = errors == 0;
1482:                        throw new DTDStopException();
1483:
1484:                    }
1485:
1486:                    inDTD = false;
1487:                } // endDTD()
1488:
1489:                // Content Model parser ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1490:
1491:                private TreeElementDecl.ContentType lastType; // occurence operators are applied on this
1492:                private TreeElementDecl.ContentType contentModel; // OUTPUT result field
1493:                private Stack contentModelMembersStack; // stack of parent group members
1494:
1495:                public XMLDTDContentModelSource getDTDContentModelSource() {
1496:                    return xmldtdContentModelSource;
1497:                }
1498:
1499:                public void setDTDContentModelSource(
1500:                        XMLDTDContentModelSource src) {
1501:                    xmldtdContentModelSource = src;
1502:                }
1503:
1504:                public void startContentModel(String elementName,
1505:                        Augmentations a) {
1506:
1507:                    if (Util.THIS.isLoggable()) /* then */
1508:                        Util.THIS.debug("startContentModel(" + elementName
1509:                                + ")"); // NOI18N
1510:
1511:                    lastType = null;
1512:                    contentModelMembersStack = new Stack();
1513:
1514:                }
1515:
1516:                public void any(Augmentations a) {
1517:                    contentModel = new ANYType();
1518:                }
1519:
1520:                public void empty(Augmentations a) {
1521:                    contentModel = new EMPTYType();
1522:                }
1523:
1524:                public void pcdata(Augmentations a) {
1525:                    setMembersType(new MixedType());
1526:                }
1527:
1528:                // it is not called for mixed type
1529:                public void startGroup(Augmentations a) {
1530:                    if (Util.THIS.isLoggable()) /* then */
1531:                        Util.THIS.debug("startGroup()"); // NOI18N
1532:
1533:                    startMembers();
1534:                }
1535:
1536:                public void element(String elementName, Augmentations a) {
1537:
1538:                    if (Util.THIS.isLoggable()) /* then */
1539:                        Util.THIS.debug("element(" + elementName + ")"); // NOI18N
1540:
1541:                    lastType = new NameType(elementName);
1542:                    addMember(lastType);
1543:                }
1544:
1545:                // determine type of content model group
1546:                public void separator(short separator, Augmentations a) {
1547:                    if (Util.THIS.isLoggable()) /* then */
1548:                        Util.THIS.debug("childrenSeparator()"); // NOI18N
1549:
1550:                    switch (separator) {
1551:                    case SEPARATOR_SEQUENCE:
1552:                        setMembersType(new SequenceType());
1553:                        break;
1554:                    case SEPARATOR_CHOICE:
1555:                        setMembersType(new ChoiceType());
1556:                        break;
1557:                    default:
1558:                        doAssert(false);
1559:                    }
1560:                }
1561:
1562:                //
1563:                // INPUT lastType field
1564:                //
1565:                public void occurrence(short occurrence, Augmentations a) {
1566:                    if (Util.THIS.isLoggable()) /* then */
1567:                        Util.THIS.debug("childrenOccurrence()"); // NOI18N
1568:
1569:                    switch (occurrence) {
1570:                    case OCCURS_ZERO_OR_ONE:
1571:                        lastType.setMultiplicity('?');
1572:                        break;
1573:                    case OCCURS_ZERO_OR_MORE:
1574:                        lastType.setMultiplicity('*');
1575:                        break;
1576:                    case OCCURS_ONE_OR_MORE:
1577:                        lastType.setMultiplicity('+');
1578:                        break;
1579:                    default:
1580:                        doAssert(false);
1581:                    }
1582:
1583:                }
1584:
1585:                public void endGroup(Augmentations a) {
1586:                    if (Util.THIS.isLoggable()) /* then */
1587:                        Util.THIS.debug("childrenEndGroup()"); // NOI18N
1588:
1589:                    ChildrenType group = getMembersType();
1590:                    group.addTypes(endMembers());
1591:                    lastType = group;
1592:                    addMember(lastType);
1593:                }
1594:
1595:                public void endContentModel(Augmentations a) {
1596:                    if (Util.THIS.isLoggable()) /* then */
1597:                        Util.THIS.debug("endContentModel()"); // NOI18N
1598:
1599:                    if (contentModel == null && lastType == null) { // #PCDATA
1600:                        contentModel = new MixedType();
1601:                    } else if (contentModel == null) { // we are of CHILDREN_TYPE or mixed type
1602:                        contentModel = lastType;
1603:                        if (contentModel instanceof  MixedType) {
1604:                            contentModel.setMultiplicity('*');
1605:                        }
1606:                    }
1607:                }
1608:
1609:                private void startMembers() {
1610:                    contentModelMembersStack.push(new Members(13));
1611:                }
1612:
1613:                private void addMember(TreeElementDecl.ContentType child) {
1614:
1615:                    // we are at top level of content model, lastType becomes it
1616:                    if (contentModelMembersStack.isEmpty())
1617:                        return;
1618:
1619:                    Collection members = (Collection) contentModelMembersStack
1620:                            .peek();
1621:                    members.add(child);
1622:                }
1623:
1624:                private Collection endMembers() {
1625:                    return (Collection) contentModelMembersStack.pop();
1626:                }
1627:
1628:                // we can predict member group now, if know balk it
1629:                private void setMembersType(ChildrenType group) {
1630:
1631:                    // we are at top level of content model, lastType becomes it
1632:                    if (contentModelMembersStack.isEmpty())
1633:                        return;
1634:
1635:                    Members members = (Members) contentModelMembersStack.peek();
1636:                    if (members.group == null)
1637:                        members.group = group;
1638:                }
1639:
1640:                private ChildrenType getMembersType() {
1641:                    Members members = (Members) contentModelMembersStack.peek();
1642:                    if (members.group == null) {
1643:                        return new ChoiceType();
1644:                    } else {
1645:                        return members.group;
1646:                    }
1647:                }
1648:
1649:                //
1650:                // Hold additional information about group that holds these members
1651:                //
1652:                private class Members extends ArrayList {
1653:
1654:                    private ChildrenType group;
1655:
1656:                    private static final long serialVersionUID = 4614355994187952965L;
1657:
1658:                    public Members(int initSize) {
1659:                        super (initSize);
1660:                        group = null;
1661:                    }
1662:                }
1663:
1664:                // ~~~~~~~~~~~~~~~~~ ERROR HANDLER ~~~~~~~~~~~~~~~~~~~~~~~~~~~
1665:
1666:                public void error(org.xml.sax.SAXParseException e) {
1667:                    trace(e.getMessage());
1668:
1669:                    errorHandler.message(
1670:                            TreeStreamBuilderErrorHandler.ERROR_ERROR, e);
1671:                }
1672:
1673:                public void warning(org.xml.sax.SAXParseException e) {
1674:                    trace(e.getMessage());
1675:
1676:                    errorHandler.message(
1677:                            TreeStreamBuilderErrorHandler.ERROR_WARNING, e);
1678:                }
1679:
1680:                public void fatalError(org.xml.sax.SAXParseException e) {
1681:                    trace(e.getMessage());
1682:
1683:                    errors++;
1684:                    errorHandler.message(
1685:                            TreeStreamBuilderErrorHandler.ERROR_FATAL_ERROR, e);
1686:                }
1687:
1688:                // ~~~~~~~~~~~~~~~~~~ UTILITY ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1689:
1690:                /**
1691:                 */
1692:                private void setReadOnly(TreeObject treeObject) {
1693:                    setReadOnly(treeObject, true);
1694:                }
1695:
1696:                private void setReadOnly(TreeObject treeObject, boolean value) {
1697:                    try {
1698:                        Method setReadOnlyMethod = TreeObject.class
1699:                                .getDeclaredMethod("setReadOnly",
1700:                                        new Class[] { Boolean.TYPE }); // NOI18N
1701:                        setReadOnlyMethod.setAccessible(true);
1702:                        setReadOnlyMethod.invoke(treeObject,
1703:                                new Object[] { value == true ? Boolean.TRUE
1704:                                        : Boolean.FALSE });
1705:                    } catch (NoSuchMethodException exc) {
1706:                    } catch (IllegalAccessException exc) {
1707:                    } catch (InvocationTargetException exc) {
1708:                    }
1709:                }
1710:
1711:                /**
1712:                 * As positons will be supported
1713:                 */
1714:                private void setBeginPosition(TreeNode n) {
1715:                    //!!!
1716:                }
1717:
1718:                /**
1719:                 * @return TreeDocument or null if fatal errors occured
1720:                 */
1721:                private TreeDocumentRoot getDocumentRoot() {
1722:                    TreeDocumentRoot doc = (TreeDocumentRoot) (errors > 0 ? null
1723:                            : returnDocument);
1724:
1725:                    if (Util.THIS.isLoggable()) /* then */
1726:                        Util.THIS.debug("TreeStreamBuilderXercesImpl returns: "
1727:                                + doc); // NOI18N
1728:
1729:                    return doc;
1730:                }
1731:
1732:                /**
1733:                 * Shortcut - retrieves child list and pushes it at stack
1734:                 */
1735:                private void pushParentNode(TreeParentNode parent) {
1736:                    parentNodeStack.push(parent);
1737:                    pushParentObjectList(parent.getChildNodes());
1738:                }
1739:
1740:                /**
1741:                 * Set new parent list pushing original one to node stack
1742:                 */
1743:                private void pushParentObjectList(TreeObjectList parentList) {
1744:                    parentObjectListStack.push(parentObjectList);
1745:
1746:                    // inherit null parents (for nested parents)
1747:                    if (parentObjectList != null
1748:                            || parentObjectListStack.size() == 1) {
1749:                        parentObjectList = parentList;
1750:                    } else {
1751:                        parentObjectList = null;
1752:                    }
1753:                }
1754:
1755:                /**
1756:                 * Restore current children list poping it from stack.
1757:                 */
1758:                private void popParentObjectList() {
1759:                    parentObjectList = (TreeObjectList) parentObjectListStack
1760:                            .pop();
1761:                }
1762:
1763:                /**
1764:                 * Resotore parent node and its list from stack
1765:                 */
1766:                private void popParentNode() {
1767:                    popParentObjectList();
1768:                    TreeParentNode parentNode = (TreeParentNode) parentNodeStack
1769:                            .pop();
1770:
1771:                    // referenced things and DTD things are read only
1772:
1773:                    if (parentNode instanceof  TreeGeneralEntityReference) { // entities in XML doc
1774:
1775:                        setReadOnly(parentNode.getChildNodes());
1776:
1777:                    } else if (parentNode instanceof  TreeDTD) { // whole DTD
1778:
1779:                        setReadOnly(parentNode);
1780:
1781:                    } else if (parentNode instanceof  TreeDocumentType) {
1782:
1783:                        setReadOnly(parentNode.getChildNodes());
1784:
1785:                        // there can be pure internal DTD
1786:                        TreeObjectList externalDTD = ((TreeDocumentType) parentNode)
1787:                                .getExternalDTD();
1788:                        if (externalDTD != null) {
1789:                            setReadOnly(externalDTD);
1790:                        }
1791:                    }
1792:                }
1793:
1794:                private TreeParentNode currentParentNode() {
1795:                    return (TreeParentNode) parentNodeStack.peek();
1796:                }
1797:
1798:                /**
1799:                 * Add child to current parent list.
1800:                 */
1801:                private void appendChild(TreeObject child) {
1802:                    if (parentObjectList != null)
1803:                        parentObjectList.add(child);
1804:                }
1805:
1806:                /**
1807:                 * Enter entity, following events origanes from entity resolution
1808:                 */
1809:                private void enterEntity() {
1810:                    entityCounter++;
1811:                }
1812:
1813:                /**
1814:                 * Exit entity.
1815:                 */
1816:                private void exitEntity() {
1817:                    entityCounter--;
1818:                }
1819:
1820:                /**
1821:                 * Test whether we are in entity, i.e. creating readonly nodes.
1822:                 */
1823:                private boolean inEntity() {
1824:                    return entityCounter > 0;
1825:                }
1826:
1827:                private void trace(String msg) {
1828:                    if (Util.THIS.isLoggable()) {
1829:                        String location = "";
1830:                        if (locator != null) {
1831:                            String entity = locator.getExpandedSystemId();
1832:                            int index = entity.lastIndexOf('/');
1833:                            entity = entity.substring(index > 0 ? index : 0);
1834:                            location = entity + "/" + locator.getLineNumber()
1835:                                    + ":" + locator.getColumnNumber();
1836:                        }
1837:                        Util.THIS.debug("X2T " + location + " " + msg); // NOI18N
1838:                    }
1839:                }
1840:
1841:                private void doAssert(boolean asrt) {
1842:                    if (asrt == false) {
1843:                        throw new IllegalStateException("ASSERT"); // NOI18N
1844:                    }
1845:                }
1846:
1847:            }
1848:
1849:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.