1 19 20 package org.netbeans.modules.xsl.grammar; 21 22 import java.io.IOException ; 23 import java.util.*; 24 import javax.swing.Icon ; 25 27 import org.netbeans.api.xml.services.UserCatalog; 28 import org.netbeans.modules.xml.api.model.*; 29 import org.netbeans.modules.xml.spi.dom.*; 30 import org.netbeans.modules.xml.api.cookies.ScenarioCookie; 31 import org.netbeans.modules.xsl.api.XSLCustomizer; 32 import org.netbeans.modules.xsl.api.XSLScenario; 33 import org.openide.filesystems.Repository; 34 import org.openide.filesystems.FileObject; 35 import org.openide.filesystems.FileSystem; 36 import org.openide.loaders.FolderLookup; 37 import org.openide.loaders.DataFolder; 38 import org.openide.loaders.DataObject; 39 import org.openide.loaders.DataObjectNotFoundException; 40 import org.openide.loaders.InstanceDataObject; 41 import org.openide.nodes.PropertySupport; 42 import org.openide.util.Lookup; 43 import org.openide.util.NbBundle; 44 45 import org.w3c.dom.*; 46 import org.w3c.dom.NodeList ; 47 import org.xml.sax.EntityResolver ; 48 import org.xml.sax.InputSource ; 49 import org.xml.sax.SAXException ; 50 51 59 public final class XSLGrammarQuery implements GrammarQuery{ 60 61 private DataObject dataObject; 62 63 private ScenarioCookie scenarioCookie; 64 65 69 private static Map elementDecls; 70 71 75 private static Map attrDecls; 76 77 78 private static Set resultElementAttr; 79 80 81 private static String resultElements = "RESULT_ELEMENTS_DUMMY_STRING"; 83 84 private static Set template; 85 86 90 private static Map exprAttributes; 91 92 93 private static Set xslFunctions; 94 95 96 private static Set xpathAxes; 97 98 102 private List prefixList = new LinkedList(); 103 104 106 private GrammarQuery resultGrammarQuery; 107 108 110 private String lastDoctypeSystem; 111 112 114 private String lastDoctypePublic; 115 116 private final static String XHTML_PUBLIC_ID = 118 System.getProperty("netbeans.xsl.html.public", "-//W3C//DTD XHTML 1.0 Transitional//EN"); 120 private final static String XHTML_SYSTEM_ID = 122 System.getProperty("netbeans.xsl.html.system", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"); 124 public static final String XSLT_NAMESPACE_URI = "http://www.w3.org/1999/XSL/Transform"; 127 128 private static final String CUSTOMIZER_FOLDER = "Plugins/XML/XSLCustomizer"; 130 private XSLCustomizer customizer = null; 131 132 private ResourceBundle bundle = NbBundle.getBundle(XSLGrammarQuery.class); 133 134 135 public XSLGrammarQuery(DataObject dataObject) { 136 this.dataObject = dataObject; 137 scenarioCookie = (ScenarioCookie)dataObject.getCookie(ScenarioCookie.class); 138 } 139 140 143 private static Map getElementDecls() { 144 if (elementDecls == null) { 145 elementDecls = new HashMap(); 146 attrDecls = new HashMap(); 147 148 Set emptySet = new TreeSet(); 150 String spaceAtt = "xml:space"; Set tmpSet; 152 153 156 Set charInstructions = new TreeSet(Arrays.asList(new String []{"apply-templates", "call-template","apply-imports","for-each","value-of", "copy-of","number","choose","if","text","copy", "variable","message","fallback"})); 161 Set instructions = new TreeSet(charInstructions); 162 instructions.addAll(Arrays.asList(new String []{"processing-instruction", "comment","element","attribute"})); 165 Set charTemplate = charInstructions; 167 template = new TreeSet(instructions); 168 template.add(resultElements); 169 170 Set topLevel = new TreeSet(Arrays.asList(new String []{"import","include","strip-space", "preserve-space","output","key","decimal-format","attribute-set", "variable","param","template","namespace-alias"})); 174 Set topLevelAttr = new TreeSet(Arrays.asList(new String []{"extension-element-prefixes", "exclude-result-prefixes","id","version",spaceAtt})); 177 resultElementAttr = new TreeSet(Arrays.asList(new String []{"extension-element-prefixes", "exclude-result-prefixes","use-attribute-sets","version"})); 180 183 elementDecls.put("stylesheet", topLevel); attrDecls.put("stylesheet", topLevelAttr); 187 elementDecls.put("transform", topLevel); attrDecls.put("transform", topLevelAttr); 191 elementDecls.put("import", emptySet); attrDecls.put("import", new TreeSet(Arrays.asList(new String []{"href"}))); 195 elementDecls.put("include", emptySet); attrDecls.put("include", new TreeSet(Arrays.asList(new String []{"href"}))); 199 elementDecls.put("strip-space", emptySet); attrDecls.put("strip-space", new TreeSet(Arrays.asList(new String []{"elements"}))); 203 elementDecls.put("preserve-space", emptySet); attrDecls.put("preserve-space", new TreeSet(Arrays.asList(new String []{"elements"}))); 207 elementDecls.put("output", emptySet); attrDecls.put("output", new TreeSet(Arrays.asList(new String []{"method", "version","encoding","omit-xml-declaration","standalone","doctype-public", "doctype-system","cdata-section-elements","indent","media-type"}))); 213 elementDecls.put("key", emptySet); attrDecls.put("key", new TreeSet(Arrays.asList(new String []{"name","match","use"}))); 217 elementDecls.put("decimal-format", emptySet); attrDecls.put("decimal-format", new TreeSet(Arrays.asList(new String []{"name", "decimal-separator","grouping-separator","infinity","minus-sign","NaN", "percent","per-mille","zero-digit","digit","pattern-separator"}))); 223 elementDecls.put("namespace-alias", emptySet); attrDecls.put("namespace-alias", new TreeSet(Arrays.asList(new String []{ "stylesheet-prefix","result-prefix"}))); 228 tmpSet = new TreeSet(instructions); 230 tmpSet.add(resultElements); 231 tmpSet.add("param"); elementDecls.put("template", tmpSet); attrDecls.put("template", new TreeSet(Arrays.asList(new String []{ "match","name","priority","mode",spaceAtt}))); 236 elementDecls.put("value-of", emptySet); attrDecls.put("value-of", new TreeSet(Arrays.asList(new String []{ "select","disable-output-escaping"}))); 241 elementDecls.put("copy-of", emptySet); attrDecls.put("copy-of", new TreeSet(Arrays.asList(new String []{"select"}))); 245 elementDecls.put("number", emptySet); attrDecls.put("number", new TreeSet(Arrays.asList(new String []{ "level","count","from","value","format","lang","letter-value", "grouping-separator","grouping-size"}))); 251 elementDecls.put("apply-templates", new TreeSet(Arrays.asList(new String []{ "sort","with-param"}))); attrDecls.put("apply-templates", new TreeSet(Arrays.asList(new String []{ "select","mode"}))); 257 elementDecls.put("apply-imports", emptySet); attrDecls.put("apply-imports", emptySet); 261 tmpSet = new TreeSet(instructions); 263 tmpSet.add(resultElements); 264 tmpSet.add("sort"); elementDecls.put("for-each", tmpSet); attrDecls.put("for-each", new TreeSet(Arrays.asList(new String []{ "select",spaceAtt}))); 269 elementDecls.put("sort", emptySet); attrDecls.put("sort", new TreeSet(Arrays.asList(new String []{ "select","lang","data-type","order","case-order"}))); 274 elementDecls.put("if", template); attrDecls.put("if", new TreeSet(Arrays.asList(new String []{"test",spaceAtt}))); 278 elementDecls.put("choose", new TreeSet(Arrays.asList(new String []{ "when","otherwise"}))); attrDecls.put("choose", new TreeSet(Arrays.asList(new String []{spaceAtt}))); 283 elementDecls.put("when", template); attrDecls.put("when", new TreeSet(Arrays.asList(new String []{ "test",spaceAtt}))); 288 elementDecls.put("otherwise", template); attrDecls.put("otherwise", new TreeSet(Arrays.asList(new String []{spaceAtt}))); 292 elementDecls.put("sort", new TreeSet(Arrays.asList(new String []{"attribute"}))); attrDecls.put("attribute-set", new TreeSet(Arrays.asList(new String []{ "name","use-attribute-sets"}))); 297 elementDecls.put("call-template", new TreeSet(Arrays.asList(new String []{"with-param"}))); attrDecls.put("call-template", new TreeSet(Arrays.asList(new String []{"name"}))); 301 elementDecls.put("with-param", template); attrDecls.put("with-param", new TreeSet(Arrays.asList(new String []{ "name","select"}))); 306 elementDecls.put("variable", template); attrDecls.put("variable", new TreeSet(Arrays.asList(new String []{ "name","select"}))); 311 elementDecls.put("param", template); attrDecls.put("param", new TreeSet(Arrays.asList(new String []{ "name","select"}))); 316 elementDecls.put("text", emptySet); attrDecls.put("text", new TreeSet(Arrays.asList(new String []{ "disable-output-escaping"}))); 321 elementDecls.put("processing-instruction", charTemplate); attrDecls.put("processing-instruction", new TreeSet(Arrays.asList(new String []{ "name",spaceAtt}))); 326 elementDecls.put("element", template); attrDecls.put("element", new TreeSet(Arrays.asList(new String []{ "name","namespace","use-attribute-sets",spaceAtt}))); 331 elementDecls.put("attribute", charTemplate); attrDecls.put("attribute", new TreeSet(Arrays.asList(new String []{ "name","namespace",spaceAtt}))); 336 elementDecls.put("comment", charTemplate); attrDecls.put("comment", new TreeSet(Arrays.asList(new String []{spaceAtt}))); 340 elementDecls.put("copy", template); attrDecls.put("copy", new TreeSet(Arrays.asList(new String []{ spaceAtt,"use-attribute-sets"}))); 345 elementDecls.put("message", template); attrDecls.put("message", new TreeSet(Arrays.asList(new String []{ spaceAtt,"terminate"}))); 350 elementDecls.put("fallback", template); attrDecls.put("fallback", new TreeSet(Arrays.asList(new String []{spaceAtt}))); } 354 return elementDecls; 355 } 356 357 private static Map getAttrDecls() { 358 if (attrDecls == null) { 359 getElementDecls(); 360 } 361 return attrDecls; 362 } 363 364 private static Set getResultElementAttr() { 365 if (resultElementAttr == null) { 366 getElementDecls(); 367 } 368 return resultElementAttr; 369 } 370 371 private static Set getTemplate() { 372 if (template == null) { 373 getElementDecls(); 374 } 375 return template; 376 } 377 378 private static Set getXslFunctions() { 379 if (xslFunctions == null) { 380 xslFunctions = new TreeSet(Arrays.asList(new String []{ 381 "boolean(","ceiling(","concat(", "contains(","count(","current()","document(", "false()", "floor(","format-number(","generate-id(", "id(","local-name(","key(","lang(","last()","name(","namespace-uri(", "normalize-space(", "not(","number(","position()","round(","starts-with(","string(", "string-length(", "substring(","substring-after(","substring-before(", "sum(", "system-property(","translate(", "true()","unparsed-entity-uri("})); } 388 return xslFunctions; 389 } 390 391 private static Set getXPathAxes() { 392 if (xpathAxes == null) { 393 xpathAxes = new TreeSet(Arrays.asList(new String []{"ancestor::", "ancestor-or-self::", "attribute::", "child::", "descendant::", "descendant-or-self::", "following::", "following-sibling::", "namespace::", "parent::", "preceding::", "preceding-sibling::", "self::"})); } 398 return xpathAxes; 399 } 400 401 private static Map getExprAttributes() { 402 if (exprAttributes == null) { 403 exprAttributes = new HashMap(); 404 exprAttributes.put("key", "use"); exprAttributes.put("value-of", "select"); exprAttributes.put("copy-of", "select"); exprAttributes.put("number", "value"); exprAttributes.put("apply-templates", "select"); exprAttributes.put("for-each", "select"); exprAttributes.put("sort", "select"); exprAttributes.put("if", "test"); exprAttributes.put("when", "test"); exprAttributes.put("with-param", "select"); exprAttributes.put("variable", "select"); exprAttributes.put("param", "select"); } 418 return exprAttributes; 419 } 420 421 422 423 426 430 public Enumeration queryElements(HintContext ctx) { 431 Node node = ((Node)ctx).getParentNode(); 432 433 String prefix = ctx.getCurrentPrefix(); 434 QueueEnumeration list = new QueueEnumeration(); 435 436 if (node instanceof Element) { 437 Element el = (Element) node; 438 updateProperties(el); 439 if (prefixList.size() == 0) return org.openide.util.Enumerations.empty(); 440 441 String firstXslPrefixWithColon = prefixList.get(0) + ":"; Set elements; 443 if (el.getTagName().startsWith(firstXslPrefixWithColon)) { 444 String parentNCName = el.getTagName().substring(firstXslPrefixWithColon.length()); 445 elements = (Set) getElementDecls().get(parentNCName); 446 } else { 447 elements = getTemplate(); 449 } 450 451 if (elements != null && resultGrammarQuery != null && elements.contains(resultElements)) { 453 ResultHintContext resultHintContext = new ResultHintContext(ctx, firstXslPrefixWithColon, null); 454 Enumeration resultEnum = resultGrammarQuery.queryElements(resultHintContext); 455 while (resultEnum.hasMoreElements()) { 456 list.put(resultEnum.nextElement()); 457 } 458 } 459 460 addXslElementsToEnum(list, elements, prefixList.get(0) + ":", prefix); 463 for (int prefixInd = 1; prefixInd < prefixList.size(); prefixInd++) { 465 String curPrefix = (String )prefixList.get(prefixInd) + ":"; Node curNode = el; 467 String curName = null; 468 while(curNode != null && null != (curName = curNode.getNodeName()) && !curName.startsWith(curPrefix)) { 469 curNode = curNode.getParentNode(); 470 } 471 472 if (curName == null) { 473 addXslElementsToEnum(list, getElementDecls().keySet(), curPrefix, prefix); 475 } else { 476 String parentName = curName.substring(curPrefix.length()); 477 elements = (Set) getElementDecls().get(parentName); 478 addXslElementsToEnum(list, elements, curPrefix, prefix); 479 } 480 } 481 482 } else if (node instanceof Document) { 483 if (prefixList.size() == 0) return org.openide.util.Enumerations.empty(); 485 addXslElementsToEnum(list, getElementDecls().keySet(), prefixList.get(0) + ":", prefix); } else { 487 return org.openide.util.Enumerations.empty(); 488 } 489 490 return list; 491 } 492 493 public Enumeration queryAttributes(HintContext ctx) { 494 Element el = null; 495 if (ctx.getNodeType() == Node.ATTRIBUTE_NODE) { 497 el = ((Attr)ctx).getOwnerElement(); 498 } else if (ctx.getNodeType() == Node.ELEMENT_NODE) { 499 el = (Element) ctx; 500 } 501 if (el == null) return org.openide.util.Enumerations.empty(); 502 503 String elTagName = el.getTagName(); 504 NamedNodeMap existingAttributes = el.getAttributes(); 505 506 updateProperties(el); 507 508 509 String curXslPrefix = null; 510 for (int ind = 0; ind < prefixList.size(); ind++) { 511 if (elTagName.startsWith((String )prefixList.get(ind) + ":")){ curXslPrefix = (String )prefixList.get(ind) + ":"; break; 514 } 515 } 516 517 Set possibleAttributes; 518 if (curXslPrefix != null) { 519 possibleAttributes = (Set) getAttrDecls().get(el.getTagName().substring(curXslPrefix.length())); 521 } else { 522 possibleAttributes = new TreeSet(); 524 if (prefixList.size() > 0) { 525 Iterator it = getResultElementAttr().iterator(); 526 while ( it.hasNext()) { 527 possibleAttributes.add((String )prefixList.get(0) + ":" + (String ) it.next()); } 529 } 530 } 531 if (possibleAttributes == null) return org.openide.util.Enumerations.empty(); 532 533 String prefix = ctx.getCurrentPrefix(); 534 535 QueueEnumeration list = new QueueEnumeration(); 536 537 if (resultGrammarQuery != null) { 538 Enumeration enum2 = resultGrammarQuery.queryAttributes(ctx); 539 while(enum2.hasMoreElements()) { 540 GrammarResult resNode = (GrammarResult)enum2.nextElement(); 541 if (!possibleAttributes.contains(resNode.getNodeName())) { 542 list.put(resNode); 543 } 544 } 545 } 546 547 Iterator it = possibleAttributes.iterator(); 548 while ( it.hasNext()) { 549 String next = (String ) it.next(); 550 if (next.startsWith(prefix)) { 551 if (existingAttributes.getNamedItem(next) == null) { 552 list.put(new MyAttr(next)); 553 } 554 } 555 } 556 557 return list; 558 } 559 560 public Enumeration queryValues(HintContext ctx) { 561 if (ctx.getNodeType() == Node.ATTRIBUTE_NODE) { 562 updateProperties(((Attr)ctx).getOwnerElement()); 563 if (prefixList.size() == 0) return org.openide.util.Enumerations.empty(); 564 String xslNamespacePrefix = prefixList.get(0) + ":"; 566 String prefix = ctx.getCurrentPrefix(); 567 568 Attr attr = (Attr)ctx; 569 570 boolean isXPath = false; 571 String elName = attr.getOwnerElement().getNodeName(); 572 if (elName.startsWith(xslNamespacePrefix)) { 573 String key = elName.substring(xslNamespacePrefix.length()); 574 String xpathAttrName = (String )getExprAttributes().get(key); 575 if (xpathAttrName != null && xpathAttrName.equals(attr.getNodeName())) { 576 isXPath = true; 578 } 579 580 if ("output".equals(key)) { if ("doctype-public".equals(attr.getName())) { UserCatalog catalog = UserCatalog.getDefault(); 584 if (catalog == null) return org.openide.util.Enumerations.empty(); 585 QueueEnumeration en = new QueueEnumeration(); 586 Iterator it = catalog.getPublicIDs(); 587 while (it.hasNext()) { 588 String next = (String ) it.next(); 589 if (next != null && next.startsWith(prefix)) { 590 en.put(new MyText(next)); 591 } 592 } 593 return en; 594 } 595 } 596 } 597 598 String preExpression = ""; 600 if (!isXPath) { 601 String nodeValue = attr.getNodeValue(); 603 int exprStart = nodeValue.lastIndexOf('{', prefix.length() - 1); int exprEnd = nodeValue.indexOf('}', prefix.length()); Util.THIS.debug("exprStart: " + exprStart); Util.THIS.debug("exprEnd: " + exprEnd); if (exprStart != -1 && exprEnd != -1) { 608 isXPath = true; 609 preExpression = prefix.substring(0, exprStart + 1); 610 prefix = prefix.substring(exprStart + 1); 611 } 612 613 } 614 615 if (isXPath) { 616 QueueEnumeration list = new QueueEnumeration(); 618 619 int curIndex = prefix.length(); 620 while (curIndex > 0) { 621 curIndex--; 622 char curChar = prefix.charAt(curIndex); 623 if (curChar == '(' || curChar == ',' || curChar == ' ') { curIndex++; 625 break; 626 } 627 } 628 629 preExpression += prefix.substring(0, curIndex); 630 String subExpression = prefix.substring(curIndex); 631 632 int lastDiv = subExpression.lastIndexOf('/'); String subPre = ""; String subRest = ""; if (lastDiv != -1) { 636 subPre = subExpression.substring(0, lastDiv + 1); 637 subRest = subExpression.substring(lastDiv + 1); 638 } else { 639 subRest = subExpression; 640 } 641 642 713 714 addItemsToEnum(list, getXPathAxes(), subRest, preExpression + subPre); 715 addItemsToEnum(list, getXslFunctions(), subExpression, preExpression); 716 717 return list; 718 } 719 } 720 721 return org.openide.util.Enumerations.empty(); 722 } 723 724 public GrammarResult queryDefault(HintContext ctx) { 725 if (resultGrammarQuery == null) return null; 727 return resultGrammarQuery.queryDefault(ctx); 728 } 729 730 public boolean isAllowed(Enumeration en) { 731 return true; } 733 734 public Enumeration queryEntities(String prefix) { 735 QueueEnumeration list = new QueueEnumeration(); 736 737 739 if ("lt".startsWith(prefix)) list.put(new MyEntityReference("lt")); if ("gt".startsWith(prefix)) list.put(new MyEntityReference("gt")); if ("apos".startsWith(prefix)) list.put(new MyEntityReference("apos")); if ("quot".startsWith(prefix)) list.put(new MyEntityReference("quot")); if ("amp".startsWith(prefix)) list.put(new MyEntityReference("amp")); 745 return list; 746 } 747 748 public Enumeration queryNotations(String prefix) { 749 return org.openide.util.Enumerations.empty(); 750 } 751 752 public java.awt.Component getCustomizer(HintContext ctx) { 753 if (customizer == null) { 754 customizer = lookupCustomizerInstance(); 755 if (customizer == null) { 756 return null; 757 } 758 } 759 760 return customizer.getCustomizer(ctx, dataObject); 761 } 762 763 public boolean hasCustomizer(HintContext ctx) { 764 if (customizer == null) { 765 customizer = lookupCustomizerInstance(); 766 if (customizer == null) { 767 return false; 768 } 769 } 770 771 return customizer.hasCustomizer(ctx); 772 } 773 774 public org.openide.nodes.Node.Property[] getProperties(final HintContext ctx) { 775 776 if (ctx.getNodeType() != Node.ATTRIBUTE_NODE || ctx.getNodeValue() == null) { 777 return null; 778 } 779 780 PropertySupport attrNameProp = new PropertySupport("Attribute name", String .class, bundle.getString("BK0001"), bundle.getString("BK0002"), true, false) { 782 public void setValue(Object value) { 783 } 785 public Object getValue() { 786 return ctx.getNodeName(); 787 } 788 789 }; 790 791 PropertySupport attrValueProp = new PropertySupport("Attribute value", String .class, bundle.getString("BK0003"), bundle.getString("BK0004"), true, true) { 793 public void setValue(Object value) { 794 ctx.setNodeValue((String )value); 795 } 796 public Object getValue() { 797 return ctx.getNodeValue(); 798 } 799 800 }; 801 802 return new org.openide.nodes.Node.Property[]{attrNameProp, attrValueProp}; 803 } 804 805 808 811 private static XSLCustomizer lookupCustomizerInstance() { 812 try { 813 FileSystem fs = Repository.getDefault().getDefaultFileSystem(); 815 FileObject fo = fs.findResource(CUSTOMIZER_FOLDER); 816 if (fo == null) return null; 817 DataObject df = DataObject.find(fo); 818 if (!(df instanceof DataObject.Container)) { 819 return null; 820 } 821 822 824 FolderLookup lookup = 825 new FolderLookup((DataObject.Container) df); 826 Lookup.Template template = 827 new Lookup.Template(XSLCustomizer.class); 828 829 Lookup.Item lookupItem = lookup.getLookup().lookupItem(template); 830 if (lookupItem == null) { 831 return null; 832 } 833 834 return (XSLCustomizer)lookupItem.getInstance(); 835 } catch (DataObjectNotFoundException e) { 836 return null; 837 } 838 } 839 840 847 private static void addXslElementsToEnum(QueueEnumeration enumX, Set elements, String namespacePrefix, String startWith) { 848 if (elements == null) return; 849 if (startWith.startsWith(namespacePrefix) || namespacePrefix.startsWith(startWith)) { 850 Iterator it = elements.iterator(); 851 while ( it.hasNext()) { 852 Object next = it.next(); 853 if (next != resultElements) { 854 String nextText = namespacePrefix + (String )next; 855 if (nextText.startsWith(startWith)) { 856 enumX.put(new MyElement(nextText, false)); 858 } 859 } 860 } 861 } 862 } 863 864 private static void addItemsToEnum(QueueEnumeration enumX, Set set, String startWith, String prefix) { 865 Iterator it = set.iterator(); 866 while ( it.hasNext()) { 867 String nextText = (String )it.next(); 868 if (nextText.startsWith(startWith)) { 869 enumX.put(new MyText(prefix + nextText)); 870 } 871 } 872 } 873 874 880 private void updateProperties(Node curNode) { 881 prefixList.clear(); 882 883 Node rootNode = curNode; 885 while (curNode != null && !(curNode instanceof Document)) { 886 887 NamedNodeMap attributes = curNode.getAttributes(); 889 for (int ind = 0; ind < attributes.getLength(); ind++) { 890 Attr attr = (Attr)attributes.item(ind); 891 String attrName = attr.getName(); 892 if (attrName != null && attrName.startsWith("xmlns:")) { if (attr.getValue().equals(XSLT_NAMESPACE_URI)) { 894 prefixList.add(0, attrName.substring(6)); 895 } 896 } 897 } 898 899 900 rootNode = curNode; 901 curNode = rootNode.getParentNode(); 902 } 903 904 boolean outputFound = false; 905 if (prefixList.size() > 0) { 906 String outputElName = (String )prefixList.get(0) + ":output"; Node childOfRoot = rootNode.getFirstChild(); 908 while (childOfRoot != null) { 909 String childNodeName = childOfRoot.getNodeName(); 910 if (childNodeName != null && childNodeName.equals(outputElName)) { 911 Element outputEl = (Element)childOfRoot; 912 String outputMethod = outputEl.getAttribute("method"); 914 String curDoctypePublic = outputEl.getAttribute("doctype-public"); String curDoctypeSystem = outputEl.getAttribute("doctype-system"); 917 if ("html".equals(outputMethod) && (curDoctypePublic == null || curDoctypePublic.length() == 0) 919 && (curDoctypeSystem == null || curDoctypeSystem.length() == 0)) { curDoctypePublic = XHTML_PUBLIC_ID; 922 curDoctypeSystem = XHTML_SYSTEM_ID; 923 } else if ("text".equals(outputMethod)) { break; 926 } 927 928 if (curDoctypePublic != null && !curDoctypePublic.equals(lastDoctypePublic) || 929 curDoctypePublic == null && lastDoctypePublic != null || 930 curDoctypeSystem != null && !curDoctypeSystem.equals(lastDoctypeSystem) || 931 curDoctypeSystem == null && lastDoctypeSystem != null) { 932 setOutputDoctype(curDoctypePublic, curDoctypeSystem); 933 } 934 935 outputFound = true; 936 break; 937 } 938 childOfRoot = childOfRoot.getNextSibling(); 939 } 940 } 941 942 if (!outputFound) { 943 setOutputDoctype(null, null); 944 } 945 } 946 947 953 private void setOutputDoctype(String publicId, String systemId) { 954 lastDoctypePublic = publicId; 955 lastDoctypeSystem = systemId; 956 957 if (publicId == null && systemId == null) { 958 resultGrammarQuery = null; 959 return; 960 } 961 962 InputSource inputSource = null; 963 UserCatalog catalog = UserCatalog.getDefault(); 964 if (catalog != null) { 965 EntityResolver resolver = catalog.getEntityResolver(); 966 if (resolver != null) { 967 try { 968 inputSource = resolver.resolveEntity(publicId, systemId); 969 } catch(SAXException e) { 970 } catch(IOException e) { 971 } } 973 } 974 975 if (inputSource == null) { 976 try { 977 java.net.URL url = new java.net.URL (systemId); 978 inputSource = new InputSource (url.openStream()); 979 inputSource.setPublicId(publicId); 980 inputSource.setSystemId(systemId); 981 } catch(IOException e) { 982 resultGrammarQuery = null; 983 return; 984 } 985 } 986 987 resultGrammarQuery = DTDUtil.parseDTD(true, inputSource); 988 989 } 990 991 994 private class ResultHintContext extends ResultNode implements HintContext { 995 private String currentPrefix; 996 997 public ResultHintContext(HintContext peer, String ignorePrefix, String onlyUsePrefix) { 998 super(peer, ignorePrefix, onlyUsePrefix); 999 currentPrefix = peer.getCurrentPrefix(); 1000 } 1001 1002 public String getCurrentPrefix() { 1003 return currentPrefix; 1004 } 1005 } 1006 1007 1009 1010 private static abstract class AbstractResultNode extends AbstractNode implements GrammarResult { 1011 1012 public Icon getIcon(int kind) { 1013 return null; 1014 } 1015 1016 1019 public String getDescription() { 1020 return NbBundle.getMessage(XSLGrammarQuery.class, "BK0005"); 1021 } 1022 1023 1027 public String getText() { 1028 return getNodeName(); 1029 } 1030 1031 1034 public String getDisplayName() { 1035 return null; 1036 } 1037 1038 public boolean isEmptyElement() { 1039 return false; 1040 } 1041 1042 } 1043 1044 private static class MyEntityReference extends AbstractResultNode implements EntityReference { 1045 1046 private String name; 1047 1048 MyEntityReference(String name) { 1049 this.name = name; 1050 } 1051 1052 public short getNodeType() { 1053 return Node.ENTITY_REFERENCE_NODE; 1054 } 1055 1056 public String getNodeName() { 1057 return name; 1058 } 1059 1060 } 1061 1062 private static class MyElement extends AbstractResultNode implements Element { 1063 1064 private String name; 1065 private boolean empty; 1066 1067 MyElement(String name, boolean empty) { 1068 this.name = name; 1069 this.empty = empty; 1070 } 1071 1072 public short getNodeType() { 1073 return Node.ELEMENT_NODE; 1074 } 1075 1076 public String getNodeName() { 1077 return name; 1078 } 1079 1080 public String getTagName() { 1081 return name; 1082 } 1083 1084 public boolean isEmptyElement() { 1085 return empty; 1086 } 1087 1088 } 1089 1090 private static class MyAttr extends AbstractResultNode implements Attr { 1091 1092 private String name; 1093 1094 MyAttr(String name) { 1095 this.name = name; 1096 } 1097 1098 public short getNodeType() { 1099 return Node.ATTRIBUTE_NODE; 1100 } 1101 1102 public String getNodeName() { 1103 return name; 1104 } 1105 1106 public String getName() { 1107 return name; 1108 } 1109 1110 public String getValue() { 1111 return null; } 1113 1114 1115 } 1116 1117 1118 private static class MyText extends AbstractResultNode implements Text { 1119 1120 private String data; 1121 1122 MyText(String data) { 1123 this.data = data; 1124 } 1125 1126 public short getNodeType() { 1127 return Node.TEXT_NODE; 1128 } 1129 1130 public String getNodeValue() { 1131 return getData(); 1132 } 1133 1134 public String getData() throws DOMException { 1135 return data; 1136 } 1137 1138 public int getLength() { 1139 return data == null ? -1 : data.length(); 1140 } 1141 } 1142 1143 private static class QueueEnumeration implements Enumeration { 1144 private java.util.LinkedList list = new LinkedList (); 1145 1146 public boolean hasMoreElements () { 1147 return !list.isEmpty (); 1148 } 1149 1150 public Object nextElement () { 1151 return list.removeFirst (); 1152 } 1153 1154 public void put (Object [] arr) { 1155 list.addAll (Arrays.asList (arr)); 1156 } 1157 public void put (Object o) { 1158 list.add (o); 1159 } 1160 1161 } } 1163 | Popular Tags |