1 19 20 package org.netbeans.modules.web.core.syntax; 21 22 23 import java.util.Map ; 24 import org.netbeans.api.lexer.LanguagePath; 25 import org.netbeans.modules.web.core.syntax.deprecated.Jsp11Syntax; 26 import org.netbeans.modules.web.core.syntax.deprecated.ELDrawLayerFactory; 27 import org.netbeans.modules.web.core.syntax.formatting.JspFormatter; 28 import java.awt.event.ActionEvent ; 29 import java.beans.*; 30 import javax.swing.Action ; 31 import javax.swing.JMenu ; 32 import javax.swing.text.*; 33 import org.netbeans.api.html.lexer.HTMLTokenId; 34 import org.netbeans.api.java.lexer.JavaTokenId; 35 import org.netbeans.api.lexer.Language; 36 import org.netbeans.api.lexer.TokenHierarchy; 37 import org.netbeans.api.lexer.TokenSequence; 38 import org.netbeans.editor.BaseAction; 39 import org.netbeans.editor.BaseDocument; 40 import org.netbeans.editor.DrawLayer; 41 import org.netbeans.editor.DrawLayerFactory; 42 import org.netbeans.editor.Syntax; 43 import org.netbeans.editor.Utilities; 44 import org.netbeans.editor.ext.Completion; 45 import org.netbeans.editor.ext.ExtEditorUI; 46 import org.netbeans.editor.ext.ExtSyntaxSupport; 47 import org.netbeans.editor.ext.java.JavaSyntax; 48 import org.netbeans.modules.editor.NbEditorDocument; 49 import org.netbeans.modules.editor.NbEditorUtilities; 50 import org.netbeans.modules.web.core.syntax.folding.JspFoldTypes; 51 import org.netbeans.spi.jsp.lexer.JspParseData; 52 import org.netbeans.spi.lexer.TokenHierarchyControl; 53 import org.openide.ErrorManager; 54 import org.openide.text.CloneableEditorSupport; 55 import org.openide.util.NbBundle; 56 import org.openide.util.WeakListeners; 57 import org.openide.filesystems.FileObject; 58 import org.openide.loaders.DataObject; 59 import org.netbeans.editor.SyntaxSupport; 60 import org.netbeans.editor.BaseKit; 61 import org.netbeans.editor.Formatter; 62 import org.netbeans.editor.ext.CompletionJavaDoc; 63 import org.netbeans.editor.ext.ExtKit; 64 import org.netbeans.editor.ext.java.JavaDrawLayerFactory; 65 import org.netbeans.editor.ext.html.HTMLSyntax; 66 import org.netbeans.modules.editor.java.JavaKit; 67 import org.netbeans.modules.web.core.syntax.spi.JSPColoringData; 68 import org.netbeans.modules.web.core.syntax.spi.JspContextInfo; 69 import org.netbeans.api.editor.fold.FoldHierarchy; 70 import org.netbeans.api.editor.fold.FoldUtilities; 71 import org.netbeans.api.jsp.lexer.JspTokenId; 72 import org.netbeans.api.lexer.InputAttributes; 73 import org.netbeans.editor.BaseKit.InsertBreakAction; 74 import org.netbeans.editor.ext.ExtKit.ExtDefaultKeyTypedAction; 75 import org.netbeans.editor.ext.ExtKit.ExtDeleteCharAction; 76 import org.netbeans.modules.editor.NbEditorKit; 77 import org.netbeans.modules.editor.NbEditorKit.GenerateFoldPopupAction; 78 79 86 public class JSPKit extends NbEditorKit implements org.openide.util.HelpCtx.Provider{ 87 88 public static final String JSP_MIME_TYPE = "text/x-jsp"; public static final String TAG_MIME_TYPE = "text/x-tag"; 91 public static final String collapseAllCommentsAction = "collapse-all-comment-folds"; public static final String expandAllCommentsAction = "expand-all-comment-folds"; 95 public static final String collapseAllScriptingAction = "collapse-all-scripting-folds"; public static final String expandAllScriptingAction = "expand-all-scripting-folds"; 99 100 private static final long serialVersionUID = 8933974837050367142L; 101 102 public static final boolean debug = false; 103 104 105 public JSPKit() { 106 super(); 107 } 108 109 public String getContentType() { 110 return JSP_MIME_TYPE; 111 } 112 113 114 public Syntax createSyntax(Document doc) { 115 initLexerColoringListener(doc); 119 120 DataObject dobj = NbEditorUtilities.getDataObject(doc); 121 FileObject fobj = (dobj != null) ? dobj.getPrimaryFile() : null; 122 123 125 Syntax contentSyntax = getSyntaxForLanguage(doc, JspUtils.getContentLanguage()); 126 Syntax scriptingSyntax = getSyntaxForLanguage(doc, JspUtils.getScriptingLanguage()); 127 final Jsp11Syntax newSyntax = new Jsp11Syntax(contentSyntax, scriptingSyntax); 128 129 JSPColoringData data = data = JspUtils.getJSPColoringData(doc, fobj); 131 PropertyChangeListener pList = new ColoringListener(doc, data, newSyntax); 133 if (data != null) { 137 data.addPropertyChangeListener(WeakListeners.propertyChange(pList, data)); 138 } 139 return newSyntax; 140 } 141 142 protected Action [] createActions() { 143 Action [] javaActions = new Action [] { 144 new MatchBraceAction(ExtKit.matchBraceAction, false), 150 new MatchBraceAction(ExtKit.selectionMatchBraceAction, true), 151 new JspGenerateFoldPopupAction(), 152 new CollapseAllCommentsFolds(), 153 new ExpandAllCommentsFolds(), 154 new CollapseAllScriptingFolds(), 155 new ExpandAllScriptingFolds(), 156 new JspInsertBreakAction(), 157 new JspDefaultKeyTypedAction(), 158 new JspDeleteCharAction(deletePrevCharAction, false), 159 }; 160 161 return TextAction.augmentList(super.createActions(), javaActions); 162 } 163 164 private static class LexerColoringListener implements PropertyChangeListener { 165 166 private Document doc; 167 private JSPColoringData data; 168 private JspParseData jspParseData; 169 170 private LexerColoringListener(Document doc, JSPColoringData data, JspParseData jspParseData) { 171 this.doc = doc; 172 this.data = data; this.jspParseData = jspParseData; 174 } 175 176 public void propertyChange(PropertyChangeEvent evt) { 177 if (JSPColoringData.PROP_COLORING_CHANGE.equals(evt.getPropertyName())) { 178 recolor(); 179 } 180 } 181 private void recolor() { 182 jspParseData.updateParseData((Map <String ,String >)data.getPrefixMapper(), data.isELIgnored(), data.isXMLSyntax()); 183 184 TokenHierarchyControl thc = (TokenHierarchyControl)doc.getProperty(TokenHierarchyControl.class); 185 if(thc != null) { 186 thc.rebuild(); 187 } 188 } 189 190 } 191 192 private static class ColoringListener implements PropertyChangeListener { 193 private Document doc; 194 private Object parsedDataRef; private Jsp11Syntax syntax; 197 199 public ColoringListener(Document doc, JSPColoringData data, Jsp11Syntax syntax) { 200 this.doc = doc; 201 this.parsedDataRef = data; 203 this.syntax = syntax; 204 syntax.listenerReference = this; 206 syntax.data = data; 207 208 } 209 210 private void recolor() { 211 if (doc instanceof BaseDocument) 212 ((BaseDocument)doc).invalidateSyntaxMarks(); 213 } 214 215 public void propertyChange(PropertyChangeEvent evt) { 216 if (syntax == null) 218 return; 219 if (syntax.listenerReference != this) { 220 syntax = null; return; 222 } 223 231 if (JSPColoringData.PROP_COLORING_CHANGE.equals(evt.getPropertyName())) { 232 recolor(); 233 } 234 } 235 } 236 237 public static Syntax getSyntaxForLanguage(Document doc, String language) { 238 EditorKit kit = CloneableEditorSupport.getEditorKit(language); 239 if (kit instanceof JavaKit) { 240 JavaKit jkit = (JavaKit)kit; 241 String sourceLevel = jkit.getSourceLevel((BaseDocument)doc); 242 return new JavaSyntax(sourceLevel, true); 244 } else { 245 return new HTMLSyntax(); 246 } 247 } 248 249 250 public SyntaxSupport createSyntaxSupport(BaseDocument doc) { 251 DataObject dobj = NbEditorUtilities.getDataObject(doc); 252 if (dobj != null) { 253 if (dobj.getPrimaryFile() != null) 254 return new JspSyntaxSupport(doc, 255 JspContextInfo.getContextInfo(dobj.getPrimaryFile()).getCachedOpenInfo(doc, dobj.getPrimaryFile(), false).isXmlSyntax()); 256 } 257 return new JspSyntaxSupport(doc, false); 258 259 } 260 261 264 public Completion createCompletion(ExtEditorUI extEditorUI) { 265 return null; 266 } 267 268 271 public CompletionJavaDoc createCompletionJavaDoc(ExtEditorUI extEditorUI) { 272 return null; 273 } 274 275 protected void initDocument(BaseDocument doc) { 276 doc.addLayer(new JavaDrawLayerFactory.JavaLayer(), 277 JavaDrawLayerFactory.JAVA_LAYER_VISIBILITY); 278 doc.addDocumentListener(new JavaDrawLayerFactory.LParenWatcher()); 279 doc.addLayer(new ELDrawLayerFactory.ELLayer(), 280 ELDrawLayerFactory.EL_LAYER_VISIBILITY); 281 doc.addDocumentListener(new ELDrawLayerFactory.LParenWatcher()); 282 } 283 284 private void initLexerColoringListener(Document doc) { 285 DataObject dobj = NbEditorUtilities.getDataObject(doc); 286 FileObject fobj = (dobj != null) ? dobj.getPrimaryFile() : null; 287 JSPColoringData data = JspUtils.getJSPColoringData(doc, fobj); 288 289 if(data == null) { 290 return ; 291 } 292 293 JspParseData jspParseData = new JspParseData(); 294 jspParseData.updateParseData((Map <String ,String >)data.getPrefixMapper(), data.isELIgnored(), data.isXMLSyntax()); 295 PropertyChangeListener lexerColoringListener = new LexerColoringListener(doc, data, jspParseData); 296 297 data.addPropertyChangeListener(WeakListeners.propertyChange(lexerColoringListener, data)); 298 doc.putProperty(LexerColoringListener.class, lexerColoringListener); 300 301 InputAttributes inputAttributes = new InputAttributes(); 304 inputAttributes.setValue(JspTokenId.language(), JspParseData.class, jspParseData, false); 305 doc.putProperty(InputAttributes.class, inputAttributes); 306 } 307 308 public Formatter createFormatter() { 309 return new JspFormatter(this.getClass()); 310 311 } 312 313 public org.openide.util.HelpCtx getHelpCtx() { 316 return new org.openide.util.HelpCtx(JSPKit.class); 317 } 318 319 320 322 public static class MatchBraceAction extends ExtKit.MatchBraceAction { 323 324 private boolean select; public MatchBraceAction(String name, boolean select) { 326 super(name, select); 327 this.select = select; 328 } 329 330 public void actionPerformed(ActionEvent evt, JTextComponent target) { 331 if (target != null) { 332 try { 333 Caret caret = target.getCaret(); 334 BaseDocument doc = Utilities.getDocument(target); 335 int dotPos = caret.getDot(); 336 dotPos--; ExtSyntaxSupport sup = (ExtSyntaxSupport)doc.getSyntaxSupport(); 338 339 TokenHierarchy hi = TokenHierarchy.get(doc); 340 BaseKit kit = null; 341 try { 342 if(JspSyntaxSupport.tokenSequence(hi, HTMLTokenId.language(), dotPos) != null) { 344 kit = getKit(getClass().forName("org.netbeans.modules.editor.html.HTMLKit")); } 346 if(JspSyntaxSupport.tokenSequence(hi, JavaTokenId.language(), dotPos) != null) { 347 kit = getKit(getClass().forName("org.netbeans.modules.editor.java.JavaKit")); } 349 } catch (java.lang.ClassNotFoundException e){ 350 kit = null; 351 ErrorManager.getDefault().notify(ErrorManager.WARNING, e); 352 } 353 354 if (kit == null) { 355 if (dotPos > 0) { 357 int[] matchBlk = sup.findMatchingBlock(dotPos - 1, false); 358 if (matchBlk != null) { 359 if (select) { 360 caret.moveDot(matchBlk[1]); 361 } else { 362 caret.setDot(matchBlk[1]); 363 } 364 } 365 } 366 } else { 367 Action action = kit.getActionByName(select ? ExtKit.selectionMatchBraceAction : ExtKit.matchBraceAction); 369 if (action != null && action instanceof ExtKit.MatchBraceAction){ 370 ((ExtKit.MatchBraceAction)action).actionPerformed(evt, target); 371 } else { 372 super.actionPerformed(evt, target); 373 } 374 } 375 376 } catch (BadLocationException e) { 377 target.getToolkit().beep(); 378 } 379 } 380 } 381 } 382 383 public static class JspGenerateFoldPopupAction extends GenerateFoldPopupAction { 384 385 protected void addAdditionalItems(JTextComponent target, JMenu menu){ 386 addAction(target, menu, collapseAllCommentsAction); 387 addAction(target, menu, expandAllCommentsAction); 388 setAddSeparatorBeforeNextAction(true); 389 addAction(target, menu, collapseAllScriptingAction); 390 addAction(target, menu, expandAllScriptingAction); 391 } 392 } 393 394 public static class ExpandAllCommentsFolds extends BaseAction{ 395 public ExpandAllCommentsFolds(){ 396 super(expandAllCommentsAction); 397 putValue(SHORT_DESCRIPTION, NbBundle.getBundle(JSPKit.class).getString("expand-all-comment-folds")); 398 putValue(BaseAction.POPUP_MENU_TEXT, NbBundle.getBundle(JSPKit.class).getString("popup-expand-all-comment-folds")); 399 } 400 401 public void actionPerformed(ActionEvent evt, JTextComponent target) { 402 FoldHierarchy hierarchy = FoldHierarchy.get(target); 403 FoldUtilities.expand(hierarchy, JspFoldTypes.COMMENT); 405 FoldUtilities.expand(hierarchy, JspFoldTypes.HTML_COMMENT); 406 407 } 408 } 409 410 public static class CollapseAllCommentsFolds extends BaseAction{ 411 public CollapseAllCommentsFolds(){ 412 super(collapseAllCommentsAction); 413 putValue(SHORT_DESCRIPTION, NbBundle.getBundle(JSPKit.class).getString("collapse-all-comment-folds")); 414 putValue(BaseAction.POPUP_MENU_TEXT, NbBundle.getBundle(JSPKit.class).getString("popup-collapse-all-comment-folds")); 415 } 416 417 public void actionPerformed(ActionEvent evt, JTextComponent target) { 418 FoldHierarchy hierarchy = FoldHierarchy.get(target); 419 FoldUtilities.collapse(hierarchy, JspFoldTypes.COMMENT); 421 FoldUtilities.collapse(hierarchy, JspFoldTypes.HTML_COMMENT); 422 } 423 } 424 425 public static class ExpandAllScriptingFolds extends BaseAction{ 426 public ExpandAllScriptingFolds(){ 427 super(expandAllScriptingAction); 428 putValue(SHORT_DESCRIPTION, NbBundle.getBundle(JSPKit.class).getString("expand-all-scripting-folds")); 429 putValue(BaseAction.POPUP_MENU_TEXT, NbBundle.getBundle(JSPKit.class).getString("popup-expand-all-scripting-folds")); 430 } 431 432 public void actionPerformed(ActionEvent evt, JTextComponent target) { 433 FoldHierarchy hierarchy = FoldHierarchy.get(target); 434 FoldUtilities.expand(hierarchy, JspFoldTypes.SCRIPTLET); 436 FoldUtilities.expand(hierarchy, JspFoldTypes.DECLARATION); 437 } 438 } 439 440 public static class CollapseAllScriptingFolds extends BaseAction{ 441 public CollapseAllScriptingFolds(){ 442 super(collapseAllScriptingAction); 443 putValue(SHORT_DESCRIPTION, NbBundle.getBundle(JSPKit.class).getString("collapse-all-scripting-folds")); 444 putValue(BaseAction.POPUP_MENU_TEXT, NbBundle.getBundle(JSPKit.class).getString("popup-collapse-all-scripting-folds")); 445 } 446 447 public void actionPerformed(ActionEvent evt, JTextComponent target) { 448 FoldHierarchy hierarchy = FoldHierarchy.get(target); 449 FoldUtilities.collapse(hierarchy, JspFoldTypes.SCRIPTLET); 451 FoldUtilities.collapse(hierarchy, JspFoldTypes.DECLARATION); 452 } 453 } 454 455 473 public static class JspInsertBreakAction extends InsertBreakAction { 474 public void actionPerformed(ActionEvent e, JTextComponent target) { 475 if (target!=null){ 476 TokenSequence javaTokenSequence = JspSyntaxSupport.tokenSequence( 477 TokenHierarchy.get(target.getDocument()), 478 JavaTokenId.language(), 479 target.getCaret().getDot() - 1); 480 481 if (javaTokenSequence != null){ 482 JavaKit jkit = (JavaKit)getKit(JavaKit.class); 483 if (jkit!=null){ 484 Action action = jkit.getActionByName(DefaultEditorKit.insertBreakAction); 485 if (action != null && action instanceof JavaKit.JavaInsertBreakAction){ 486 ((JavaKit.JavaInsertBreakAction)action).actionPerformed(e, target); 487 return; 488 } 489 } 490 } 491 } 492 super.actionPerformed(e, target); 493 } 494 } 495 496 public static class JspDefaultKeyTypedAction extends ExtDefaultKeyTypedAction { 497 public void actionPerformed(ActionEvent e, JTextComponent target) { 498 if (target!=null){ 499 TokenSequence javaTokenSequence = JspSyntaxSupport.tokenSequence( 500 TokenHierarchy.get(target.getDocument()), 501 JavaTokenId.language(), 502 target.getCaret().getDot() - 1); 503 504 if (javaTokenSequence != null){ 505 JavaKit jkit = (JavaKit)getKit(JavaKit.class); 506 if (jkit!=null){ 507 Action action = jkit.getActionByName(DefaultEditorKit.defaultKeyTypedAction); 508 if (action != null && action instanceof JavaKit.JavaDefaultKeyTypedAction){ 509 ((JavaKit.JavaDefaultKeyTypedAction)action).actionPerformed(e, target); 510 return; 511 } 512 } 513 } 514 } 515 super.actionPerformed(e, target); 516 } 517 } 518 519 public static class JspDeleteCharAction extends ExtDeleteCharAction { 520 521 public JspDeleteCharAction(String nm, boolean nextChar) { 522 super(nm, nextChar); 523 } 524 525 public void actionPerformed(ActionEvent e, JTextComponent target) { 526 if (target!=null){ 527 TokenSequence javaTokenSequence = JspSyntaxSupport.tokenSequence( 528 TokenHierarchy.get(target.getDocument()), 529 JavaTokenId.language(), 530 target.getCaret().getDot() - 1); 531 532 if (javaTokenSequence != null){ 533 JavaKit jkit = (JavaKit)getKit(JavaKit.class); 534 if (jkit!=null){ 535 Action action = jkit.getActionByName(DefaultEditorKit.deletePrevCharAction); 536 if (action != null && action instanceof JavaKit.JavaDeleteCharAction){ 537 ((JavaKit.JavaDeleteCharAction)action).actionPerformed(e, target); 538 return; 539 } 540 } 541 } 542 } 543 super.actionPerformed(e, target); 544 } 545 } 546 547 581 582 } 583 584 | Popular Tags |