1 19 20 package org.netbeans.modules.web.core.syntax; 21 22 import java.io.File ; 23 import java.util.*; 24 import java.net.URL ; 25 import javax.swing.text.BadLocationException ; 26 import javax.swing.text.EditorKit ; 27 import javax.swing.JEditorPane ; 28 import javax.swing.text.JTextComponent ; 29 import javax.servlet.jsp.tagext.*; 30 import org.netbeans.api.lexer.Language; 31 import org.netbeans.api.lexer.TokenHierarchy; 32 import org.netbeans.api.lexer.TokenSequence; 33 import org.netbeans.editor.ext.html.HTMLCompletionQuery; 34 import org.netbeans.modules.web.core.syntax.deprecated.ELTokenContext; 35 import org.netbeans.modules.web.core.syntax.deprecated.JspDirectiveTokenContext; 36 import org.netbeans.modules.web.core.syntax.deprecated.JspMultiTokenContext; 37 import org.netbeans.modules.web.core.syntax.deprecated.JspTagTokenContext; 38 import org.openide.filesystems.FileObject; 39 import org.openide.ErrorManager; 40 import org.openide.loaders.DataObject; 41 import org.netbeans.modules.web.jsps.parserapi.JspParserAPI; 42 import org.netbeans.modules.web.jsps.parserapi.PageInfo; 43 import org.netbeans.editor.*; 44 import org.netbeans.editor.ext.ExtSyntaxSupport; 45 import org.netbeans.editor.ext.html.HTMLTokenContext; 46 import org.netbeans.editor.ext.java.JavaTokenContext; 47 import org.netbeans.modules.editor.NbEditorUtilities; 48 import org.openide.filesystems.FileUtil; 49 import org.openide.modules.InstalledFileLocator; 50 import org.netbeans.modules.web.core.syntax.completion.JspCompletionItem; 51 import org.openide.text.CloneableEditorSupport; 52 53 58 public class JspSyntaxSupport extends ExtSyntaxSupport { 59 60 61 static final ErrorManager err = 62 ErrorManager.getDefault().getInstance("org.netbeans.modules.web.jspsyntax"); 64 66 67 68 public static final int TAG_COMPLETION_CONTEXT = 1; 69 70 public static final int ENDTAG_COMPLETION_CONTEXT = 2; 71 72 public static final int DIRECTIVE_COMPLETION_CONTEXT = 3; 73 74 public static final int COMMENT_COMPLETION_CONTEXT = 4; 75 77 public static final int TEXT_COMPLETION_CONTEXT = 5; 78 79 public static final int CONTENTL_COMPLETION_CONTEXT = 6; 80 81 public static final int SCRIPTINGL_COMPLETION_CONTEXT = 7; 82 83 public static final int ERROR_COMPLETION_CONTEXT = 8; 84 85 public static final int EL_COMPLETION_CONTEXT = 9; 86 87 88 89 private static final String STANDARD_JSP_PREFIX = "jsp"; 92 private static TagInfo[] standardJspTagDatas; 93 94 private static TagInfo[] standardTagTagDatas; 95 97 private static TagInfo[] xmlJspTagDatas; 98 99 101 private static TagInfo[] xmlTagFileTagDatas; 102 103 105 private static TagInfo[] directiveJspData; 106 private static TagInfo[] directiveTagFileData; 107 108 110 private static HashMap helpMap = null; 111 112 private static final TokenID[] JSP_BRACKET_SKIP_TOKENS = new TokenID[] { 113 JavaTokenContext.LINE_COMMENT, 114 JavaTokenContext.BLOCK_COMMENT, 115 JavaTokenContext.CHAR_LITERAL, 116 JavaTokenContext.STRING_LITERAL, 117 JspTagTokenContext.ATTR_VALUE, 118 JspTagTokenContext.COMMENT 119 }; 120 121 protected FileObject fobj; 122 123 124 private ExtSyntaxSupport contentLanguageSyntaxSupport = null; 125 126 127 private boolean useCustomBracketFinder = true; 128 129 private boolean isXmlSyntax = false; 130 131 private static final TagNameComparator TAG_NAME_COMPARATOR = new TagNameComparator(); 132 133 134 135 public JspSyntaxSupport(BaseDocument doc, boolean isXml) { 136 super(doc); 137 fobj = null; 138 if (doc != null){ 139 DataObject dobj = NbEditorUtilities.getDataObject(doc); 140 fobj = (dobj != null) ? NbEditorUtilities.getDataObject(doc).getPrimaryFile(): null; 141 } 142 143 isXmlSyntax = isXml; 144 } 145 146 public JspSyntaxSupport(BaseDocument doc) { 147 this(doc, false); 148 } 149 150 public String [] getImports(){ 151 JspParserAPI.ParseResult pre = getParseResult(); 152 if (pre != null){ 153 PageInfo pi = pre.getPageInfo(); 154 if(pi == null) { 155 ErrorManager.getDefault().notify(ErrorManager.WARNING, new NullPointerException ("PageInfo obtained from JspParserAPI.ParseResult is null!")); 157 return null; 158 } 159 List<String > imports = pi.getImports(); 160 return imports.toArray(new String [imports.size()]); 161 } 162 163 return null; 164 } 165 166 public boolean isXmlSyntax(){ 167 return isXmlSyntax; 168 } 169 170 protected JspParserAPI.ParseResult getParseResult() { 171 JspParserAPI.ParseResult result = JspUtils.getCachedParseResult(getDocument(), fobj, true, false); 172 if (result == null) { 173 result = JspUtils.getCachedParseResult(getDocument(), fobj, false, false); 174 } 175 return result; 176 } 177 178 181 private Map getPrefixMapper() { 182 JspParserAPI.ParseResult result = getParseResult(); 184 Map prefixMapper = null; 185 if (result != null && result.getPageInfo() != null) { 186 if (result.getPageInfo().getXMLPrefixMapper().size() > 0) { 189 prefixMapper = result.getPageInfo().getApproxXmlPrefixMapper(); 190 if (prefixMapper.size() == 0){ 191 prefixMapper = result.getPageInfo().getXMLPrefixMapper(); 192 } 193 prefixMapper.putAll(result.getPageInfo().getJspPrefixMapper()); 194 195 } else { 196 prefixMapper = result.getPageInfo().getJspPrefixMapper(); 197 } 198 } 200 return prefixMapper; 201 } 202 203 private Map getTagLibraries() { 204 getTagLibraryMappings(); 206 JspParserAPI.ParseResult result = JspUtils.getCachedParseResult(getDocument(), fobj, false, true, true); 208 if (result != null) return result.getPageInfo().getTagLibraries(); 209 210 return null; } 212 213 private TagInfo[] getSortedTagInfos(TagInfo[] tinfos) { 214 Arrays.sort(tinfos, new Comparator() { 215 public int compare(Object o1, Object o2) { 216 TagInfo ti1 = (TagInfo)o1; 217 TagInfo ti2 = (TagInfo)o2; 218 String tname1 = (ti1.getDisplayName() == null ? ti1.getTagName() : ti1.getDisplayName()); 219 String tname2 = (ti2.getDisplayName() == null ? ti2.getTagName() : ti2.getDisplayName()); 220 if(tname1 == null || tname2 == null) return 0; 221 return tname1.compareTo(tname2); 222 } 223 public boolean equals(Object o) { 224 return o.equals(this); 225 } 226 }); 227 return tinfos; 228 } 229 230 private TagLibraryInfo getTagLibrary(String prefix) { 231 Map mapper = getPrefixMapper(); 232 if (mapper != null) { 233 Object uri = mapper.get(prefix); 234 if (uri != null) { 235 Map taglibs = getTagLibraries(); 236 if (taglibs != null) { 237 return (TagLibraryInfo)taglibs.get(uri); 238 } 239 } 240 } 241 return null; 242 } 243 244 protected SyntaxSupport createSyntaxSupport(Class syntaxSupportClass) { 245 SyntaxSupport support = super.createSyntaxSupport(syntaxSupportClass); 249 if (support != null) 250 return support; 251 253 EditorKit kit; 254 kit = CloneableEditorSupport.getEditorKit(JspUtils.getContentLanguage()); 256 if (kit instanceof BaseKit) { 257 support = ((BaseKit)kit).createSyntaxSupport(getDocument()); 258 if (support != null) 259 return support; 260 } 261 kit = CloneableEditorSupport.getEditorKit(JspUtils.getScriptingLanguage()); 263 if (kit instanceof BaseKit) { 264 support = ((BaseKit)kit).createSyntaxSupport(getDocument()); 265 if (support != null) 266 return support; 267 } 268 return null; 269 } 270 271 273 protected ExtSyntaxSupport getContentLanguageSyntaxSupport() { 274 if (contentLanguageSyntaxSupport != null) { 275 return contentLanguageSyntaxSupport; 276 } 277 278 EditorKit kit = 279 JEditorPane.createEditorKitForContentType(JspUtils.getContentLanguage()); 280 if (kit instanceof BaseKit) { 281 SyntaxSupport support = ((BaseKit)kit).createSyntaxSupport(getDocument()); 282 if (support != null && support instanceof ExtSyntaxSupport) { 283 contentLanguageSyntaxSupport = (ExtSyntaxSupport) support; 284 return contentLanguageSyntaxSupport; 285 } 286 } 287 return (ExtSyntaxSupport)get( org.netbeans.editor.ext.html.HTMLSyntaxSupport.class ); 288 } 289 290 293 public int checkCompletion(JTextComponent target, String typedText, boolean visible ) { 294 295 char first = typedText.charAt(0); 297 TokenItem item = null; try{ 299 item = getItemAtOrBefore(target.getCaret().getDot()); 300 }catch(BadLocationException e) { 301 return COMPLETION_HIDE; 302 } 303 if (item == null) return COMPLETION_HIDE; 304 305 TokenContextPath tcp = item.getTokenContextPath(); 306 307 309 if(tcp.contains(HTMLTokenContext.contextPath)) { 310 if (err.isLoggable(ErrorManager.INFORMATIONAL)) err.log("CONTENTL_COMPLETION_CONTEXT"); ExtSyntaxSupport support = getContentLanguageSyntaxSupport(); 313 if (support != null) { 314 return support.checkCompletion( target, typedText, visible ); 315 } 316 } 317 318 if(tcp.contains(JavaTokenContext.contextPath)) { 319 return COMPLETION_CANCEL; } 321 322 if(tcp.contains(JspTagTokenContext.contextPath)) { 324 TokenItem tracking = item; 326 327 int maxBacktrace = 20 * 4; 336 337 do { 338 if(tracking.getTokenID() == JspTagTokenContext.ERROR) return COMPLETION_HIDE; 340 341 String image = tracking.getImage(); 342 344 if(image.equals("%>")) return COMPLETION_HIDE; 346 347 if(tracking.getImage().startsWith("<%")) { 348 if (err.isLoggable(ErrorManager.INFORMATIONAL)) err.log("DIRECTIVE_COMPLETION_CONTEXT"); 351 if( !visible && first == '=' && tracking.getImage().equals("<%")) return COMPLETION_POPUP; 353 354 if( !visible && first == '%' || first == '@' || first == ' ' ) return COMPLETION_POPUP; 355 if( visible && first == '=' || first == '>' ) return COMPLETION_HIDE; 356 return visible ? COMPLETION_POST_REFRESH : COMPLETION_CANCEL; 357 } 358 if(tracking.getImage().equals("<")) { 359 if (err.isLoggable(ErrorManager.INFORMATIONAL)) err.log("TAG_COMPLETION_CONTEXT"); if( !visible && first == ' ' || first == ':' ) return COMPLETION_POPUP; 362 if( visible && first == '>' ) return COMPLETION_HIDE; 363 return visible ? COMPLETION_POST_REFRESH : COMPLETION_CANCEL; 364 } 365 if(tracking.getImage().equals("</")) { 366 if (err.isLoggable(ErrorManager.INFORMATIONAL)) err.log("ENDTAG_COMPLETION_CONTEXT" ); if( visible && first == '>' ) return COMPLETION_HIDE; 369 return visible ? COMPLETION_POST_REFRESH : COMPLETION_CANCEL; 370 } 371 if(!tracking.getTokenContextPath().contains(JspTagTokenContext.contextPath)) { 373 if (err.isLoggable(ErrorManager.INFORMATIONAL)) err.log("We are out of jsp tag without finding any tag start token!"); 374 break; 375 } 376 377 if(tracking.getImage().equals(">")) { 378 try { 379 SyntaxElement se = getElementChain(tracking.getOffset()); 381 if(se != null && (se instanceof SyntaxElement.Tag)) { 382 return COMPLETION_POPUP; 383 } 384 }catch(BadLocationException e) { 385 } 387 return COMPLETION_HIDE; 388 } 389 390 tracking = tracking.getPrevious(); 392 393 } while((maxBacktrace-- > 0) && (tracking != null)); 394 395 } 397 if(tcp.contains(ELTokenContext.contextPath)) { 398 if (visible) return COMPLETION_HIDE; 400 } 401 402 return COMPLETION_HIDE; 403 } 404 405 406 private final int getTokenEnd( TokenItem item ) { 407 if (item == null) 408 return 0; return item.getOffset() + item.getImage().length(); 410 } 411 412 414 public final List filterList(List toFilter, String prefix) { 415 List newList = new ArrayList(); 416 Object item; 417 for (int i = 0; i < toFilter.size(); i++) { 418 item = toFilter.get(i); 419 String txt; 420 if (item instanceof TagInfo) 421 txt = ((TagInfo)item).getTagName(); 422 else if (item instanceof TagAttributeInfo) 423 txt = ((TagAttributeInfo)item).getName(); 424 else 425 txt = (String )item; 426 427 if (txt != null && txt.startsWith(prefix)) { 428 newList.add(item); 429 } 430 } 431 return newList; 432 } 433 434 435 public final List getTagPrefixes(String complPrefix) { 436 return filterList(getAllTagPrefixes(), complPrefix); 437 } 438 439 442 public final List getTags(String complPrefix) { 443 int colonIndex = complPrefix.indexOf(":"); if (colonIndex == -1) 445 throw new IllegalArgumentException (); 446 return getTags(complPrefix.substring(0, colonIndex), 447 complPrefix.substring(colonIndex + 1)); 448 } 449 450 454 public final List getTags(String tagPrefix, String complPrefix) { 455 return filterList(getAllTags(tagPrefix), complPrefix); 456 } 457 458 462 public final List getTagAttributes(String tagPrefixName, String complPrefix) { 463 int colonIndex = tagPrefixName.indexOf(":"); if (colonIndex == -1) 465 throw new IllegalArgumentException (); 466 return getTagAttributes(tagPrefixName.substring(0, colonIndex), 467 tagPrefixName.substring(colonIndex + 1), complPrefix); 468 } 469 470 474 protected final List getTagAttributes(String tagPrefix, String tagName, String complPrefix) { 475 return filterList(getAllTagAttributes(tagPrefix, tagName), complPrefix); 476 } 477 478 479 public final List getDirectives(String complPrefix) { 480 return filterList(getAllDirectives(), complPrefix); 481 } 482 483 485 public final List getDirectiveAttributes(String directive, String complPrefix) { 486 return filterList(getAllDirectiveAttributes(directive), complPrefix); 487 } 488 489 492 protected List getAllTagPrefixes() { 493 List items = new ArrayList(); 494 495 items.add(STANDARD_JSP_PREFIX); 497 498 Map mapper = getPrefixMapper(); 499 if (mapper != null) { 500 TreeSet ts = new TreeSet(); 502 ts.addAll(mapper.keySet()); 503 ts.remove("jsp"); items.addAll(ts); 505 } 506 516 return items; 517 } 518 519 521 protected List getAllTags(String prefix) { 522 List items = new ArrayList(); 523 524 initCompletionData(); 526 if (STANDARD_JSP_PREFIX.equals(prefix)) { 527 TagInfo[] stanTagDatas = getTagInfos(); 528 for (int i=0; i<stanTagDatas.length; i++) { 529 items.add(stanTagDatas[i]); 530 } 531 } 532 533 TagLibraryInfo info = getTagLibrary(prefix); 534 if (info != null && info.getTags() != null) { 535 TagInfo[] tags = getSortedTagInfos(info.getTags()); 536 String url = (String )helpMap.get(info.getURI()); 537 if (url != null && !url.equals("")){ 538 for (int i = 0; i < tags.length; i++) { 539 items.add(new TagInfo(tags[i].getTagName(), 540 tags[i].getTagClassName(), tags[i].getBodyContent(), 541 url + tags[i].getTagName() + ".html#tag-start-" + tags[i].getTagName() 542 + "#tag-end-" + tags[i].getTagName(), info, 543 tags[i].getTagExtraInfo(), tags[i].getAttributes(), 544 tags[i].getDisplayName(), tags[i].getSmallIcon(), tags[i].getLargeIcon(), 545 tags[i].getTagVariableInfos(), tags[i].hasDynamicAttributes())); 546 } 547 } else { 548 for (int i = 0; i < tags.length; i++) { 549 items.add(tags[i]); 550 } 551 } 552 } 553 return items; 554 } 555 556 559 protected List getAllTagAttributes(String prefix, String tag) { 560 List items = new ArrayList(); 561 562 initCompletionData(); 564 if (STANDARD_JSP_PREFIX.equals(prefix)) { 565 TagInfo[] stanTagDatas = getTagInfos(); 566 for (int i=0; i<stanTagDatas.length; i++) { 567 if (stanTagDatas[i].getTagName().equals(tag)) { 568 TagAttributeInfo[] attrs = stanTagDatas[i].getAttributes(); 569 for (int j=0; j<attrs.length; j++) 570 items.add(attrs[j]); 571 break; 572 } 573 } 574 } 575 576 TagLibraryInfo info = getTagLibrary(prefix); 577 if (info != null) { 578 TagInfo tagInfo = info.getTag(tag); 579 if (tagInfo != null) { 580 TagAttributeInfo[] attributes = tagInfo.getAttributes(); 581 String url = (String )helpMap.get(tagInfo.getTagLibrary().getURI()); 582 if (url != null && !url.equals("")){ 583 for (int i = 0; i < attributes.length; i++) { 584 items.add(new TagAttributeInfo(attributes[i].getName(), 585 attributes[i].isRequired(), 586 url + tagInfo.getTagName() + ".html#attribute-start-" + attributes[i].getName() 587 + "#attribute-end-" + attributes[i].getName(), 588 attributes[i].canBeRequestTime(), 589 attributes[i].isFragment())); 590 } 591 } else { 592 for (int i = 0; i < attributes.length; i++) 593 items.add(attributes[i]); 594 } 595 } 596 } 597 return items; 598 } 599 600 601 602 603 protected List getAllDirectives() { 604 initCompletionData(); 605 List items = new ArrayList(); 606 607 if (isXmlSyntax) return items; 609 610 TagInfo[] directiveData; 611 if(NbEditorUtilities.getMimeType(getDocument()).equals(JspUtils.TAG_MIME_TYPE)) 612 directiveData = directiveTagFileData; 613 else { 614 directiveData = directiveJspData; 615 616 } 617 for (int i = 0; i < directiveData.length; i++){ 618 items.add(directiveData[i]); 619 } 620 return items; 621 } 622 623 624 protected List getAllDirectiveAttributes(String directive) { 625 initCompletionData(); 626 List items = new ArrayList(); 627 if (isXmlSyntax) return items; 629 630 TagInfo[] directiveData; 631 if(NbEditorUtilities.getMimeType(getDocument()).equals(JspUtils.TAG_MIME_TYPE)) 632 directiveData = directiveTagFileData; 633 else 634 directiveData = directiveJspData; 635 for (int i=0; i<directiveData.length; i++) { 636 if (directiveData[i].getTagName().equals(directive)) { 637 TagAttributeInfo[] attrs = directiveData[i].getAttributes(); 638 for (int j=0; j<attrs.length; j++) 639 items.add(attrs[j]); 640 break; 641 } 642 } 643 return items; 644 } 645 646 public PageInfo.BeanData[] getBeanData() { 647 JspParserAPI.ParseResult result = getParseResult(); 648 if (result != null) { 649 return result.getPageInfo().getBeans(); 650 } 651 654 return null; 655 } 656 657 public boolean isErrorPage() { 658 JspParserAPI.ParseResult result = getParseResult(); 659 if (result != null) { 660 if (result.getPageInfo() != null) 661 return result.getPageInfo().isErrorPage(); 662 } 663 666 return false; 667 } 668 669 670 678 public Map getTagLibraryMappings() { 679 if (fobj == null) { 680 return null; 681 } 682 return JspUtils.getTaglibMap(getDocument(), fobj); 683 } 684 685 private static void initHelp(){ 686 if (helpMap == null){ 687 String url=""; 688 File f = InstalledFileLocator.getDefault().locate("docs/jstl11-doc.zip", null, false); if (f != null){ 690 try { 691 URL urll = f.toURL(); 692 urll = FileUtil.getArchiveRoot(urll); 693 url = urll.toString(); 694 } catch (java.net.MalformedURLException e){ 695 ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, e); 696 } 698 } 699 helpMap = new HashMap(); 700 helpMap.put("http://java.sun.com/jsp/jstl/core", url + "c/"); 702 helpMap.put("http://java.sun.com/jstl/core", url + "c/"); 703 helpMap.put("http://java.sun.com/jstl/core_rt", url + "c_rt/"); 704 helpMap.put("http://java.sun.com/jsp/jstl/fmt", url + "fmt/"); 705 helpMap.put("http://java.sun.com/jstl/fmt", url + "fmt/"); 706 helpMap.put("http://java.sun.com/jstl/fmt_rt", url + "fmt_rt/"); 707 helpMap.put("http://java.sun.com/jsp/jstl/functions", url + "fn/"); 708 helpMap.put("http://java.sun.com/jstl/functions", url + "fn/"); 709 helpMap.put("http://jakarta.apache.org/taglibs/standard/permittedTaglibs", url+"permittedTaglibs/"); 710 helpMap.put("http://jakarta.apache.org/taglibs/standard/scriptfree", url+ "scriptfree/"); 711 helpMap.put("http://java.sun.com/jsp/jstl/sql", url + "sql/"); 712 helpMap.put("http://java.sun.com/jstl/sql", url + "sql/"); 713 helpMap.put("http://java.sun.com/jstl/sql_rt", url + "sql_rt/"); 714 helpMap.put("http://java.sun.com/jsp/jstl/xml", url + "x/"); 715 helpMap.put("http://java.sun.com/jstl/xml", url + "x/"); 716 helpMap.put("http://java.sun.com/jstl/xml_rt", url + "x_rt/"); 717 f = InstalledFileLocator.getDefault().locate("docs/jsf12-tlddoc.zip", null, false); if (f != null){ 719 try { 720 URL urll = f.toURL(); 721 urll = FileUtil.getArchiveRoot(urll); 722 url = urll.toString(); 723 helpMap.put("http://java.sun.com/jsf/html", url + "h/"); 724 helpMap.put("http://java.sun.com/jsf/core", url + "f/"); 725 } catch (java.net.MalformedURLException e){ 726 ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, e); 727 } 729 } 730 f = InstalledFileLocator.getDefault().locate("docs/struts-tags.zip", null, false); 731 if (f != null){ 732 try { 733 URL urll = f.toURL(); 734 urll = FileUtil.getArchiveRoot(urll); 735 url = urll.toString(); 736 helpMap.put("http://jakarta.apache.org/struts/tags-bean", url + "bean/"); 737 helpMap.put("http://struts.apache.org/tags-bean", url + "bean/"); 738 helpMap.put("/WEB-INF/struts-bean.tld", url + "bean/"); 739 helpMap.put("http://jakarta.apache.org/struts/tags-html", url + "html/"); 740 helpMap.put("http://struts.apache.org/tags-html", url + "html/"); 741 helpMap.put("/WEB-INF/struts-html.tld", url + "html/"); 742 helpMap.put("http://jakarta.apache.org/struts/tags-logic", url + "logic/"); 743 helpMap.put("http://struts.apache.org/tags-logic", url + "logic/"); 744 helpMap.put("/WEB-INF/struts-logic.tld", url + "logic/"); 745 helpMap.put("http://jakarta.apache.org/struts/tags-nested", url + "nested/"); 746 helpMap.put("http://struts.apache.org/tags-nested", url + "nested/"); 747 helpMap.put("/WEB-INF/struts-nested.tld", url + "nested/"); 748 helpMap.put("http://jakarta.apache.org/struts/tags-tiles", url + "tiles/"); 749 helpMap.put("http://struts.apache.org/tags-tiles", url + "tiles/"); 750 helpMap.put("/WEB-INF/struts-tiles.tld", url + "tiles/"); 751 } catch (java.net.MalformedURLException e){ 752 ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, e); 753 } 755 } 756 757 } 758 759 } 760 761 private static void initCompletionData() { 762 if (helpMap == null) 763 initHelp(); 764 String url = ""; if (standardJspTagDatas == null) { 766 final String helpFiles = "docs/syntaxref20.zip"; File f = InstalledFileLocator.getDefault().locate(helpFiles, null, true); if (f != null){ 769 try { 770 URL urll = f.toURL(); 771 urll = FileUtil.getArchiveRoot(urll); 772 url = urll.toString(); 773 } catch (java.net.MalformedURLException e){ 774 err.notify(ErrorManager.EXCEPTION, e); 775 } 777 } 778 standardJspTagDatas = new TagInfo[] { 779 new TagInfo("attribute", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2014.html", null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2014.html#1003581#1006483", false), new TagAttributeInfo("trim", false, url + "syntaxref2014.html#1006483#1003583", false)}), new TagInfo("body", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2015.html#1006731#1003768", null, null, new TagAttributeInfo[]{}), 784 new TagInfo("element", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2016.html#1003696#1003708", null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2016.html#1003706#1003708", false)}), new TagInfo("expression", null, TagInfo.BODY_CONTENT_JSP, url+"syntaxref205.html#1004353#11268", null, null, new TagAttributeInfo[] {}), 788 new TagInfo("fallback", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2023.html#11583#19029", null, null, new TagAttributeInfo[] {}), 790 new TagInfo("forward", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2018.html#1003349#15708", null, null, new TagAttributeInfo[] { new TagAttributeInfo("page", true, url + "syntaxref2018.html#15704#15708", true)}), new TagInfo("getProperty", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2019.html#8820#9201", null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2019.html#15748#10919", false), new TagAttributeInfo("property", true, url + "syntaxref2019.html#10919#19482", false)}), new TagInfo("include", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2020.html#8828#9228", null, null, new TagAttributeInfo[] { new TagAttributeInfo("flush", true, url + "syntaxref2020.html#17145#18376", false), new TagAttributeInfo("page", true, url + "syntaxref2020.html#10930#17145", true)}), new TagInfo("param", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2023.html#11538#11583", null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2023.html#11538#11583", false), new TagAttributeInfo("value", true, url + "syntaxref2023.html#11538#11583", true)}), new TagInfo("params", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2023.html#11538#11583", null, null, new TagAttributeInfo[] {}), 803 new TagInfo("plugin", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2023.html#1004158#19029", null, null, new TagAttributeInfo[] { new TagAttributeInfo("align", false, url + "syntaxref2023.html#11516#11518", false), new TagAttributeInfo("archive", false, url + "syntaxref2023.html#11553#11516", false), new TagAttributeInfo("code", true, url + "syntaxref2023.html#11514#11515", false), new TagAttributeInfo("codebase", true, url + "syntaxref2023.html#11515#11547", false), new TagAttributeInfo("height", false, url + "syntaxref2023.html#11518#11568", false), new TagAttributeInfo("hspace", false, url + "syntaxref2023.html#11568#11520", false), new TagAttributeInfo("iepluginurl", false, url + "syntaxref2023.html#11526#11538", false), new TagAttributeInfo("jreversion", false, url + "syntaxref2023.html#11520#11525", false), new TagAttributeInfo("name", false, url + "syntaxref2023.html#11547#11553", false), new TagAttributeInfo("nspluginurl", false,url + "syntaxref2023.html#11525#11526", false), new TagAttributeInfo("type", true, url + "syntaxref2023.html#10935#11514", false), new TagAttributeInfo("vspace", false, url + "syntaxref2023.html#11568#11520", false), new TagAttributeInfo("width", false, url + "syntaxref2023.html#11518#11568", false)}), new TagInfo("setProperty", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2025.html#8856#9329", null, null, new TagAttributeInfo[] { new TagAttributeInfo("name", true, url + "syntaxref2025.html#17612#1001786", true), new TagAttributeInfo("param", false, url + "syntaxref2025.html#9919#20483", false), new TagAttributeInfo("property", false, url + "syntaxref2025.html#1001786#9329", false), new TagAttributeInfo("value", false, url + "syntaxref2025.html#20483#9329", true)}), new TagInfo("text", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2026.html", 823 null, null, new TagAttributeInfo[]{}), 824 new TagInfo("useBean", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2027.html#8865#9359", null, null, new TagAttributeInfo[] { new TagAttributeInfo("beanName", false, url + "syntaxref2027.html#15804#9359", false), new TagAttributeInfo("class", false, url + "syntaxref2027.html#10968#19433", false), new TagAttributeInfo("id", true, url + "syntaxref2027.html#10964#10966", false), new TagAttributeInfo("scope", true, url + "syntaxref2027.html#10966#10968", false), new TagAttributeInfo("type", false, url + "syntaxref2027.html#19433#18019", false)}) }; 831 832 standardTagTagDatas = new TagInfo[standardJspTagDatas.length + 2 ]; 833 standardTagTagDatas[0] = standardJspTagDatas[0]; standardTagTagDatas[1] = standardJspTagDatas[1]; standardTagTagDatas[2] = new TagInfo("doBody", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2017.html", null, null, new TagAttributeInfo[] { new TagAttributeInfo("scope", false, url + "syntaxref2017.html#1006246#syntaxref20.html", false), new TagAttributeInfo("var", false, url + "syntaxref2017.html#1006234#1006240", false), new TagAttributeInfo("varReader", false, url + "syntaxref2017.html#1006240#1006246", false)}); 840 standardTagTagDatas[3] = standardJspTagDatas[2]; standardTagTagDatas[4] = standardJspTagDatas[3]; standardTagTagDatas[5] = standardJspTagDatas[4]; standardTagTagDatas[6] = standardJspTagDatas[5]; standardTagTagDatas[7] = standardJspTagDatas[6]; standardTagTagDatas[8] = standardJspTagDatas[7]; standardTagTagDatas[9] = new TagInfo("invoke", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2021.html#8837#1003634", null, null, new TagAttributeInfo[] { new TagAttributeInfo("fragment", true, url + "syntaxref2021.html#1007359#1007361", false), new TagAttributeInfo("scope", false, url + "syntaxref2021.html#1007373#1003634", false), new TagAttributeInfo("var", false, url + "syntaxref2021.html#1007361#1007367", false), new TagAttributeInfo("varReader", false, url + "syntaxref2021.html#1007367#1007373", false)}); 852 standardTagTagDatas[10] = standardJspTagDatas[8]; standardTagTagDatas[11] = standardJspTagDatas[9]; standardTagTagDatas[12] = standardJspTagDatas[10]; standardTagTagDatas[13] = standardJspTagDatas[11]; standardTagTagDatas[14] = standardJspTagDatas[12]; standardTagTagDatas[15] = standardJspTagDatas[13]; } 859 860 861 if (directiveJspData == null){ 862 directiveJspData = new TagInfo[] { 863 new TagInfo("include", null, TagInfo.BODY_CONTENT_EMPTY, url+"syntaxref209.html#1003408#8975", null, null, new TagAttributeInfo[] { new TagAttributeInfo("file", true, url + "syntaxref209.html#16836#10636", false)}), new TagInfo("page", null, TagInfo.BODY_CONTENT_EMPTY, url+"syntaxref2010.html", null, null, new TagAttributeInfo[] { new TagAttributeInfo("autoFlush", false, url+"syntaxref2010.html#15673#15675", false), new TagAttributeInfo("buffer", false, url+"syntaxref2010.html#15671#15673", false), new TagAttributeInfo("contentType", false, url+"syntaxref2010.html#15683#1001361", false), new TagAttributeInfo("errorPage", false, url+"syntaxref2010.html#15679#15681", false), new TagAttributeInfo("extends", false, url+"syntaxref2010.html#15665#16862", false), new TagAttributeInfo("import", false, url+"syntaxref2010.html#16862#15669", false), new TagAttributeInfo("info", false, url+"syntaxref2010.html#15677#15679", false), new TagAttributeInfo("isELIgnored", false, url+"syntaxref2010.html#1011216#18865", false), new TagAttributeInfo("isErrorPage", false, url+"syntaxref2010.html#15681#15683", false), new TagAttributeInfo("isThreadSafe", false, url+"syntaxref2010.html#15675#15677", false), new TagAttributeInfo("language", false, url+"syntaxref2010.html#15663#15665", false), new TagAttributeInfo("pageEncoding", false, url+"syntaxref2010.html#1001361#1011216", false), new TagAttributeInfo("session", false, url+"syntaxref2010.html#15669#15671", false)}), new TagInfo("taglib", null, TagInfo.BODY_CONTENT_EMPTY, url+"syntaxref2012.html#1003416#1002041", null, null, new TagAttributeInfo[] { new TagAttributeInfo("prefix", true, url+"syntaxref2012.html#1011290#1002041", false), new TagAttributeInfo("uri", false, url+"syntaxref2012.html#10721#1011294", false), new TagAttributeInfo("tagdir", false, url + "syntaxref2012.html#1011294#1011290", false)}) }; 884 } 885 886 887 if (directiveTagFileData == null){ 888 889 directiveTagFileData = new TagInfo[]{ 890 new TagInfo("attribute", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref208.html", null, null, new TagAttributeInfo[] { new TagAttributeInfo("description", false, url + "syntaxref208.html#1004672", false), new TagAttributeInfo("fragment", false, url + "syntaxref208.html#1004657#1004666", false), new TagAttributeInfo("name", true, url + "syntaxref208.html#1004648#1004655", false), new TagAttributeInfo("required", false, url + "syntaxref208.html#1004655#1004657", false), new TagAttributeInfo("rtexprvalue", false, url + "syntaxref208.html#1004666#1004669", false), new TagAttributeInfo("type", false, url + "syntaxref208.html#1004669#1004672", false)}), directiveJspData[0], 898 new TagInfo("tag", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2011.html", null, null, new TagAttributeInfo[] { new TagAttributeInfo("body-content", false, url + "syntaxref2011.html#1005164#005172", false), new TagAttributeInfo("description", false, url + "syntaxref2011.html#1005196#1005198", false), new TagAttributeInfo("display-name", false, url + "syntaxref2011.html#1005161#1005164", false), new TagAttributeInfo("dynamic-attributes", false, url + "syntaxref2011.html#005172#1005190", false), new TagAttributeInfo("example", false, url + "syntaxref2011.html#1005198#1005201", false), new TagAttributeInfo("import", false, url + "syntaxref2011.html#1005203#1005209", false), new TagAttributeInfo("isELIgnored", false, url + "syntaxref2011.html#1005214#1005291#1005291", false), new TagAttributeInfo("large-icon", false, url + "syntaxref2011.html#1005193#1005196", false), new TagAttributeInfo("language", false, url + "syntaxref2011.html#1005201#1005203", false), new TagAttributeInfo("pageEncoding", false, url + "syntaxref2011.html#1005209#1005214", false), new TagAttributeInfo("small-icon", false, url + "syntaxref2011.html#1005190#1005193", false)}), directiveJspData[2], 912 new TagInfo("variable", null, TagInfo.BODY_CONTENT_EMPTY, url + "syntaxref2013.html#15694#1003563", null, null, new TagAttributeInfo[] { new TagAttributeInfo("alias", false, url + "syntaxref2013.html#1005914#1005956", false), new TagAttributeInfo("declare", false, url + "syntaxref2013.html#1006001#1006019", false), new TagAttributeInfo("description", false, url + "syntaxref2013.html#1005991#1003563", false), new TagAttributeInfo("name-given", false, url + "syntaxref2013.html#1003561#1005914", false), new TagAttributeInfo("scope", false, url + "syntaxref2013.html#1006019#1005991", false), new TagAttributeInfo("variable-class", false, url + "syntaxref2013.html#1005956#1006001", false)}) }; 920 } 921 922 if (xmlJspTagDatas == null) { 923 TagInfo[] commonXMLTagDatas; 924 commonXMLTagDatas = new TagInfo[]{ 925 new TagInfo("declaration", null, TagInfo.BODY_CONTENT_JSP, url+"syntaxref204.html#10983#10991", null, null, new TagAttributeInfo[] {}), 927 new TagInfo("output", null, TagInfo.BODY_CONTENT_JSP, url + "syntaxref2022.html#1004130#1007521", null, null, new TagAttributeInfo[] {new TagAttributeInfo("doctype-public", false, "url + syntaxref2022.html#1007534#1007521", false), new TagAttributeInfo("doctype-root-element", false, "url + syntaxref2022.html#1007528#1007532", false), new TagAttributeInfo("doctype-system", false, url + "syntaxref2022.html#1007532#1007534", false), new TagAttributeInfo("omit-xml-declaration", false, url + "syntaxref2022.html#1007525#1007528" , false)}), new TagInfo("scriptlet", null, TagInfo.BODY_CONTENT_JSP, url+"syntaxref206.html#10996#11007", null, null, new TagAttributeInfo[] {}), 934 new TagInfo("root", null, TagInfo.BODY_CONTENT_JSP, url+"syntaxref2024.html#1003283#1003311", null, null, new TagAttributeInfo[] {new TagAttributeInfo("version", false, url+"syntaxref2024.html#1003299#1003301", false), 936 new TagAttributeInfo("xmlns:jsp", false, url+"syntaxref2024.html#1003297#1003299", false), 937 new TagAttributeInfo("xmlns:x", false, url+"syntaxref2024.html#1003301#1003311", false)}) 938 }; 939 940 xmlJspTagDatas = new TagInfo[] { 941 new TagInfo("directive.page", null, TagInfo.BODY_CONTENT_EMPTY, directiveJspData[1].getInfoString(), null, null, directiveJspData[1].getAttributes()), 943 new TagInfo("directive.include", null, TagInfo.BODY_CONTENT_EMPTY, directiveJspData[1].getInfoString(), null, null, directiveJspData[0].getAttributes()), 945 }; 946 947 ArrayList list = new ArrayList(); 948 for (int i = 0; i < xmlJspTagDatas.length; i++){ 949 list.add(xmlJspTagDatas[i]); 950 } 951 for (int i = 0; i < standardJspTagDatas.length; i++){ 952 list.add(standardJspTagDatas[i]); 953 } 954 for (int i = 0; i < commonXMLTagDatas.length; i++){ 955 list.add(commonXMLTagDatas[i]); 956 } 957 958 Collections.sort(list, TAG_NAME_COMPARATOR); 960 961 xmlJspTagDatas = new TagInfo[list.size()]; 962 for (int i = 0; i < list.size(); i++) 963 xmlJspTagDatas[i] = (TagInfo)list.get(i); 964 965 xmlTagFileTagDatas = new TagInfo[] { 966 new TagInfo("directive.tag", null, TagInfo.BODY_CONTENT_EMPTY, directiveTagFileData[2].getInfoString(), null, null, directiveTagFileData[2].getAttributes()), 968 new TagInfo("directive.attribute", null, TagInfo.BODY_CONTENT_EMPTY, directiveTagFileData[0].getInfoString(), null, null, directiveTagFileData[0].getAttributes()), 970 new TagInfo("directive.variable", null, TagInfo.BODY_CONTENT_EMPTY, directiveTagFileData[4].getInfoString(), null, null, directiveTagFileData[4].getAttributes()), 972 new TagInfo("directive.include", null, TagInfo.BODY_CONTENT_EMPTY, directiveJspData[1].getInfoString(), null, null, directiveJspData[0].getAttributes()) 974 }; 975 976 list = new ArrayList(); 977 for (int i = 0; i < xmlTagFileTagDatas.length; i++){ 978 list.add(xmlTagFileTagDatas[i]); 979 } 980 for (int i = 0; i < standardTagTagDatas.length; i++){ 981 list.add(standardTagTagDatas[i]); 982 } 983 for (int i = 0; i < commonXMLTagDatas.length; i++){ 984 list.add(commonXMLTagDatas[i]); 985 } 986 987 Collections.sort(list, TAG_NAME_COMPARATOR); 988 xmlTagFileTagDatas = new TagInfo[list.size()]; 989 for (int i = 0; i < list.size(); i++) 990 xmlTagFileTagDatas[i] = (TagInfo)list.get(i); 991 992 } 993 994 995 } 996 997 private TagInfo[] getTagInfos(){ 998 TagInfo[] rValue; 999 if ("text/x-jsp".equals(fobj.getMIMEType()) || "text/x-tag".equals(fobj.getMIMEType())){ 1000 if ( isXmlSyntax()){ 1001 if (NbEditorUtilities.getMimeType(getDocument()).equals(JspUtils.TAG_MIME_TYPE)) 1002 rValue = xmlTagFileTagDatas; 1003 else 1004 rValue = xmlJspTagDatas; 1005 } else 1006 if (NbEditorUtilities.getMimeType(getDocument()).equals(JspUtils.TAG_MIME_TYPE)) 1007 rValue = standardTagTagDatas; 1008 else 1009 rValue = standardJspTagDatas; 1010 } else 1011 rValue = new TagInfo[0]; 1012 return rValue; 1013 } 1014 1015 public String toString() { 1016 return printJspCompletionInfo(); 1017 } 1018 1019 1020 private String printJspCompletionInfo() { 1021 StringBuffer output = new StringBuffer (); 1022 1023 output.append("TAGS\n"); List tagPrefixes = getTagPrefixes(""); for (int i = 0; i < tagPrefixes.size(); i++) { 1026 String prefix = (String )tagPrefixes.get(i); 1027 output.append(" " + prefix + "\n"); List tags = getTags(prefix, ""); for (int j = 0; j < tags.size(); j++) { 1030 if (tags.get(j) instanceof TagInfo){ 1031 TagInfo ti = (TagInfo) tags.get(j); 1032 output.append(" " + ti.getTagName() + "\n"); 1033 TagAttributeInfo[] attributes = ti.getAttributes(); 1034 for (int k = 0; k < attributes.length; k++) { 1035 output.append(" " + attributes[k].getName() + "\n"); } 1037 } else { 1038 String tagName = (String )tags.get(j); 1039 output.append(" " + tagName + "\n"); List attributes = getTagAttributes(prefix, tagName, ""); for (int k = 0; k < attributes.size(); k++) { 1042 String attribute = (String )attributes.get(k); 1043 output.append(" " + attribute + "\n"); } 1045 } 1046 } 1047 1048 } 1049 1050 output.append("DIRECTIVES\n"); List directives = getDirectives(""); for (int i = 0; i < directives.size(); i++) { 1053 if (directives.get(i) instanceof TagInfo){ 1054 TagInfo ti = (TagInfo) directives.get(i); 1055 output.append(" " + ti.getTagName() + "\n"); 1056 TagAttributeInfo[] attributes = ti.getAttributes(); 1057 for (int k = 0; k < attributes.length; k++) { 1058 output.append(" " + attributes[k].getName() + "\n"); } 1060 } else { 1061 String directive = (String )directives.get(i); 1062 output.append(" " + directive + "\n"); List attributes = getDirectiveAttributes(directive, ""); for (int k = 0; k < attributes.size(); k++) { 1065 String attribute = (String )attributes.get(k); 1066 output.append(" " + attribute + "\n"); } 1068 } 1069 } 1070 1071 return output.toString(); 1072 } 1073 1074 1078 @Deprecated () 1079 public TokenItem getItemAtOrBefore(int offset) throws BadLocationException { 1080 TokenItem backItem = null; 1081 int chainLength = 100; 1082 while (backItem == null) { 1083 if (offset < getDocument().getLength()) { 1084 backItem = getTokenChain( offset, 1085 Math.min(offset + chainLength, getDocument().getLength()) ); 1086 } else { 1087 backItem = getTokenChain(Math.max(offset-50, 0), offset); 1089 } 1090 1091 if (chainLength++ > 1000) 1092 break; 1093 } 1094 if (backItem == null) 1095 return null; 1096 1097 TokenItem item; 1101 while (true) { 1102 item = backItem.getNext(); 1103 if (item == null) { 1105 item = backItem; 1106 break; 1108 } 1109 if (item.getOffset() > offset) { 1110 item = backItem; 1111 break; 1113 } 1114 backItem = item; 1115 } 1117 1118 TokenItem adjustedItem = (item.getOffset() == offset) ? 1120 item.getPrevious() : item; 1121 1123 TokenID id = (adjustedItem == null) ? 1124 item.getTokenID() : adjustedItem.getTokenID(); 1125 return adjustedItem; 1127 } 1128 1129 1134 public SyntaxElement getElementChain( int offset ) throws BadLocationException { 1135 TokenItem item = getItemAtOrBefore(offset); 1136 if (item == null) 1137 return null; 1138 TokenID id = item.getTokenID(); 1139 1140 if ( 1141 id == JspTagTokenContext.ERROR || 1142 id == JspTagTokenContext.TEXT || 1143 id == JspMultiTokenContext.ERROR || 1144 1145 id == JspDirectiveTokenContext.ERROR || 1146 id == JspDirectiveTokenContext.TEXT 1147 ) { 1148 return null; 1150 } 1151 1152 if(id == JspTagTokenContext.COMMENT || id == JspDirectiveTokenContext.COMMENT) { 1154 return getCommentChain(item, offset); 1155 } 1156 1157 if(item.getTokenContextPath().contains(ELTokenContext.contextPath)) { 1159 return getELChain(item, offset); 1160 } 1161 1162 if (id == JspTagTokenContext.SYMBOL2 || id == JspDirectiveTokenContext.SYMBOL2) { 1163 if (isScriptStartToken(item)) { 1164 return getScriptingChain(item, offset); 1165 } 1166 1167 if ((getTokenEnd(item) == offset) && isScriptEndToken(item)) { 1168 TokenItem nextItem = item.getNext(); 1169 if (!isTagDirToken(item)) 1170 return getContentChain(item, offset); 1171 } 1172 return null; 1173 } 1174 1175 if (id == JspTagTokenContext.TAG || 1176 id == JspTagTokenContext.SYMBOL || 1177 id == JspTagTokenContext.ATTRIBUTE || 1178 id == JspTagTokenContext.ATTR_VALUE || 1179 id == JspTagTokenContext.WHITESPACE || 1180 id == JspTagTokenContext.EOL || 1181 id == JspDirectiveTokenContext.TAG || 1182 id == JspDirectiveTokenContext.SYMBOL || 1183 id == JspDirectiveTokenContext.ATTRIBUTE || 1184 id == JspDirectiveTokenContext.ATTR_VALUE || 1185 id == JspDirectiveTokenContext.WHITESPACE || 1186 id == JspDirectiveTokenContext.EOL) { 1187 TokenItem elementStart = item; 1191 do { 1192 if (elementStart == null) 1194 return null; 1195 if (elementStart.getTokenID() == JspTagTokenContext.SYMBOL 1196 || elementStart.getTokenID() == JspDirectiveTokenContext.SYMBOL) { 1197 if (elementStart.getImage().equals("<")) { return getTagOrDirectiveChain(true, elementStart, offset); 1199 } 1200 if (elementStart.getImage().equals("</")) { return getEndTagChain(elementStart, offset); 1202 } 1203 if (elementStart.getImage().equals("<%@")) { return getTagOrDirectiveChain(false, elementStart, offset); 1205 } 1206 } 1207 if(elementStart.getTokenID() == JspTagTokenContext.ERROR 1208 || elementStart.getTokenID() == JspDirectiveTokenContext.ERROR) { 1209 return null; 1211 } 1212 if (elementStart.getTokenID() == JspTagTokenContext.COMMENT 1213 || elementStart.getTokenID() == JspDirectiveTokenContext.COMMENT) { 1214 return null; 1215 } 1216 elementStart = elementStart.getPrevious(); 1217 } 1218 while (true); 1219 } 1220 1221 if (isScriptingOrContentToken(item)) { 1226 TokenItem elementStart = item; 1227 do { 1228 if (elementStart.getPrevious() == null) { 1229 return getContentChain(elementStart, offset); 1232 } 1233 elementStart = elementStart.getPrevious(); if (!isScriptingOrContentToken(elementStart) 1235 || elementStart.getTokenID() == JspTagTokenContext.COMMENT 1236 || elementStart.getTokenID() == JspDirectiveTokenContext.COMMENT 1237 || elementStart.getTokenContextPath().contains(ELTokenContext.contextPath)) { 1238 if (isScriptStartToken(elementStart)) { 1240 return getScriptingChain(elementStart.getNext(), offset); 1241 } else { 1242 return getContentChain(elementStart.getNext(), offset); 1243 } 1244 } 1245 } 1246 while (true); 1247 } 1248 1249 return null; 1251 } 1252 1253 1255 private boolean isScriptStartToken(TokenItem item) { 1256 if (item == null) 1257 return false; 1258 TokenID id = item.getTokenID(); 1259 if (id == JspTagTokenContext.SYMBOL2 1260 || id == JspDirectiveTokenContext.SYMBOL2) { 1261 String image = item.getImage(); 1262 if (image.equals("<%") || image.equals("<%=") || image.equals("<%!")) return true; 1266 } 1267 return false; 1268 } 1269 1270 1272 private boolean isScriptEndToken(TokenItem item) { 1273 if (item == null) 1274 return false; 1275 TokenID id = item.getTokenID(); 1276 if (id == JspTagTokenContext.SYMBOL2 1277 || id == JspDirectiveTokenContext.SYMBOL2) { 1278 String image = item.getImage(); 1279 if (image.equals("%>")) return true; 1281 } 1282 return false; 1283 } 1284 1285 1287 private boolean isInnerTagDirToken(TokenItem item) { 1288 if (!isTagDirToken(item)) 1289 return false; 1290 TokenID id = item.getTokenID(); 1291 if (id == JspTagTokenContext.SYMBOL 1292 || id == JspDirectiveTokenContext.SYMBOL) { 1293 String image = item.getImage(); 1294 if (image.equals("<") || image.equals("</") || image.equals("<%@") || image.equals("%>") || image.equals(">") || image.equals("/>")) return false; 1301 } 1302 return true; 1303 } 1304 1305 1307 private boolean isTagDirToken(TokenItem item) { 1308 if (item == null) 1309 return false; 1310 TokenID id = item.getTokenID(); 1311 if (id == null) 1312 return false; 1313 if ((id != JspTagTokenContext.TEXT) && 1314 (id != JspTagTokenContext.ERROR) && 1315 (id != JspTagTokenContext.TAG) && 1316 (id != JspTagTokenContext.SYMBOL) && 1317 (id != JspTagTokenContext.ATTRIBUTE) && 1318 (id != JspTagTokenContext.ATTR_VALUE) && 1319 (id != JspTagTokenContext.WHITESPACE) && 1320 (id != JspTagTokenContext.EOL) && 1321 (id != JspDirectiveTokenContext.TEXT) && 1322 (id != JspDirectiveTokenContext.ERROR) && 1323 (id != JspDirectiveTokenContext.TAG) && 1324 (id != JspDirectiveTokenContext.SYMBOL) && 1325 (id != JspDirectiveTokenContext.ATTRIBUTE) && 1326 (id != JspDirectiveTokenContext.ATTR_VALUE) && 1327 (id != JspDirectiveTokenContext.WHITESPACE) && 1328 (id != JspDirectiveTokenContext.EOL )) { 1329 return false; 1330 } 1331 return true; 1333 } 1334 1335 1337 private boolean isScriptingOrContentToken(TokenItem item) { 1338 if (item == null) 1339 return true; 1340 TokenID id = item.getTokenID(); 1341 if (id == null) 1342 return true; 1343 if ((id == JspTagTokenContext.TEXT) || 1344 (id == JspTagTokenContext.ERROR) || 1345 (id == JspTagTokenContext.TAG) || 1346 (id == JspTagTokenContext.SYMBOL) || 1347 (id == JspTagTokenContext.ATTRIBUTE) || 1348 (id == JspTagTokenContext.ATTR_VALUE) || 1349 (id == JspTagTokenContext.SYMBOL2) || 1350 (id == JspTagTokenContext.EOL) || 1351 (id == JspDirectiveTokenContext.TEXT) || 1352 (id == JspDirectiveTokenContext.ERROR) || 1353 (id == JspDirectiveTokenContext.TAG) || 1354 (id == JspDirectiveTokenContext.SYMBOL) || 1355 (id == JspDirectiveTokenContext.ATTRIBUTE) || 1356 (id == JspDirectiveTokenContext.ATTR_VALUE) || 1357 (id == JspDirectiveTokenContext.SYMBOL2) || 1358 (id == JspDirectiveTokenContext.EOL) || 1359 (id == JspMultiTokenContext.ERROR)) 1360 return false; 1361 return true; 1362 } 1363 1364 public boolean isValueBeginning(String text) { 1365 if (text.trim().endsWith("\"\"")) return false; 1367 for (int i = 0; i < text.length(); i++) { 1368 char c = text.charAt(i); 1369 if ((c != ' ') && 1370 (c != '=') && 1371 (c != '"')) 1372 return false; 1373 } 1374 return true; 1375 } 1376 1377 1379 private SyntaxElement getCommentChain(TokenItem token, int offset) { 1380 TokenItem start = null; 1383 TokenItem search = token; 1384 do { 1385 if(search != null && search.getImage().startsWith("<%--")) { start = search; 1387 break; 1388 } 1389 search = search.getPrevious(); 1390 } while(search != null); 1391 1392 if(start == null) { 1393 return null; 1395 } 1396 1397 TokenItem end = null; 1399 TokenItem prevNonNullToken = token; 1400 search = token; 1401 do { 1402 if(search != null && search.getImage().endsWith("--%>")) { end = search; 1404 break; 1405 } 1406 prevNonNullToken = search; 1407 search = search.getNext(); 1408 } while(search != null); 1409 if(end == null) { 1410 end = prevNonNullToken; } 1413 1414 return new SyntaxElement.Comment(this, start.getOffset(), getTokenEnd(end)); 1415 } 1416 1417 private SyntaxElement getELChain(TokenItem token, int offset) { 1418 TokenItem scan = token; 1421 TokenItem start = null; 1422 do { 1423 start = scan; 1424 scan = scan.getPrevious(); 1425 } while(scan != null && scan.getTokenContextPath().contains(ELTokenContext.contextPath)); 1426 1427 TokenItem end = null; 1429 scan = token; 1430 do { 1431 end = scan; 1432 scan = scan.getNext(); 1433 } while(scan != null && scan.getTokenContextPath().contains(ELTokenContext.contextPath)); 1434 1435 return new SyntaxElement.ExpressionLanguage(this, start.getOffset(), getTokenEnd(end)); 1436 } 1437 1438 1439 1440 private SyntaxElement getTagOrDirectiveChain(boolean tag, TokenItem firstToken, int offset) { 1441 TokenItem item = firstToken.getNext(); 1444 String name = getWholeWord(item, JspTagTokenContext.TAG); 1445 while ((item != null) && (item.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID || 1446 item.getTokenID().getNumericID() == JspTagTokenContext.WHITESPACE_ID )) 1447 item = item.getNext(); 1448 TreeMap attributes = new TreeMap(); 1449 while (isInnerTagDirToken(item)) { 1450 if (item.getTokenID().getNumericID() == JspTagTokenContext.ATTRIBUTE_ID) { 1452 String attributeName = getWholeWord(item, JspTagTokenContext.ATTRIBUTE); 1453 while ((item != null) && (item.getTokenID().getNumericID() == JspTagTokenContext.ATTRIBUTE_ID)) 1455 item = item.getNext(); 1456 while ((item != null) && 1458 (item.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL_ID) && 1459 (isValueBeginning(item.getImage()))) 1460 item = item.getNext(); 1461 StringBuffer value = new StringBuffer (); 1462 while ((item != null) 1463 && ((item.getTokenID().getNumericID() == JspTagTokenContext.ATTR_VALUE_ID) 1464 || (item.getTokenID().getNumericID() == JspTagTokenContext.EOL_ID))) { 1465 value.append(item.getImage()); 1466 item = item.getNext(); 1467 if ((item != null) && (item.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL2_ID)) { 1469 while (!isScriptEndToken(item)) { 1471 if (item == null) 1472 break; 1473 else { 1474 value.append(item.getImage()); 1475 item = item.getNext(); 1476 } 1477 } 1478 if (item != null) { 1480 value.append(item.getImage()); 1481 item = item.getNext(); 1482 } 1483 } 1484 1485 if((item != null) && (item.getTokenContextPath().contains(ELTokenContext.contextPath))) { 1487 while(item.getTokenContextPath().contains(ELTokenContext.contextPath)) { 1489 item = item.getNext(); 1490 if(item == null) break; 1491 value.append(item.getImage()); 1492 } 1493 } 1494 1495 } 1496 String vString = value.toString(); 1497 if (vString.startsWith("\"")) vString = vString.substring(1); 1500 if (vString.endsWith("\"")) vString = vString.substring(0, vString.length() - 1); 1502 attributes.put(attributeName, vString); 1503 continue; 1504 } 1505 if (item.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL2_ID) { 1506 while (!isScriptEndToken(item)) { 1508 if (item == null) 1509 break; 1510 else 1511 item = item.getNext(); 1512 } 1513 if (item != null) 1515 item = item.getNext(); 1516 continue; 1517 } 1518 item = item.getNext(); 1520 } 1521 if (tag) { 1522 boolean endslash= false; 1523 if (item != null) 1524 endslash = (item.getImage().equals("/>"))? true: false; 1526 return new SyntaxElement.Tag(this, firstToken.getOffset(), 1527 (item != null)? getTokenEnd(item): getDocument().getLength(), 1528 name, attributes, endslash); 1529 } else { 1530 return new SyntaxElement.Directive(this, firstToken.getOffset(), 1531 (item != null)? getTokenEnd(item): getDocument().getLength(), 1532 name, attributes); 1533 } 1534 } 1535 1536 private SyntaxElement getEndTagChain(TokenItem firstToken, int offset) { 1537 TokenItem item = firstToken.getNext(); 1538 String name = getWholeWord(item, JspTagTokenContext.TAG); 1539 while ((item != null) && (item.getTokenID() == JspTagTokenContext.TAG)) 1540 item = item.getNext(); 1541 while (isInnerTagDirToken(item)) { 1542 item = item.getNext(); 1543 } 1544 return new SyntaxElement.EndTag(this, firstToken.getOffset(), 1545 getTokenEnd(item), name); 1546 } 1547 1548 private String getWholeWord(TokenItem firstToken, TokenID requestedTokenID) { 1549 StringBuffer sb = new StringBuffer (); 1550 while ((firstToken != null) && (firstToken.getTokenID().getNumericID() == requestedTokenID.getNumericID())) { 1551 sb.append(firstToken.getImage()); 1552 firstToken = firstToken.getNext(); 1553 } 1554 return sb.toString().trim(); 1555 } 1556 1557 1560 private SyntaxElement getScriptingChain(TokenItem firstToken, int offset) { 1561 if (firstToken == null) { 1562 return new SyntaxElement.ScriptingL(this, 1563 getDocument().getLength(), getDocument().getLength()); 1564 } 1565 TokenItem item = firstToken; 1566 do { 1567 TokenItem nextItem = item.getNext(); 1568 if (nextItem == null) { 1569 return new SyntaxElement.ScriptingL(this, 1570 firstToken.getOffset(), getDocument().getLength()); 1571 } 1572 if (!isScriptingOrContentToken(nextItem)) 1573 return new SyntaxElement.ScriptingL(this, 1574 firstToken.getOffset(), getTokenEnd(nextItem)); 1575 item = nextItem; 1576 } 1577 while (true); 1578 } 1579 1580 1583 private SyntaxElement getContentChain(TokenItem firstToken, int offset) { 1584 if (firstToken == null) { 1585 return new SyntaxElement.ContentL(this, 1586 getDocument().getLength(), getDocument().getLength()); 1587 } 1588 TokenItem item = firstToken; 1589 do { 1590 TokenItem nextItem = item.getNext(); 1591 if (nextItem == null) { 1592 return new SyntaxElement.ContentL(this, 1593 firstToken.getOffset(), getDocument().getLength()); 1594 } 1595 if (!isScriptingOrContentToken(nextItem) 1596 || nextItem.getTokenID() == JspTagTokenContext.COMMENT 1597 || nextItem.getTokenID() == JspDirectiveTokenContext.COMMENT 1598 || nextItem.getTokenContextPath().contains(ELTokenContext.contextPath)) 1599 return new SyntaxElement.ContentL(this, 1600 firstToken.getOffset(), getTokenEnd(item)); 1601 item = nextItem; 1602 } 1603 while (true); 1604 } 1605 1606 1610 SyntaxElement getPreviousElement( int offset ) throws BadLocationException { 1611 if (offset == 0) 1612 return null; 1613 SyntaxElement elem = null; 1614 offset--; 1615 do { 1616 elem = getElementChain( offset); 1617 if (elem == null){ 1618 TokenItem ti = getItemAtOrBefore(offset); 1619 if (ti == null) 1620 return null; 1621 offset = ti.getOffset() -1 ; 1622 } 1623 } while (elem == null && offset >= 0); 1624 return elem; 1625 } 1626 1627 SyntaxElement getNextElement(int offset) throws BadLocationException { 1628 int doclen = getDocument().getLength(); 1629 if(offset >= doclen) 1630 return null; 1631 1632 SyntaxElement elem = null; 1633 offset++; 1634 do { 1635 elem = getElementChain(offset); 1636 if(elem == null) { 1637 TokenItem ti = getItemAtOrBefore(offset); 1638 if(ti == null) 1639 return null; 1640 offset = getTokenEnd(ti) + 1; 1641 } 1642 } while(elem == null && offset < doclen); 1643 1644 return elem; 1645 } 1646 1647 public List getPossibleEndTags(int offset, String pattern) throws BadLocationException { 1648 return getPossibleEndTags(offset, pattern, false); } 1650 1651 public List getPossibleEndTags(int offset, String pattern, boolean firstOnly) throws BadLocationException { 1652 SyntaxElement elem = getElementChain( offset ); 1653 Stack stack = new Stack(); 1654 List result = new ArrayList(); 1655 Set found = new HashSet(); 1656 1657 if( elem != null ) { 1658 elem = elem.getPrevious(); } else { if( offset > 0 ) { 1661 elem = getElementChain( offset-1 ); 1662 } else { return result; 1664 } 1665 } 1666 1667 1668 for( ; elem != null; elem = elem.getPrevious() ) { 1669 1670 if( elem instanceof SyntaxElement.EndTag ) { 1671 stack.push( ((SyntaxElement.EndTag)elem).getName() ); 1672 } else if( elem instanceof SyntaxElement.Tag ) { 1673 SyntaxElement.Tag tag = (SyntaxElement.Tag)elem; 1674 1675 if (tag.isClosed()) 1676 continue; 1677 1678 String image = tag.getName(); 1679 String prefix = image.substring(0, image.indexOf(':')); 1680 String name = image.substring(image.indexOf(':')+1); 1681 TagInfo ti = null; 1682 1683 TagLibraryInfo tli = getTagLibrary(prefix); 1684 if (tli != null) { 1685 ti = tli.getTag(name); 1686 } 1687 1688 if (STANDARD_JSP_PREFIX.equals(prefix)) { 1689 initCompletionData(); 1690 TagInfo[] stanTagDatas = getTagInfos(); 1691 for (int i=0; i<stanTagDatas.length; i++) { 1692 if (stanTagDatas[i].getTagName().equals(name)) { 1693 ti = stanTagDatas[i]; 1694 break; 1695 } 1696 } 1697 } 1698 1699 if (ti == null) continue; 1701 if( stack.empty() ) { if( image.startsWith( pattern ) && !found.contains( image ) ) { found.add( image ); 1704 1705 if (ti.getBodyContent().equalsIgnoreCase(TagInfo.BODY_CONTENT_EMPTY)) 1706 continue; 1707 1708 result.add( new JspCompletionItem.Tag( "/"+image, ti ) ); 1710 if(firstOnly) break; } 1712 } else { if( stack.peek().equals( image ) ) { stack.pop(); 1716 } } 1718 1719 if (ti.getBodyContent().equalsIgnoreCase(TagInfo.BODY_CONTENT_EMPTY)) 1721 continue; 1722 1723 1725 } 1726 } 1727 1728 return result; 1729 } 1730 1731 public List getAutocompletedEndTag(int offset) { 1732 List l = new ArrayList(); 1733 try { 1734 SyntaxElement elem = getElementChain( offset - 1); 1735 if(elem != null && elem instanceof SyntaxElement.Tag) { 1736 String tagName = ((SyntaxElement.Tag)elem).getName(); 1737 HTMLCompletionQuery.ResultItem eti = new HTMLCompletionQuery.AutocompleteEndTagItem(tagName, offset, false); 1738 l.add(eti); 1739 } 1740 }catch(BadLocationException e) { 1741 } 1743 return l; 1744 } 1745 1746 public FileObject getFileObject() { 1747 return fobj; 1748 } 1749 1750 1757 protected ExtSyntaxSupport.BracketFinder getMatchingBracketFinder(char bracketChar) { 1758 if (useCustomBracketFinder) { 1759 JspSyntaxSupport.BracketFinder bf = new JspSyntaxSupport.BracketFinder(bracketChar); 1760 return bf.isValid()? bf: null; 1761 } else{ 1762 return super.getMatchingBracketFinder(bracketChar); 1763 } 1764 } 1765 1766 1776 public int[] findMatchingBlock(int offset, boolean simpleSearch) 1777 throws BadLocationException { 1778 1779 int [] r_value = null; 1780 1781 TokenItem token = getItemAtOrBefore((offset<getDocument().getLength())?offset+1:offset); 1782 if (token != null){ 1783 if (token.getTokenContextPath().contains(HTMLTokenContext.contextPath)){ 1784 r_value = getContentLanguageSyntaxSupport().findMatchingBlock(offset, simpleSearch); 1785 } else { 1786 if (token.getTokenID() == JspTagTokenContext.COMMENT) { 1788 return findMatchingJspComment(token, offset); 1789 } 1790 if (token.getTokenContextPath().contains(JspTagTokenContext.contextPath) 1792 && token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL2_ID){ 1793 return findMatchingScripletDelimiter(token); 1794 } 1795 if (token.getTokenContextPath().contains(JspTagTokenContext.contextPath)){ 1797 return findMatchingTag(token); 1798 } else { 1799 if (isScriptingOrContentToken(token)) { 1800 useCustomBracketFinder = false; 1801 } else { 1802 useCustomBracketFinder = true; 1803 } 1804 r_value = super.findMatchingBlock(offset, simpleSearch); 1805 } 1806 } 1807 } 1808 1809 return r_value; 1810 } 1811 1812 private int[] findMatchingJspComment(TokenItem token, int offset) { 1813 String tokenImage = token.getImage(); 1814 if(tokenImage.startsWith("<%--") && (offset < (token.getOffset()) + "<%--".length())) { while(token != null) { 1817 if((token.getTokenID() == JspTagTokenContext.COMMENT) 1818 || (token.getTokenID() == JspTagTokenContext.EOL)) { 1819 if(token.getImage().endsWith("--%>")) { int start = token.getOffset() + token.getImage().length() - "--%>".length(); int end = token.getOffset() + token.getImage().length(); 1823 return new int[] {start, end}; 1824 } 1825 } else break; 1826 token = token.getNext(); 1827 } 1828 } else if(tokenImage.endsWith("--%>") && (offset >= (token.getOffset()) + token.getImage().length() - "--%>".length())) { while(token != null) { 1831 if((token.getTokenID() == JspTagTokenContext.COMMENT) 1832 || (token.getTokenID() == JspTagTokenContext.EOL)) { 1833 if(token.getImage().startsWith("<%--")) { int start = token.getOffset(); 1836 int end = token.getOffset() + "<%--".length(); return new int[] {start, end}; 1838 } 1839 } else break; 1840 token = token.getPrevious(); 1841 } 1842 } 1843 return null; 1844 } 1845 1846 private int [] findMatchingScripletDelimiter(TokenItem token){ 1847 if (token.getImage().charAt(0) == '<'){ 1848 do{ 1849 token = token.getNext(); 1850 } while (token != null 1851 && !(token.getTokenContextPath().contains(JspTagTokenContext.contextPath) 1852 &&token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL2_ID)); 1853 } else { 1854 do{ 1855 token = token.getPrevious(); 1856 } while (token != null 1857 && !(token.getTokenContextPath().contains(JspTagTokenContext.contextPath) 1858 &&token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL2_ID)); 1859 } 1860 if (token != null){ 1861 return new int [] {token.getOffset(), token.getOffset() + token.getImage().length()}; 1862 } 1863 return null; 1864 } 1865 1866 private int[] findMatchingTag(TokenItem token){ 1867 if (token != null && token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL_ID 1870 && token.getImage().charAt(token.getImage().length()-1) == '>') 1871 token = token.getPrevious(); 1872 boolean isInside = false; if (token != null 1874 && ((token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID && token.getImage().trim().length() > 0) 1875 || (token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL_ID && token.getImage().charAt(0)=='<'))){ 1876 if (token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL_ID) while (token !=null 1879 && !(token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID 1880 && token.getImage().trim().length() > 0)) 1881 token = token.getNext(); isInside = true; } else { 1884 if (token != null 1886 && !(token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID && token.getImage().trim().length() > 0)){ 1887 token = token.getPrevious(); 1888 while (token!=null 1890 && !(token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID 1891 && token.getImage().trim().length() > 0) && !(token.getTokenID().getNumericID() == JspTagTokenContext.SYMBOL_ID 1893 && token.getImage().charAt(token.getImage().length()-1) == '>')) 1894 token = token.getPrevious(); 1895 if (token!=null && token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID) 1896 isInside = true; 1897 } 1898 } 1899 if (token != null && token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID && isInside){ 1901 1902 int start; int end; int poss = 0; String tag = token.getImage().trim(); 1906 1907 while (token != null && token.getTokenID().getNumericID() != JspTagTokenContext.SYMBOL_ID) { 1908 token = token.getPrevious(); 1909 } 1910 if (token == null) 1911 return null; 1912 if ((token.getImage().length() == 2) && token.getImage().charAt(1) == '/'){ 1913 while ( token != null){ 1914 if (token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID) { 1915 if (token.getImage().trim().equals(tag)){ 1916 while (token != null && token.getTokenID().getNumericID() != JspTagTokenContext.SYMBOL_ID) { 1917 token = token.getPrevious(); 1918 } 1919 if (token != null) { 1920 if (token.getImage().length() == 1){ 1921 if (poss == 0){ 1922 start = token.getOffset(); 1923 token = token.getNext(); 1924 end = token.getOffset()+token.getImage().length(); 1925 1926 TokenItem next = token.getNext(); 1928 if(next != null && next.getTokenID() == JspTagTokenContext.SYMBOL && next.getImage().endsWith(">")) 1929 end += next.getImage().length(); 1930 1931 return new int[] {start, end}; 1932 } else { 1933 poss++; 1934 } 1935 } 1936 if (token.getImage().length() == 2){ 1937 poss--; 1938 } 1939 } 1940 1941 } 1942 } 1943 token = token.getPrevious(); 1944 } 1945 1946 } else{ 1947 if ((token.getImage().length() == 1) && token.getImage().charAt(0) == '<'){ 1948 poss = 1; 1949 TokenItem hToken; 1950 while ( token != null){ 1951 if (token.getTokenID().getNumericID() == JspTagTokenContext.TAG_ID) { 1952 if (token.getImage().trim().equals(tag)){ 1953 hToken = token; 1954 while (token != null && token.getTokenID().getNumericID() != JspTagTokenContext.SYMBOL_ID) { 1955 token = token.getPrevious(); 1956 } 1957 if (token != null) { 1958 if (token.getImage().length() == 2){ 1959 if (poss == 0){ 1960 start = token.getOffset(); 1961 end = hToken.getOffset()+hToken.getImage().length()+1; 1962 token = token.getNext(); 1963 1964 while (token != null && (token.getTokenID().getNumericID() != JspTagTokenContext.SYMBOL_ID 1965 || token.getImage().charAt(0)!='>')){ 1966 token = token.getNext(); 1967 } 1968 if (token != null) 1969 end = token.getOffset()+1; 1970 return new int[] {start, end}; 1971 } else { 1972 poss++; 1973 } 1974 } 1975 if (token.getImage().length() == 1){ 1976 poss--; 1977 } 1978 } 1979 token = hToken; 1980 } 1981 } 1982 token = token.getNext(); 1983 } 1984 } 1985 } 1986 } 1987 return null; 1988 } 1989 1990 1994 public boolean isSingletonTag(TokenItem tagTokenItem) { 1995 TokenItem ti = tagTokenItem; 1996 while(ti != null) { 1997 if(ti.getTokenID() == JspTagTokenContext.SYMBOL){ 1998 if("/>".equals(ti.getImage())) { return true; 2001 } 2002 if(">".equals(ti.getImage())) return false; } 2004 if(ti.getTokenID() == JspTagTokenContext.TEXT) break; 2007 2008 ti = ti.getNext(); 2009 } 2010 return false; 2011 } 2012 2013 2017 protected TokenID[] getBracketSkipTokens() { 2018 return JSP_BRACKET_SKIP_TOKENS; 2019 } 2020 2021 public static TokenSequence tokenSequence(TokenHierarchy hi, Language language, int offset) { 2022 TokenSequence ts = hi.tokenSequence(language); 2023 if(ts == null) { 2024 ts = hi.tokenSequence(); 2026 int diff = ts.move(offset); 2027 if(!ts.moveNext() && !ts.movePrevious()) { 2028 return null; } else { 2030 ts = ts.embedded(language); 2031 } 2032 } 2033 return ts; 2034 } 2035 2036 2037 2040 public class BracketFinder extends ExtSyntaxSupport.BracketFinder { 2041 2042 BracketFinder(char c) { 2043 super(c); 2044 } 2045 2046 2050 protected boolean updateStatus() { 2051 if (super.updateStatus()) 2052 return true; 2053 boolean valid = true; 2054 switch (bracketChar) { 2055 case '<': 2056 matchChar = '>'; 2057 moveCount = +1; 2058 break; 2059 case '>': 2060 matchChar = '<'; 2061 moveCount = -1; 2062 break; 2063 default: 2064 valid = false; 2065 } 2066 return valid; 2067 } 2068 2069 boolean isValid() { 2070 return (moveCount != 0); 2071 } 2072 2073 } 2074 2075 private static class TagNameComparator implements Comparator{ 2076 2077 public TagNameComparator() {} 2078 2079 public int compare(Object o1, Object o2) { 2080 if (o1 == o2 || o1 == null || o2 == null){ 2081 return 0; 2082 } 2083 String tagNameOne = ((TagInfo)o1).getTagName(); 2084 String tagNameTwo = ((TagInfo)o2).getTagName(); 2085 if (tagNameOne == null || tagNameTwo == null){ 2086 return 0; 2087 } 2088 return tagNameOne.compareTo(tagNameTwo); 2089 } 2090 } 2091} 2092 | Popular Tags |