Source Code Cross Referenced for XSLGrammarQuery.java in  » IDE-Netbeans » xml » org » netbeans » modules » xsl » grammar » 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.modules.xsl.grammar 
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.modules.xsl.grammar;
0043:
0044:        import java.io.IOException;
0045:        import java.util.*;
0046:        import javax.swing.Icon; //import org.apache.xpath.XPathAPI;
0047:
0048:        import org.netbeans.api.xml.services.UserCatalog;
0049:        import org.netbeans.modules.xml.api.model.*;
0050:        import org.netbeans.modules.xml.spi.dom.*;
0051:        import org.netbeans.modules.xsl.api.XSLCustomizer;
0052:        import org.openide.loaders.DataObject;
0053:        import org.openide.nodes.PropertySupport;
0054:        import org.openide.util.Lookup;
0055:        import org.openide.util.NbBundle;
0056:        import org.openide.util.lookup.Lookups;
0057:
0058:        import org.w3c.dom.*;
0059:        import org.xml.sax.EntityResolver;
0060:        import org.xml.sax.InputSource;
0061:        import org.xml.sax.SAXException;
0062:
0063:        /**
0064:         * This class implements code completion for XSL transformation files.
0065:         * XSL elements in the completion are hardcoded from the XSLT spec, but the
0066:         * result elements are gathered from the "doctype-public" and "doctype-system"
0067:         * attributes of the xsl:output element.
0068:         *
0069:         * @author  asgeir@dimonsoftware.com
0070:         */
0071:        public final class XSLGrammarQuery implements  GrammarQuery {
0072:
0073:            private DataObject dataObject;
0074:
0075:            /** Contains a mapping from XSL namespace element names to set of names of
0076:             * allowed XSL children. Neither the element name keys nor the names in the
0077:             * value set should contain the namespace prefix.
0078:             */
0079:            private static Map elementDecls;
0080:
0081:            /** Contains a mapping from XSL namespace element names to set of names of
0082:             * allowed XSL attributes for that element.  The element name keys should
0083:             * not contain the namespace prefix.
0084:             */
0085:            private static Map attrDecls;
0086:
0087:            /** A Set of XSL attributes which should be allowd for result elements*/
0088:            private static Set resultElementAttr;
0089:
0090:            /** An object which indicates that result element should be allowed in a element Set */
0091:            private static String resultElements = "RESULT_ELEMENTS_DUMMY_STRING"; // NOI18N
0092:
0093:            /** A Set of elements which should be allowed at template level in XSL stylesheet */
0094:            private static Set template;
0095:
0096:            /** Contains a mapping from XSL namespace element names to an attribute name which
0097:             * should contain XPath expression.  The element name keys should
0098:             * not contain the namespace prefix.
0099:             */
0100:            private static Map exprAttributes;
0101:
0102:            /** A set containing all functions allowed in XSLT */
0103:            private static Set xslFunctions;
0104:
0105:            /** A set containing XPath axes */
0106:            private static Set xpathAxes;
0107:
0108:            /** A list of prefixes using the "http://www.w3.org/1999/XSL/Transform" namespace
0109:             * defined in the context XSL document.  The first prefix in the list is the actual XSL
0110:             * transformation prefix, which is normally defined on the xsl:stylesheet element.
0111:             */
0112:            private List prefixList = new LinkedList();
0113:
0114:            /** A GrammarQuery for the result elements created for the doctype-public" and
0115:             * "doctype-system" attributes of the xsl:output element.*/
0116:            private GrammarQuery resultGrammarQuery;
0117:
0118:            /** The value of the system identifier of the DTD which was used when
0119:             * resultGrammarQuery was previously created */
0120:            private String lastDoctypeSystem;
0121:
0122:            /** The value of the public identifier of the DTD which was used when
0123:             * resultGrammarQuery was previously created */
0124:            private String lastDoctypePublic;
0125:
0126:            // we cannot parse SGML DTD for HTML, let emulate it by XHTML DTD
0127:            private final static String XHTML_PUBLIC_ID = System.getProperty(
0128:                    "netbeans.xsl.html.public",
0129:                    "-//W3C//DTD XHTML 1.0 Transitional//EN"); // NOI18N
0130:
0131:            // we cannot parse SGML DTD for HTML, let emulate it by XHTML DTD
0132:            private final static String XHTML_SYSTEM_ID = System.getProperty(
0133:                    "netbeans.xsl.html.system",
0134:                    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"); // NOI18N
0135:
0136:            // namespace that this grammar supports
0137:            public static final String XSLT_NAMESPACE_URI = "http://www.w3.org/1999/XSL/Transform"; // NOI18N
0138:
0139:            /** Folder which stores instances of custom external XSL customizers */
0140:            private static final String CUSTOMIZER_FOLDER = "Plugins/XML/XSLCustomizer"; // NOI18N
0141:
0142:            private XSLCustomizer customizer = null;
0143:
0144:            private ResourceBundle bundle = NbBundle
0145:                    .getBundle(XSLGrammarQuery.class);
0146:
0147:            /** Creates a new instance of XSLGrammarQuery */
0148:            public XSLGrammarQuery(DataObject dataObject) {
0149:                this .dataObject = dataObject;
0150:            }
0151:
0152:            //////////////////////////////////////////7
0153:            // Getters for the static members
0154:
0155:            private static Map getElementDecls() {
0156:                if (elementDecls == null) {
0157:                    elementDecls = new HashMap();
0158:                    attrDecls = new HashMap();
0159:
0160:                    // Commonly used variables
0161:                    Set emptySet = new TreeSet();
0162:                    String spaceAtt = "xml:space"; // NOI18N
0163:                    Set tmpSet;
0164:
0165:                    ////////////////////////////////////////////////
0166:                    // Initialize common sets
0167:
0168:                    Set charInstructions = new TreeSet(Arrays
0169:                            .asList(new String[] {
0170:                                    "apply-templates", // NOI18N
0171:                                    "call-template", "apply-imports",
0172:                                    "for-each",
0173:                                    "value-of", // NOI18N
0174:                                    "copy-of", "number", "choose", "if",
0175:                                    "text", "copy", // NOI18N
0176:                                    "variable", "message", "fallback" })); // NOI18N
0177:
0178:                    Set instructions = new TreeSet(charInstructions);
0179:                    instructions.addAll(Arrays.asList(new String[] {
0180:                            "processing-instruction", // NOI18N
0181:                            "comment", "element", "attribute" })); // NOI18N
0182:
0183:                    Set charTemplate = charInstructions; // We don't care about PCDATA
0184:
0185:                    template = new TreeSet(instructions);
0186:                    template.add(resultElements);
0187:
0188:                    Set topLevel = new TreeSet(Arrays
0189:                            .asList(new String[] {
0190:                                    "import",
0191:                                    "include",
0192:                                    "strip-space", // NOI18N
0193:                                    "preserve-space", "output", "key",
0194:                                    "decimal-format",
0195:                                    "attribute-set", // NOI18N
0196:                                    "variable", "param", "template",
0197:                                    "namespace-alias" })); // NOI18N
0198:
0199:                    Set topLevelAttr = new TreeSet(Arrays.asList(new String[] {
0200:                            "extension-element-prefixes", // NOI18N
0201:                            "exclude-result-prefixes", "id", "version",
0202:                            spaceAtt })); // NOI18N
0203:
0204:                    resultElementAttr = new TreeSet(Arrays.asList(new String[] {
0205:                            "extension-element-prefixes", // NOI18N
0206:                            "exclude-result-prefixes", "use-attribute-sets",
0207:                            "version" })); // NOI18N
0208:
0209:                    ////////////////////////////////////////////////
0210:                    // Add items to elementDecls and attrDecls maps
0211:
0212:                    // xsl:stylesheet
0213:                    elementDecls.put("stylesheet", topLevel); // NOI18N
0214:                    attrDecls.put("stylesheet", topLevelAttr); // NOI18N
0215:
0216:                    // xsl:transform
0217:                    elementDecls.put("transform", topLevel); // NOI18N
0218:                    attrDecls.put("transform", topLevelAttr); // NOI18N
0219:
0220:                    // xsl:import
0221:                    elementDecls.put("import", emptySet); // NOI18N
0222:                    attrDecls.put("import", new TreeSet(Arrays
0223:                            .asList(new String[] { "href" }))); // NOI18N
0224:
0225:                    // xxsl:include
0226:                    elementDecls.put("include", emptySet); // NOI18N
0227:                    attrDecls.put("include", new TreeSet(Arrays
0228:                            .asList(new String[] { "href" }))); // NOI18N
0229:
0230:                    // xsl:strip-space
0231:                    elementDecls.put("strip-space", emptySet); // NOI18N
0232:                    attrDecls.put("strip-space", new TreeSet(Arrays
0233:                            .asList(new String[] { "elements" }))); // NOI18N
0234:
0235:                    // xsl:preserve-space
0236:                    elementDecls.put("preserve-space", emptySet); // NOI18N
0237:                    attrDecls.put("preserve-space", new TreeSet(Arrays
0238:                            .asList(new String[] { "elements" }))); // NOI18N
0239:
0240:                    // xsl:output
0241:                    elementDecls.put("output", emptySet); // NOI18N
0242:                    attrDecls.put("output", new TreeSet(Arrays
0243:                            .asList(new String[] {
0244:                                    "method", // NOI18N
0245:                                    "version", "encoding",
0246:                                    "omit-xml-declaration",
0247:                                    "standalone",
0248:                                    "doctype-public", // NOI18N
0249:                                    "doctype-system", "cdata-section-elements",
0250:                                    "indent", "media-type" }))); // NOI18N
0251:
0252:                    // xsl:key
0253:                    elementDecls.put("key", emptySet); // NOI18N
0254:                    attrDecls.put("key", new TreeSet(Arrays
0255:                            .asList(new String[] { "name", "match", "use" }))); // NOI18N
0256:
0257:                    // xsl:decimal-format
0258:                    elementDecls.put("decimal-format", emptySet); // NOI18N
0259:                    attrDecls.put("decimal-format", new TreeSet(Arrays
0260:                            .asList(new String[] {
0261:                                    "name", // NOI18N
0262:                                    "decimal-separator", "grouping-separator",
0263:                                    "infinity", "minus-sign",
0264:                                    "NaN", // NOI18N
0265:                                    "percent", "per-mille", "zero-digit",
0266:                                    "digit", "pattern-separator" }))); // NOI18N
0267:
0268:                    // xsl:namespace-alias
0269:                    elementDecls.put("namespace-alias", emptySet); // NOI18N
0270:                    attrDecls.put("namespace-alias", new TreeSet(Arrays
0271:                            .asList(new String[] { // NOI18N
0272:                            "stylesheet-prefix", "result-prefix" }))); // NOI18N
0273:
0274:                    // xsl:template
0275:                    tmpSet = new TreeSet(instructions);
0276:                    tmpSet.add(resultElements);
0277:                    tmpSet.add("param"); // NOI18N
0278:                    elementDecls.put("template", tmpSet); // NOI18N
0279:                    attrDecls.put("template", new TreeSet(Arrays
0280:                            .asList(new String[] { // NOI18N
0281:                            "match", "name", "priority", "mode", spaceAtt }))); // NOI18N
0282:
0283:                    // xsl:value-of
0284:                    elementDecls.put("value-of", emptySet); // NOI18N
0285:                    attrDecls.put("value-of", new TreeSet(Arrays
0286:                            .asList(new String[] { // NOI18N
0287:                            "select", "disable-output-escaping" }))); // NOI18N
0288:
0289:                    // xsl:copy-of
0290:                    elementDecls.put("copy-of", emptySet); // NOI18N
0291:                    attrDecls.put("copy-of", new TreeSet(Arrays
0292:                            .asList(new String[] { "select" }))); // NOI18N
0293:
0294:                    // xsl:number
0295:                    elementDecls.put("number", emptySet); // NOI18N
0296:                    attrDecls.put("number", new TreeSet(Arrays
0297:                            .asList(new String[] { // NOI18N
0298:                            "level", "count", "from", "value", "format",
0299:                                    "lang", "letter-value", // NOI18N
0300:                                    "grouping-separator", "grouping-size" }))); // NOI18N
0301:
0302:                    // xsl:apply-templates
0303:                    elementDecls.put("apply-templates", new TreeSet(Arrays
0304:                            .asList(new String[] { // NOI18N
0305:                            "sort", "with-param" }))); // NOI18N
0306:                    attrDecls.put("apply-templates", new TreeSet(Arrays
0307:                            .asList(new String[] { // NOI18N
0308:                            "select", "mode" }))); // NOI18N
0309:
0310:                    // xsl:apply-imports
0311:                    elementDecls.put("apply-imports", emptySet); // NOI18N
0312:                    attrDecls.put("apply-imports", emptySet); // NOI18N
0313:
0314:                    // xsl:for-each
0315:                    tmpSet = new TreeSet(instructions);
0316:                    tmpSet.add(resultElements);
0317:                    tmpSet.add("sort"); // NOI18N
0318:                    elementDecls.put("for-each", tmpSet); // NOI18N
0319:                    attrDecls.put("for-each", new TreeSet(Arrays
0320:                            .asList(new String[] { // NOI18N
0321:                            "select", spaceAtt }))); // NOI18N
0322:
0323:                    // xsl:sort
0324:                    elementDecls.put("sort", emptySet); // NOI18N
0325:                    attrDecls.put("sort", new TreeSet(Arrays
0326:                            .asList(new String[] { // NOI18N
0327:                            "select", "lang", "data-type", "order",
0328:                                    "case-order" }))); // NOI18N
0329:
0330:                    // xsl:if
0331:                    elementDecls.put("if", template); // NOI18N
0332:                    attrDecls.put("if", new TreeSet(Arrays.asList(new String[] {
0333:                            "test", spaceAtt }))); // NOI18N
0334:
0335:                    // xsl:choose
0336:                    elementDecls.put("choose", new TreeSet(Arrays
0337:                            .asList(new String[] { // NOI18N
0338:                            "when", "otherwise" }))); // NOI18N
0339:                    attrDecls.put("choose", new TreeSet(Arrays
0340:                            .asList(new String[] { spaceAtt }))); // NOI18N
0341:
0342:                    // xsl:when
0343:                    elementDecls.put("when", template); // NOI18N
0344:                    attrDecls.put("when", new TreeSet(Arrays
0345:                            .asList(new String[] { // NOI18N
0346:                            "test", spaceAtt }))); // NOI18N
0347:
0348:                    // xsl:otherwise
0349:                    elementDecls.put("otherwise", template); // NOI18N
0350:                    attrDecls.put("otherwise", new TreeSet(Arrays
0351:                            .asList(new String[] { spaceAtt }))); // NOI18N
0352:
0353:                    // xsl:attribute-set
0354:                    elementDecls.put("sort", new TreeSet(Arrays
0355:                            .asList(new String[] { "attribute" }))); // NOI18N
0356:                    attrDecls.put("attribute-set", new TreeSet(Arrays
0357:                            .asList(new String[] { // NOI18N
0358:                            "name", "use-attribute-sets" }))); // NOI18N
0359:
0360:                    // xsl:call-template
0361:                    elementDecls.put("call-template", new TreeSet(Arrays
0362:                            .asList(new String[] { "with-param" }))); // NOI18N
0363:                    attrDecls.put("call-template", new TreeSet(Arrays
0364:                            .asList(new String[] { "name" }))); // NOI18N
0365:
0366:                    // xsl:with-param
0367:                    elementDecls.put("with-param", template); // NOI18N
0368:                    attrDecls.put("with-param", new TreeSet(Arrays
0369:                            .asList(new String[] { // NOI18N
0370:                            "name", "select" }))); // NOI18N
0371:
0372:                    // xsl:variable
0373:                    elementDecls.put("variable", template); // NOI18N
0374:                    attrDecls.put("variable", new TreeSet(Arrays
0375:                            .asList(new String[] { // NOI18N
0376:                            "name", "select" }))); // NOI18N
0377:
0378:                    // xsl:param
0379:                    elementDecls.put("param", template); // NOI18N
0380:                    attrDecls.put("param", new TreeSet(Arrays
0381:                            .asList(new String[] { // NOI18N
0382:                            "name", "select" }))); // NOI18N
0383:
0384:                    // xsl:text
0385:                    elementDecls.put("text", emptySet); // NOI18N
0386:                    attrDecls.put("text", new TreeSet(Arrays
0387:                            .asList(new String[] { // NOI18N
0388:                            "disable-output-escaping" }))); // NOI18N
0389:
0390:                    // xsl:processing-instruction
0391:                    elementDecls.put("processing-instruction", charTemplate); // NOI18N
0392:                    attrDecls.put("processing-instruction", new TreeSet(Arrays
0393:                            .asList(new String[] { // NOI18N
0394:                            "name", spaceAtt }))); // NOI18N
0395:
0396:                    // xsl:element
0397:                    elementDecls.put("element", template); // NOI18N
0398:                    attrDecls.put("element", new TreeSet(
0399:                            Arrays.asList(new String[] { // NOI18N
0400:                                    "name", "namespace", "use-attribute-sets",
0401:                                            spaceAtt }))); // NOI18N
0402:
0403:                    // xsl:attribute
0404:                    elementDecls.put("attribute", charTemplate); // NOI18N
0405:                    attrDecls.put("attribute", new TreeSet(Arrays
0406:                            .asList(new String[] { // NOI18N
0407:                            "name", "namespace", spaceAtt }))); // NOI18N
0408:
0409:                    // xsl:comment
0410:                    elementDecls.put("comment", charTemplate); // NOI18N
0411:                    attrDecls.put("comment", new TreeSet(Arrays
0412:                            .asList(new String[] { spaceAtt }))); // NOI18N
0413:
0414:                    // xsl:copy
0415:                    elementDecls.put("copy", template); // NOI18N
0416:                    attrDecls.put("copy", new TreeSet(Arrays
0417:                            .asList(new String[] { // NOI18N
0418:                            spaceAtt, "use-attribute-sets" }))); // NOI18N
0419:
0420:                    // xsl:message
0421:                    elementDecls.put("message", template); // NOI18N
0422:                    attrDecls.put("message", new TreeSet(Arrays
0423:                            .asList(new String[] { // NOI18N
0424:                            spaceAtt, "terminate" }))); // NOI18N
0425:
0426:                    // xsl:fallback
0427:                    elementDecls.put("fallback", template); // NOI18N
0428:                    attrDecls.put("fallback", new TreeSet(Arrays
0429:                            .asList(new String[] { spaceAtt }))); // NOI18N
0430:                }
0431:                return elementDecls;
0432:            }
0433:
0434:            private static Map getAttrDecls() {
0435:                if (attrDecls == null) {
0436:                    getElementDecls();
0437:                }
0438:                return attrDecls;
0439:            }
0440:
0441:            private static Set getResultElementAttr() {
0442:                if (resultElementAttr == null) {
0443:                    getElementDecls();
0444:                }
0445:                return resultElementAttr;
0446:            }
0447:
0448:            private static Set getTemplate() {
0449:                if (template == null) {
0450:                    getElementDecls();
0451:                }
0452:                return template;
0453:            }
0454:
0455:            private static Set getXslFunctions() {
0456:                if (xslFunctions == null) {
0457:                    xslFunctions = new TreeSet(Arrays.asList(new String[] {
0458:                            "boolean(",
0459:                            "ceiling(",
0460:                            "concat(",
0461:                            "contains(",
0462:                            "count(",
0463:                            "current()",
0464:                            "document(", // NOI18N
0465:                            "false()",
0466:                            "floor(",
0467:                            "format-number(",
0468:                            "generate-id(", // NOI18N
0469:                            "id(", "local-name(", "key(", "lang(",
0470:                            "last()",
0471:                            "name(",
0472:                            "namespace-uri(",
0473:                            "normalize-space(", // NOI18N
0474:                            "not(", "number(", "position()",
0475:                            "round(",
0476:                            "starts-with(",
0477:                            "string(", // NOI18N
0478:                            "string-length(", "substring(", "substring-after(",
0479:                            "substring-before(",
0480:                            "sum(", // NOI18N
0481:                            "system-property(", "translate(", "true()",
0482:                            "unparsed-entity-uri(" })); // NOI18N
0483:                }
0484:                return xslFunctions;
0485:            }
0486:
0487:            private static Set getXPathAxes() {
0488:                if (xpathAxes == null) {
0489:                    xpathAxes = new TreeSet(Arrays.asList(new String[] {
0490:                            "ancestor::",
0491:                            "ancestor-or-self::", // NOI18N
0492:                            "attribute::", "child::", "descendant::",
0493:                            "descendant-or-self::",
0494:                            "following::", // NOI18N
0495:                            "following-sibling::", "namespace::", "parent::",
0496:                            "preceding::", // NOI18N
0497:                            "preceding-sibling::", "self::" })); // NOI18N
0498:                }
0499:                return xpathAxes;
0500:            }
0501:
0502:            private static Map getExprAttributes() {
0503:                if (exprAttributes == null) {
0504:                    exprAttributes = new HashMap();
0505:                    exprAttributes.put("key", "use"); // NOI18N
0506:                    exprAttributes.put("value-of", "select"); // NOI18N
0507:                    exprAttributes.put("copy-of", "select"); // NOI18N
0508:                    exprAttributes.put("number", "value"); // NOI18N
0509:                    //??? what about match one
0510:                    exprAttributes.put("apply-templates", "select"); // NOI18N
0511:                    exprAttributes.put("for-each", "select"); // NOI18N
0512:                    exprAttributes.put("sort", "select"); // NOI18N
0513:                    exprAttributes.put("if", "test"); // NOI18N
0514:                    exprAttributes.put("when", "test"); // NOI18N
0515:                    exprAttributes.put("with-param", "select"); // NOI18N
0516:                    exprAttributes.put("variable", "select"); // NOI18N
0517:                    exprAttributes.put("param", "select"); // NOI18N
0518:                }
0519:                return exprAttributes;
0520:            }
0521:
0522:            ////////////////////////////////////////////////////////////////////////////////
0523:            // GrammarQuery interface fulfillment
0524:
0525:            /**
0526:             * Support completions of elements defined by XSLT spec and by the <output>
0527:             * doctype attribute (in result space).
0528:             */
0529:            public Enumeration queryElements(HintContext ctx) {
0530:                Node node = ((Node) ctx).getParentNode();
0531:
0532:                String prefix = ctx.getCurrentPrefix();
0533:                QueueEnumeration list = new QueueEnumeration();
0534:
0535:                if (node instanceof  Element) {
0536:                    Element el = (Element) node;
0537:                    updateProperties(el);
0538:                    if (prefixList.size() == 0)
0539:                        return org.openide.util.Enumerations.empty();
0540:
0541:                    String firstXslPrefixWithColon = prefixList.get(0) + ":"; // NOI18N
0542:                    Set elements;
0543:                    if (el.getTagName().startsWith(firstXslPrefixWithColon)) {
0544:                        String parentNCName = el.getTagName().substring(
0545:                                firstXslPrefixWithColon.length());
0546:                        elements = (Set) getElementDecls().get(parentNCName);
0547:                    } else {
0548:                        // Children of result elements should always be the template set
0549:                        elements = getTemplate();
0550:                    }
0551:
0552:                    // First we add the Result elements
0553:                    if (elements != null && resultGrammarQuery != null
0554:                            && elements.contains(resultElements)) {
0555:                        ResultHintContext resultHintContext = new ResultHintContext(
0556:                                ctx, firstXslPrefixWithColon, null);
0557:                        Enumeration resultEnum = resultGrammarQuery
0558:                                .queryElements(resultHintContext);
0559:                        while (resultEnum.hasMoreElements()) {
0560:                            list.put(resultEnum.nextElement());
0561:                        }
0562:                    }
0563:
0564:                    // Then we add the XSLT elements of the first prefix (normally of the stylesheet node).
0565:                    addXslElementsToEnum(list, elements, prefixList.get(0)
0566:                            + ":", prefix); // NOI18N
0567:
0568:                    // Finally we add xsl namespace elements with other prefixes than the first one
0569:                    for (int prefixInd = 1; prefixInd < prefixList.size(); prefixInd++) {
0570:                        String curPrefix = (String) prefixList.get(prefixInd)
0571:                                + ":"; // NOI18N
0572:                        Node curNode = el;
0573:                        String curName = null;
0574:                        while (curNode != null
0575:                                && null != (curName = curNode.getNodeName())
0576:                                && !curName.startsWith(curPrefix)) {
0577:                            curNode = curNode.getParentNode();
0578:                        }
0579:
0580:                        if (curName == null) {
0581:                            // This must be the document node
0582:                            addXslElementsToEnum(list, getElementDecls()
0583:                                    .keySet(), curPrefix, prefix);
0584:                        } else {
0585:                            String parentName = curName.substring(curPrefix
0586:                                    .length());
0587:                            elements = (Set) getElementDecls().get(parentName);
0588:                            addXslElementsToEnum(list, elements, curPrefix,
0589:                                    prefix);
0590:                        }
0591:                    }
0592:
0593:                } else if (node instanceof  Document) {
0594:                    //??? it should be probably only root element name
0595:                    if (prefixList.size() == 0)
0596:                        return org.openide.util.Enumerations.empty();
0597:                    addXslElementsToEnum(list, getElementDecls().keySet(),
0598:                            prefixList.get(0) + ":", prefix); // NOI18N
0599:                } else {
0600:                    return org.openide.util.Enumerations.empty();
0601:                }
0602:
0603:                return list;
0604:            }
0605:
0606:            public Enumeration queryAttributes(HintContext ctx) {
0607:                Element el = null;
0608:                // Support two versions of GrammarQuery contract
0609:                if (ctx.getNodeType() == Node.ATTRIBUTE_NODE) {
0610:                    el = ((Attr) ctx).getOwnerElement();
0611:                } else if (ctx.getNodeType() == Node.ELEMENT_NODE) {
0612:                    el = (Element) ctx;
0613:                }
0614:                if (el == null)
0615:                    return org.openide.util.Enumerations.empty();
0616:
0617:                String elTagName = el.getTagName();
0618:                NamedNodeMap existingAttributes = el.getAttributes();
0619:
0620:                updateProperties(el);
0621:
0622:                String curXslPrefix = null;
0623:                for (int ind = 0; ind < prefixList.size(); ind++) {
0624:                    if (elTagName
0625:                            .startsWith((String) prefixList.get(ind) + ":")) { // NOI18N
0626:                        curXslPrefix = (String) prefixList.get(ind) + ":"; // NOI18N
0627:                        break;
0628:                    }
0629:                }
0630:
0631:                Set possibleAttributes;
0632:                if (curXslPrefix != null) {
0633:                    // Attributes of XSL element
0634:                    possibleAttributes = (Set) getAttrDecls().get(
0635:                            el.getTagName().substring(curXslPrefix.length()));
0636:                } else {
0637:                    // XSL Attributes of Result element
0638:                    possibleAttributes = new TreeSet();
0639:                    if (prefixList.size() > 0) {
0640:                        Iterator it = getResultElementAttr().iterator();
0641:                        while (it.hasNext()) {
0642:                            possibleAttributes.add((String) prefixList.get(0)
0643:                                    + ":" + (String) it.next()); // NOI18N
0644:                        }
0645:                    }
0646:                }
0647:                if (possibleAttributes == null)
0648:                    return org.openide.util.Enumerations.empty();
0649:
0650:                String prefix = ctx.getCurrentPrefix();
0651:
0652:                QueueEnumeration list = new QueueEnumeration();
0653:
0654:                if (resultGrammarQuery != null) {
0655:                    Enumeration enum2 = resultGrammarQuery.queryAttributes(ctx);
0656:                    while (enum2.hasMoreElements()) {
0657:                        GrammarResult resNode = (GrammarResult) enum2
0658:                                .nextElement();
0659:                        if (!possibleAttributes.contains(resNode.getNodeName())) {
0660:                            list.put(resNode);
0661:                        }
0662:                    }
0663:                }
0664:
0665:                Iterator it = possibleAttributes.iterator();
0666:                while (it.hasNext()) {
0667:                    String next = (String) it.next();
0668:                    if (next.startsWith(prefix)) {
0669:                        if (existingAttributes.getNamedItem(next) == null) {
0670:                            list.put(new MyAttr(next));
0671:                        }
0672:                    }
0673:                }
0674:
0675:                return list;
0676:            }
0677:
0678:            public Enumeration queryValues(HintContext ctx) {
0679:                if (ctx.getNodeType() == Node.ATTRIBUTE_NODE) {
0680:                    updateProperties(((Attr) ctx).getOwnerElement());
0681:                    if (prefixList.size() == 0)
0682:                        return org.openide.util.Enumerations.empty();
0683:                    String xslNamespacePrefix = prefixList.get(0) + ":"; // NOI18N
0684:
0685:                    String prefix = ctx.getCurrentPrefix();
0686:
0687:                    Attr attr = (Attr) ctx;
0688:
0689:                    boolean isXPath = false;
0690:                    String elName = attr.getOwnerElement().getNodeName();
0691:                    if (elName.startsWith(xslNamespacePrefix)) {
0692:                        String key = elName.substring(xslNamespacePrefix
0693:                                .length());
0694:                        String xpathAttrName = (String) getExprAttributes()
0695:                                .get(key);
0696:                        if (xpathAttrName != null
0697:                                && xpathAttrName.equals(attr.getNodeName())) {
0698:                            // This is an XSLT element which should contain XPathExpression
0699:                            isXPath = true;
0700:                        }
0701:
0702:                        // consult awailable public IDs with users catalog
0703:                        if ("output".equals(key)) { // NOI18N
0704:                            if ("doctype-public".equals(attr.getName())) { // NOI18N
0705:                                UserCatalog catalog = UserCatalog.getDefault();
0706:                                if (catalog == null)
0707:                                    return org.openide.util.Enumerations
0708:                                            .empty();
0709:                                QueueEnumeration en = new QueueEnumeration();
0710:                                Iterator it = catalog.getPublicIDs();
0711:                                while (it.hasNext()) {
0712:                                    String next = (String) it.next();
0713:                                    if (next != null && next.startsWith(prefix)) {
0714:                                        en.put(new MyText(next));
0715:                                    }
0716:                                }
0717:                                return en;
0718:                            }
0719:                        }
0720:                    }
0721:
0722:                    String preExpression = ""; // NOI18N
0723:
0724:                    if (!isXPath) {
0725:                        // Check if we are inside { } for attribute value
0726:                        String nodeValue = attr.getNodeValue();
0727:                        int exprStart = nodeValue.lastIndexOf('{', prefix
0728:                                .length() - 1); // NOI18N
0729:                        int exprEnd = nodeValue.indexOf('}', prefix.length()); // NOI18N
0730:                        //Util.THIS.debug("exprStart: " + exprStart); // NOI18N
0731:                        //Util.THIS.debug("exprEnd: " + exprEnd); // NOI18N
0732:                        if (exprStart != -1 && exprEnd != -1) {
0733:                            isXPath = true;
0734:                            preExpression = prefix.substring(0, exprStart + 1);
0735:                            prefix = prefix.substring(exprStart + 1);
0736:                        }
0737:
0738:                    }
0739:
0740:                    if (isXPath) {
0741:                        // This is an XPath expression
0742:                        QueueEnumeration list = new QueueEnumeration();
0743:
0744:                        int curIndex = prefix.length();
0745:                        while (curIndex > 0) {
0746:                            curIndex--;
0747:                            char curChar = prefix.charAt(curIndex);
0748:                            if (curChar == '(' || curChar == ','
0749:                                    || curChar == ' ') { // NOI18N
0750:                                curIndex++;
0751:                                break;
0752:                            }
0753:                        }
0754:
0755:                        preExpression += prefix.substring(0, curIndex);
0756:                        String subExpression = prefix.substring(curIndex);
0757:
0758:                        int lastDiv = subExpression.lastIndexOf('/'); // NOI18N
0759:                        String subPre = ""; // NOI18N
0760:                        String subRest = ""; // NOI18N
0761:                        if (lastDiv != -1) {
0762:                            subPre = subExpression.substring(0, lastDiv + 1);
0763:                            subRest = subExpression.substring(lastDiv + 1);
0764:                        } else {
0765:                            subRest = subExpression;
0766:                        }
0767:
0768:                        // At this point we need to consult transformed document or
0769:                        // its grammar.
0770:                        // [93792] +
0771:                        //              Object selScenarioObj = scenarioCookie.getModel().getSelectedItem();
0772:                        // [93792] -
0773:                        /*
0774:                        if (selScenarioObj instanceof XSLScenario) {
0775:                            XSLScenario scenario = (XSLScenario)selScenarioObj;
0776:                            Document doc = null;
0777:                            try {
0778:                                doc = scenario.getSourceDocument(dataObject, false);
0779:                            } catch(Exception e) {
0780:                                // We don't care, ignore
0781:                            }
0782:
0783:                            if (doc != null) {
0784:                                Element docElement = doc.getDocumentElement();
0785:
0786:                                Set childNodeNames = new TreeSet();
0787:
0788:                                String combinedXPath;
0789:                                if (subPre.startsWith("/")) { // NOI18N
0790:                                    // This is an absolute XPath
0791:                                    combinedXPath = subPre;
0792:                                } else {
0793:                                    // This is a relative XPath
0794:
0795:                                    // Traverse up the documents tree looking for xsl:for-each
0796:                                    String xslForEachName = xslNamespacePrefix + "for-each"; // NOI18N
0797:                                    List selectAttrs = new LinkedList();
0798:                                    Node curNode = attr.getOwnerElement();
0799:                                    if (curNode != null) {
0800:                                        // We don't want to add select of our selfs
0801:                                        curNode = curNode.getParentNode();
0802:                                    }
0803:
0804:                                    while (curNode != null && !(curNode instanceof Document)) {
0805:                                        if (curNode.getNodeName().equals(xslForEachName)) {
0806:                                            selectAttrs.add(0, ((Element)curNode).getAttribute("select")); // NOI18N
0807:                                        }
0808:
0809:                                        curNode = curNode.getParentNode();
0810:                                    }
0811:
0812:                                    combinedXPath = ""; // NOI18N
0813:                                    for (int ind = 0; ind < selectAttrs.size(); ind++) {
0814:                                        combinedXPath += selectAttrs.get(ind) + "/"; // NOI18N
0815:                                    }
0816:                                    combinedXPath += subPre;
0817:                                }
0818:
0819:                                try {
0820:                                    NodeList nodeList = XPathAPI.selectNodeList(doc, combinedXPath + "child::*"); // NOI18N
0821:                                    for (int ind = 0; ind < nodeList.getLength(); ind++) {
0822:                                        Node curResNode = nodeList.item(ind);
0823:                                        childNodeNames.add(curResNode.getNodeName());
0824:                                    }
0825:
0826:                                    nodeList = XPathAPI.selectNodeList(doc, combinedXPath + "@*"); // NOI18N
0827:                                    for (int ind = 0; ind < nodeList.getLength(); ind++) {
0828:                                        Node curResNode = nodeList.item(ind);
0829:                                        childNodeNames.add("@" + curResNode.getNodeName()); // NOI18N
0830:                                    }
0831:                                } catch (Exception e) {
0832:                                    Util.THIS.debug("Ignored during XPathAPI operations", e); // NOI18N
0833:                                    // We don't care, ignore
0834:                                }
0835:
0836:                                addItemsToEnum(list, childNodeNames, subRest, preExpression + subPre);
0837:                            }
0838:                        }*/
0839:
0840:                        addItemsToEnum(list, getXPathAxes(), subRest,
0841:                                preExpression + subPre);
0842:                        addItemsToEnum(list, getXslFunctions(), subExpression,
0843:                                preExpression);
0844:
0845:                        return list;
0846:                    }
0847:                }
0848:
0849:                return org.openide.util.Enumerations.empty();
0850:            }
0851:
0852:            public GrammarResult queryDefault(HintContext ctx) {
0853:                //??? XSLT defaults are missing
0854:                if (resultGrammarQuery == null)
0855:                    return null;
0856:                return resultGrammarQuery.queryDefault(ctx);
0857:            }
0858:
0859:            public boolean isAllowed(Enumeration en) {
0860:                return true; //!!! not implemented
0861:            }
0862:
0863:            public Enumeration queryEntities(String prefix) {
0864:                QueueEnumeration list = new QueueEnumeration();
0865:
0866:                // add well-know build-in entity names
0867:
0868:                if ("lt".startsWith(prefix))
0869:                    list.put(new MyEntityReference("lt")); // NOI18N
0870:                if ("gt".startsWith(prefix))
0871:                    list.put(new MyEntityReference("gt")); // NOI18N
0872:                if ("apos".startsWith(prefix))
0873:                    list.put(new MyEntityReference("apos")); // NOI18N
0874:                if ("quot".startsWith(prefix))
0875:                    list.put(new MyEntityReference("quot")); // NOI18N
0876:                if ("amp".startsWith(prefix))
0877:                    list.put(new MyEntityReference("amp")); // NOI18N
0878:
0879:                return list;
0880:            }
0881:
0882:            public Enumeration queryNotations(String prefix) {
0883:                return org.openide.util.Enumerations.empty();
0884:            }
0885:
0886:            public java.awt.Component getCustomizer(HintContext ctx) {
0887:                if (customizer == null) {
0888:                    customizer = lookupCustomizerInstance();
0889:                    if (customizer == null) {
0890:                        return null;
0891:                    }
0892:                }
0893:
0894:                return customizer.getCustomizer(ctx, dataObject);
0895:            }
0896:
0897:            public boolean hasCustomizer(HintContext ctx) {
0898:                if (customizer == null) {
0899:                    customizer = lookupCustomizerInstance();
0900:                    if (customizer == null) {
0901:                        return false;
0902:                    }
0903:                }
0904:
0905:                return customizer.hasCustomizer(ctx);
0906:            }
0907:
0908:            public org.openide.nodes.Node.Property[] getProperties(
0909:                    final HintContext ctx) {
0910:
0911:                if (ctx.getNodeType() != Node.ATTRIBUTE_NODE
0912:                        || ctx.getNodeValue() == null) {
0913:                    return null;
0914:                }
0915:
0916:                PropertySupport attrNameProp = new PropertySupport(
0917:                        "Attribute name",
0918:                        String.class, // NOI18N
0919:                        bundle.getString("BK0001"), bundle.getString("BK0002"),
0920:                        true, false) {
0921:                    public void setValue(Object value) {
0922:                        // Dummy
0923:                    }
0924:
0925:                    public Object getValue() {
0926:                        return ctx.getNodeName();
0927:                    }
0928:
0929:                };
0930:
0931:                PropertySupport attrValueProp = new PropertySupport(
0932:                        "Attribute value",
0933:                        String.class, // NOI18N
0934:                        bundle.getString("BK0003"), bundle.getString("BK0004"),
0935:                        true, true) {
0936:                    public void setValue(Object value) {
0937:                        ctx.setNodeValue((String) value);
0938:                    }
0939:
0940:                    public Object getValue() {
0941:                        return ctx.getNodeValue();
0942:                    }
0943:
0944:                };
0945:
0946:                return new org.openide.nodes.Node.Property[] { attrNameProp,
0947:                        attrValueProp };
0948:            }
0949:
0950:            ////////////////////////////////////////////////////////////////////////////////
0951:            // Private helper methods
0952:
0953:            /**
0954:             * Looks up registered XSLCustomizer objects which will be used by this object
0955:             */
0956:            private static XSLCustomizer lookupCustomizerInstance() {
0957:                Lookup.Template template = new Lookup.Template(
0958:                        XSLCustomizer.class);
0959:
0960:                Lookup.Item lookupItem = Lookups.forPath(CUSTOMIZER_FOLDER)
0961:                        .lookupItem(template);
0962:                if (lookupItem == null) {
0963:                    return null;
0964:                }
0965:
0966:                return (XSLCustomizer) lookupItem.getInstance();
0967:            }
0968:
0969:            /**
0970:             * @param enumX the Enumeration which the element should be added to
0971:             * @param elements a set containing strings which should be added (with prefix) to the enum or <code>null</null>
0972:             * @param namespacePrefix a prefix at the form "xsl:" which should be added in front
0973:             *          of the names in the elements.
0974:             * @param startWith Elements should only be added to enum if they start with this string
0975:             */
0976:            private static void addXslElementsToEnum(QueueEnumeration enumX,
0977:                    Set elements, String namespacePrefix, String startWith) {
0978:                if (elements == null)
0979:                    return;
0980:                if (startWith.startsWith(namespacePrefix)
0981:                        || namespacePrefix.startsWith(startWith)) {
0982:                    Iterator it = elements.iterator();
0983:                    while (it.hasNext()) {
0984:                        Object next = it.next();
0985:                        if (next != resultElements) {
0986:                            String nextText = namespacePrefix + (String) next;
0987:                            if (nextText.startsWith(startWith)) {
0988:                                // TODO pass true for empty elements
0989:                                enumX.put(new MyElement(nextText, false));
0990:                            }
0991:                        }
0992:                    }
0993:                }
0994:            }
0995:
0996:            private static void addItemsToEnum(QueueEnumeration enumX, Set set,
0997:                    String startWith, String prefix) {
0998:                Iterator it = set.iterator();
0999:                while (it.hasNext()) {
1000:                    String nextText = (String) it.next();
1001:                    if (nextText.startsWith(startWith)) {
1002:                        enumX.put(new MyText(prefix + nextText));
1003:                    }
1004:                }
1005:            }
1006:
1007:            /**
1008:             * This method traverses up the document tree, investigates it and updates
1009:             * prefixList, resultGrammarQuery, lastDoctypeSystem or lastDoctypePublic
1010:             * members if necessery.
1011:             * @param curNode the node which from wich the traversing should start.
1012:             */
1013:            private void updateProperties(Node curNode) {
1014:                prefixList.clear();
1015:
1016:                // Traverse up the documents tree
1017:                Node rootNode = curNode;
1018:                while (curNode != null && !(curNode instanceof  Document)) {
1019:
1020:                    // Update the xsl namespace prefix list
1021:                    NamedNodeMap attributes = curNode.getAttributes();
1022:                    for (int ind = 0; ind < attributes.getLength(); ind++) {
1023:                        Attr attr = (Attr) attributes.item(ind);
1024:                        String attrName = attr.getName();
1025:                        if (attrName != null && attrName.startsWith("xmlns:")) { // NOI18N
1026:                            if (attr.getValue().equals(XSLT_NAMESPACE_URI)) {
1027:                                prefixList.add(0, attrName.substring(6));
1028:                            }
1029:                        }
1030:                    }
1031:
1032:                    rootNode = curNode;
1033:                    curNode = rootNode.getParentNode();
1034:                }
1035:
1036:                boolean outputFound = false;
1037:                if (prefixList.size() > 0) {
1038:                    String outputElName = (String) prefixList.get(0)
1039:                            + ":output"; // NOI18N
1040:                    Node childOfRoot = rootNode.getFirstChild();
1041:                    while (childOfRoot != null) {
1042:                        String childNodeName = childOfRoot.getNodeName();
1043:                        if (childNodeName != null
1044:                                && childNodeName.equals(outputElName)) {
1045:                            Element outputEl = (Element) childOfRoot;
1046:                            String outputMethod = outputEl
1047:                                    .getAttribute("method"); // NOI18N
1048:
1049:                            String curDoctypePublic = outputEl
1050:                                    .getAttribute("doctype-public"); // NOI18N
1051:                            String curDoctypeSystem = outputEl
1052:                                    .getAttribute("doctype-system"); // NOI18N
1053:
1054:                            if ("html".equals(outputMethod) // NOI18N
1055:                                    && (curDoctypePublic == null || curDoctypePublic
1056:                                            .length() == 0)
1057:                                    && (curDoctypeSystem == null || curDoctypeSystem
1058:                                            .length() == 0)) { // NOI18N
1059:                                // html is special case that can be emulated using XHTML
1060:                                curDoctypePublic = XHTML_PUBLIC_ID;
1061:                                curDoctypeSystem = XHTML_SYSTEM_ID;
1062:                            } else if ("text".equals(outputMethod)) { // NOI18N
1063:                                // user error, ignore
1064:                                break;
1065:                            }
1066:
1067:                            if (curDoctypePublic != null
1068:                                    && !curDoctypePublic
1069:                                            .equals(lastDoctypePublic)
1070:                                    || curDoctypePublic == null
1071:                                    && lastDoctypePublic != null
1072:                                    || curDoctypeSystem != null
1073:                                    && !curDoctypeSystem
1074:                                            .equals(lastDoctypeSystem)
1075:                                    || curDoctypeSystem == null
1076:                                    && lastDoctypeSystem != null) {
1077:                                setOutputDoctype(curDoctypePublic,
1078:                                        curDoctypeSystem);
1079:                            }
1080:
1081:                            outputFound = true;
1082:                            break;
1083:                        }
1084:                        childOfRoot = childOfRoot.getNextSibling();
1085:                    }
1086:                }
1087:
1088:                if (!outputFound) {
1089:                    setOutputDoctype(null, null);
1090:                }
1091:            }
1092:
1093:            /**
1094:             * Updates resultGrammarQuery by parsing the DTD specified by publicId and
1095:             * systemId. lastDoctypeSystem and lastDoctypePublic are assigned to the new values.
1096:             * @param publicId the public identifier of the DTD
1097:             * @param publicId the system identifier of the DTD
1098:             */
1099:            private void setOutputDoctype(String publicId, String systemId) {
1100:                lastDoctypePublic = publicId;
1101:                lastDoctypeSystem = systemId;
1102:
1103:                if (publicId == null && systemId == null) {
1104:                    resultGrammarQuery = null;
1105:                    return;
1106:                }
1107:
1108:                InputSource inputSource = null;
1109:                UserCatalog catalog = UserCatalog.getDefault();
1110:                if (catalog != null) {
1111:                    EntityResolver resolver = catalog.getEntityResolver();
1112:                    if (resolver != null) {
1113:                        try {
1114:                            inputSource = resolver.resolveEntity(publicId,
1115:                                    systemId);
1116:                        } catch (SAXException e) {
1117:                        } catch (IOException e) {
1118:                        } // Will be handled below
1119:                    }
1120:                }
1121:
1122:                if (inputSource == null) {
1123:                    try {
1124:                        java.net.URL url = new java.net.URL(systemId);
1125:                        inputSource = new InputSource(url.openStream());
1126:                        inputSource.setPublicId(publicId);
1127:                        inputSource.setSystemId(systemId);
1128:                    } catch (IOException e) {
1129:                        resultGrammarQuery = null;
1130:                        return;
1131:                    }
1132:                }
1133:
1134:                resultGrammarQuery = DTDUtil.parseDTD(true, inputSource);
1135:
1136:            }
1137:
1138:            ////////////////////////////////////////////////////////////////////////////////
1139:            // Private helper classes
1140:
1141:            private class ResultHintContext extends ResultNode implements 
1142:                    HintContext {
1143:                private String currentPrefix;
1144:
1145:                public ResultHintContext(HintContext peer, String ignorePrefix,
1146:                        String onlyUsePrefix) {
1147:                    super (peer, ignorePrefix, onlyUsePrefix);
1148:                    currentPrefix = peer.getCurrentPrefix();
1149:                }
1150:
1151:                public String getCurrentPrefix() {
1152:                    return currentPrefix;
1153:                }
1154:            }
1155:
1156:            // Result classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1157:
1158:            private static abstract class AbstractResultNode extends
1159:                    AbstractNode implements  GrammarResult {
1160:
1161:                public Icon getIcon(int kind) {
1162:                    return null;
1163:                }
1164:
1165:                /**
1166:                 * @return provide additional information simplifiing decision
1167:                 */
1168:                public String getDescription() {
1169:                    return NbBundle.getMessage(XSLGrammarQuery.class, "BK0005");
1170:                }
1171:
1172:                /**
1173:                 * @return text representing name of suitable entity
1174:                 * //??? is it really needed
1175:                 */
1176:                public String getText() {
1177:                    return getNodeName();
1178:                }
1179:
1180:                /**
1181:                 * @return name that is presented to user
1182:                 */
1183:                public String getDisplayName() {
1184:                    return null;
1185:                }
1186:
1187:                public boolean isEmptyElement() {
1188:                    return false;
1189:                }
1190:
1191:            }
1192:
1193:            private static class MyEntityReference extends AbstractResultNode
1194:                    implements  EntityReference {
1195:
1196:                private String name;
1197:
1198:                MyEntityReference(String name) {
1199:                    this .name = name;
1200:                }
1201:
1202:                public short getNodeType() {
1203:                    return Node.ENTITY_REFERENCE_NODE;
1204:                }
1205:
1206:                public String getNodeName() {
1207:                    return name;
1208:                }
1209:
1210:            }
1211:
1212:            private static class MyElement extends AbstractResultNode implements 
1213:                    Element {
1214:
1215:                private String name;
1216:                private boolean empty;
1217:
1218:                MyElement(String name, boolean empty) {
1219:                    this .name = name;
1220:                    this .empty = empty;
1221:                }
1222:
1223:                public short getNodeType() {
1224:                    return Node.ELEMENT_NODE;
1225:                }
1226:
1227:                public String getNodeName() {
1228:                    return name;
1229:                }
1230:
1231:                public String getTagName() {
1232:                    return name;
1233:                }
1234:
1235:                public boolean isEmptyElement() {
1236:                    return empty;
1237:                }
1238:
1239:            }
1240:
1241:            private static class MyAttr extends AbstractResultNode implements 
1242:                    Attr {
1243:
1244:                private String name;
1245:
1246:                MyAttr(String name) {
1247:                    this .name = name;
1248:                }
1249:
1250:                public short getNodeType() {
1251:                    return Node.ATTRIBUTE_NODE;
1252:                }
1253:
1254:                public String getNodeName() {
1255:                    return name;
1256:                }
1257:
1258:                public String getName() {
1259:                    return name;
1260:                }
1261:
1262:                public String getValue() {
1263:                    return null; //??? what spec says
1264:                }
1265:
1266:            }
1267:
1268:            private static class MyText extends AbstractResultNode implements 
1269:                    Text {
1270:
1271:                private String data;
1272:
1273:                MyText(String data) {
1274:                    this .data = data;
1275:                }
1276:
1277:                public short getNodeType() {
1278:                    return Node.TEXT_NODE;
1279:                }
1280:
1281:                public String getNodeValue() {
1282:                    return getData();
1283:                }
1284:
1285:                public String getData() throws DOMException {
1286:                    return data;
1287:                }
1288:
1289:                public int getLength() {
1290:                    return data == null ? -1 : data.length();
1291:                }
1292:            }
1293:
1294:            private static class QueueEnumeration implements  Enumeration {
1295:                private java.util.LinkedList list = new LinkedList();
1296:
1297:                public boolean hasMoreElements() {
1298:                    return !list.isEmpty();
1299:                }
1300:
1301:                public Object nextElement() {
1302:                    return list.removeFirst();
1303:                }
1304:
1305:                public void put(Object[] arr) {
1306:                    list.addAll(Arrays.asList(arr));
1307:                }
1308:
1309:                public void put(Object o) {
1310:                    list.add(o);
1311:                }
1312:
1313:            } // end of QueueEnumeration
1314:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.