1 19 package org.netbeans.modules.gsf; 20 21 import java.awt.Color ; 22 import java.awt.Font ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.OutputStream ; 26 import java.util.*; 27 import java.util.ArrayList ; 28 import java.util.HashMap ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 33 import javax.swing.SwingUtilities ; 34 import javax.swing.text.AttributeSet ; 35 import javax.swing.text.SimpleAttributeSet ; 36 import javax.swing.text.StyleConstants ; 37 38 import org.netbeans.api.editor.settings.EditorStyleConstants; 39 import org.netbeans.api.gsf.annotations.NonNull; 40 import org.netbeans.api.lexer.TokenId; 41 42 import org.netbeans.modules.gsf.Language; 45 import org.openide.ErrorManager; 46 import org.openide.filesystems.FileObject; 47 import org.openide.filesystems.FileObject; 48 import org.openide.filesystems.FileSystem; 49 import org.openide.filesystems.FileSystem; 50 import org.openide.filesystems.FileSystem.AtomicAction; 51 import org.openide.filesystems.FileUtil; 52 import org.openide.filesystems.FileUtil; 53 import org.openide.filesystems.Repository; 54 import org.openide.filesystems.Repository; 55 56 57 64 public class LanguageRegistry implements Iterable <Language> { 65 private static LanguageRegistry instance; 66 private static final String DISPLAY_NAME = "displayName"; 67 private static final String ICON_BASE = "iconBase"; 68 private static final String EXTENSIONS = "extensions"; 69 private static final String LANGUAGE = "language.instance"; 70 private static final String PARSER = "parser.instance"; 71 private static final String COMPLETION = "completion.instance"; 72 private static final String RENAMER = "renamer.instance"; 73 private static final String FORMATTER = "formatter.instance"; 74 private static final String BRACKET_COMPLETION = "bracket.instance"; 75 private static final String DECLARATION_FINDER = "declarationfinder.instance"; 76 private static final String INDEXER = "indexer.instance"; 77 private static final String PALETTE = "palette.instance"; 78 private static final String STRUCTURE = "structure.instance"; 79 80 81 private static final String FOLDER = "GsfPlugins"; 82 private List <Language> languages; 83 private boolean languagesInitialized; 84 85 88 public LanguageRegistry() { 89 initialize(); 90 } 91 92 public static synchronized LanguageRegistry getInstance() { 93 if (instance == null) { 94 instance = new LanguageRegistry(); 95 } 96 97 return instance; 98 } 99 100 104 public Language getLanguageByExtension(@NonNull 105 String extension) { 106 extension = extension.toLowerCase(); 107 108 for (Language language : this) { 110 String [] extensions = language.getExtensions(); 111 112 for (int i = 0; i < extensions.length; i++) { 113 if (extension.equals(extensions[i])) { 114 return language; 115 } 116 } 117 } 118 119 return null; 120 } 121 122 126 public Language getLanguageByMimeType(@NonNull 127 String mimeType) { 128 assert mimeType.equals(mimeType.toLowerCase()); 129 130 for (Language language : this) { 131 if (language.getMimeType().equals(mimeType)) { 132 return language; 133 } 134 } 135 136 return null; 137 } 138 139 143 public boolean isSupported(@NonNull 144 String mimeType) { 145 for (Language language : this) { 146 if (mimeType.equals(language.getMimeType())) { 147 return true; 148 } 149 } 150 151 return false; 152 } 153 154 public Iterator <Language> iterator() { 155 if (languages == null) { 156 return new Iterator <Language>() { 157 public boolean hasNext() { 158 return false; 159 } 160 161 public Language next() { 162 return null; 163 } 164 165 public void remove() { 166 } 167 }; 168 } else { 169 return languages.iterator(); 170 } 171 } 172 173 private synchronized void initialize() { 174 if (languages == null) { 175 readSfs(); 176 177 initializeLanguages(); 178 } 179 } 180 181 synchronized void initializeLanguages() { 182 if (languagesInitialized) { 183 return; 184 } 185 186 languagesInitialized = true; 187 188 if (languages == null) { 189 return; 191 } 192 193 Iterator it = languages.iterator(); 194 195 while (it.hasNext()) { 196 final Language language = (Language)it.next(); 197 198 initializeLanguage(language); 199 200 211 } 229 } 230 231 private void readSfs() { 232 FileSystem sfs = Repository.getDefault().getDefaultFileSystem(); 233 FileObject f = sfs.findResource(FOLDER); 234 235 if (f == null) { 236 return; 237 } 238 239 FileObject[] children = f.getChildren(); 241 languages = new ArrayList <Language>(); 242 243 for (int i = 0; i < children.length; i++) { 244 FileObject mimePrefixFile = children[i]; 245 246 FileObject[] innerChildren = mimePrefixFile.getChildren(); 248 249 for (int j = 0; j < innerChildren.length; j++) { 250 FileObject mimeFile = innerChildren[j]; 251 252 String mime = mimePrefixFile.getName() + "/" + mimeFile.getName(); 253 DefaultLanguage language = new DefaultLanguage(mime); 254 languages.add(language); 255 256 String displayName = (String )mimeFile.getAttribute(DISPLAY_NAME); 257 258 275 if ((displayName != null) && (displayName.length() > 0)) { 276 language.setDisplayName(displayName); 277 } 278 279 FileObject loaderMimeFile = sfs.findResource("Loaders/" + mime); 281 282 if (loaderMimeFile != null) { 283 String iconBase = (String )loaderMimeFile.getAttribute(ICON_BASE); 284 285 if ((iconBase != null) && (iconBase.length() > 0)) { 286 language.setIconBase(iconBase); 287 } 288 } 289 290 297 FileObject extensionsDir = mimeFile.getFileObject(EXTENSIONS, null); 299 300 if ((extensionsDir != null) && extensionsDir.isFolder()) { 301 FileObject[] extensionFiles = extensionsDir.getChildren(); 302 303 for (int k = 0; k < extensionFiles.length; k++) { 304 String extension = extensionFiles[k].getName(); 305 language.addExtension(extension); 306 } 307 } 308 309 FileObject languageFile = mimeFile.getFileObject(LANGUAGE, null); 310 311 if (languageFile != null) { 312 language.setGsfLanguageFile(languageFile); 313 } 314 315 FileObject parserFile = mimeFile.getFileObject(PARSER, null); 316 317 if (parserFile != null) { 318 language.setParserFile(parserFile); 319 } 320 321 FileObject completionFile = mimeFile.getFileObject(COMPLETION, null); 322 323 if (completionFile != null) { 324 language.setCompletionProviderFile(completionFile); 325 } 326 327 FileObject renamerFile = mimeFile.getFileObject(RENAMER, null); 328 329 if (renamerFile != null) { 330 language.setInstantRenamerFile(renamerFile); 331 } 332 333 FileObject formatterFile = mimeFile.getFileObject(FORMATTER, null); 334 335 if (formatterFile != null) { 336 language.setFormatterFile(formatterFile); 337 } 338 339 FileObject finderFile = mimeFile.getFileObject(DECLARATION_FINDER, null); 340 341 if (finderFile != null) { 342 language.setDeclarationFinderFile(finderFile); 343 } 344 345 FileObject bracketFile = mimeFile.getFileObject(BRACKET_COMPLETION, null); 346 347 if (bracketFile != null) { 348 language.setBracketCompletionFile(bracketFile); 349 } 350 351 FileObject indexerFile = mimeFile.getFileObject(INDEXER, null); 352 353 if (indexerFile != null) { 354 language.setIndexerFile(indexerFile); 355 } 356 357 FileObject structureFile = mimeFile.getFileObject(STRUCTURE, null); 358 359 if (structureFile != null) { 360 language.setStructureFile(structureFile); 361 } 362 363 FileObject paletteFile = mimeFile.getFileObject(PALETTE, null); 364 365 if (paletteFile != null) { 366 language.setPaletteFile(paletteFile); 367 } 368 } 369 } 370 } 371 372 377 private void initializeLanguage(Language language) { 378 FileSystem fs = Repository.getDefault().getDefaultFileSystem(); 379 380 String oldNavFileName = 381 "Navigator/Panels/" + language.getMimeType() + 382 "/org-netbeans-modules-retouche-navigation-GsfStructurePanel.instance"; 383 384 FileObject fo = fs.findResource(oldNavFileName); 386 387 if (fo != null) { 388 try { 389 fo.delete(); 390 } catch (IOException ex) { 391 ErrorManager.getDefault().notify(ex); 392 } 393 } 394 395 String navFileName = 396 "Navigator/Panels/" + language.getMimeType() + 397 "/org-netbeans-modules-retouche-navigation-ClassMemberPanel.instance"; 398 399 fo = fs.findResource(navFileName); 400 401 if (fo == null) { 402 try { 403 FileUtil.createData(fs.getRoot(), navFileName); 404 } catch (IOException ex) { 405 ErrorManager.getDefault().notify(ex); 406 } 407 } 408 } 409 410 421 void initializeLanguageForEditor(Language l) { 422 FileSystem fs = Repository.getDefault().getDefaultFileSystem(); 423 final FileObject root = fs.findResource("Editors/" + l.getMimeType()); 424 425 if (root.getFileObject("Settings.settings") == null) { 427 try { 428 fs.runAtomicAction(new AtomicAction() { 429 public void run() { 430 try { 431 InputStream is = 432 getClass().getClassLoader() 433 .getResourceAsStream("org/netbeans/modules/gsf/GsfOptions.settings"); 434 435 try { 436 FileObject fo = root.createData("Settings.settings"); 437 OutputStream os = fo.getOutputStream(); 438 439 try { 440 FileUtil.copy(is, os); 441 442 } finally { 444 os.close(); 445 } 446 } finally { 447 is.close(); 448 } 449 } catch (IOException ex) { 450 ErrorManager.getDefault().notify(ex); 451 } 452 } 453 }); 454 } catch (IOException ex) { 455 ErrorManager.getDefault().notify(ex); 456 } 457 } 458 459 if ((root.getFileObject( 461 "SideBar/org-netbeans-modules-editor-retouche-GsfCodeFoldingSideBarFactory.instance") == null) && 462 (l.getParser() != null)) { 464 try { 465 FileUtil.createData(root, 467 "FoldManager/org-netbeans-modules-retouche-editor-fold-GsfFoldManagerFactory.instance"); 468 FileUtil.createData(root, 469 "SideBar/org-netbeans-modules-editor-retouche-GsfCodeFoldingSideBarFactory.instance"); 470 471 FileObject fo = root.getFileObject("SideBar"); 472 fo.setAttribute("org-netbeans-editor-GlyphGutter.instance/org-netbeans-modules-editor-retouche-GsfCodeFoldingSideBarFactory.instance", 473 Boolean.TRUE); 474 } catch (IOException ex) { 475 ErrorManager.getDefault().notify(ex); 476 } 477 } 478 479 if (root.getFileObject("HyperlinkProviders/GsfHyperlinkProvider.instance") == null) { 481 try { 482 FileObject fo = 483 FileUtil.createData(root, "HyperlinkProviders/GsfHyperlinkProvider.instance"); 484 fo.setAttribute("instanceClass", 485 "org.netbeans.modules.retouche.editor.hyperlink.GsfHyperlinkProvider"); 486 fo.setAttribute("instanceOf", 487 "org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider"); 488 } catch (IOException ex) { 489 ErrorManager.getDefault().notify(ex); 490 } 491 } 492 493 FileObject popup = root.getFileObject("Popup"); 495 496 if (popup == null) { 497 try { 498 popup = root.createFolder("Popup"); 499 popup.createData("in-place-refactoring"); 500 popup.createData("generate-goto-popup"); 501 502 FileObject sep = popup.createData("SeparatorBeforeCut.instance"); 503 sep.setAttribute("instanceClass", "javax.swing.JSeparator"); 504 popup.setAttribute("SeparatorBeforeCut.instance/org-netbeans-modules-editor-NbSelectInPopupAction.instance", 505 Boolean.TRUE); 506 popup.setAttribute("SeparatorBeforeCut.instance/org-openide-actions-CutAction.instance", 507 Boolean.TRUE); 508 popup.setAttribute("in-place-refactoring/generate-goto-popup", Boolean.TRUE); 509 popup.setAttribute("generate-goto-popup/SeparatorBeforeCut.instance", Boolean.TRUE); 510 511 512 popup.setAttribute("org-openide-actions-PasteAction.instance/SeparatorBeforeFormat.instance", 513 Boolean.TRUE); 514 FileObject sep2 = popup.createData("SeparatorBeforeFormat.instance"); 515 sep2.setAttribute("instanceClass", "javax.swing.JSeparator"); 516 popup.setAttribute("SeparatorBeforeFormat.instance/format", 517 Boolean.TRUE); 518 popup.createData("format"); 519 popup.createData("pretty-print"); 520 popup.setAttribute("format/pretty-print", Boolean.TRUE); 521 } catch (IOException ex) { 522 ErrorManager.getDefault().notify(ex); 523 } 524 } else { 525 if (root.getFileObject("Popup/format") == null) { 527 try { 528 popup.createData("format"); 529 } catch (IOException ex) { 530 ErrorManager.getDefault().notify(ex); 531 } 532 } 533 if (root.getFileObject("Popup/pretty-print") == null) { 534 try { 535 popup.createData("pretty-print"); 536 } catch (IOException ex) { 537 ErrorManager.getDefault().notify(ex); 538 } 539 } 540 } 541 542 if (root.getFileObject( 544 "UpToDateStatusProvider/org-netbeans-modules-retouche-hints-GsfUpToDateStateProviderFactory.instance") == null) { 545 try { 546 FileUtil.createData(root, 547 "UpToDateStatusProvider/org-netbeans-modules-retouche-hints-GsfUpToDateStateProviderFactory.instance"); 548 } catch (IOException ex) { 549 ErrorManager.getDefault().notify(ex); 550 } 551 } 552 553 if (root.getFileObject( 555 "UpToDateStatusProvider/org-netbeans-modules-retouche-editor-semantic-OccurrencesMarkProviderCreator.instance") == null) { 556 try { 557 FileUtil.createData(root, 558 "UpToDateStatusProvider/org-netbeans-modules-retouche-editor-semantic-OccurrencesMarkProviderCreator.instance"); 559 } catch (IOException ex) { 560 ErrorManager.getDefault().notify(ex); 561 } 562 } 563 564 String hintsFilename = 566 "Editors/" + l.getMimeType() + 567 "/org-netbeans-modules-retouche-hints-GsfHintsProvider.instance"; 568 569 if (fs.findResource(hintsFilename) == null) { 570 try { 571 FileObject fo = FileUtil.createData(fs.getRoot(), hintsFilename); 572 fo.setAttribute("instanceOf", "org.netbeans.modules.editor.hints.spi.HintsProvider"); 573 } catch (IOException ex) { 574 ErrorManager.getDefault().notify(ex); 575 } 576 } 577 578 FileObject completion = root.getFileObject("CompletionProviders"); 580 581 if (completion == null) { 582 try { 583 completion = root.createFolder("CompletionProviders"); 584 completion.createData( 585 "org-netbeans-lib-editor-codetemplates-CodeTemplateCompletionProvider.instance"); 586 completion.createData( 587 "org-netbeans-modules-retouche-editor-completion-GsfCompletionProvider.instance"); 588 } catch (IOException ex) { 589 ErrorManager.getDefault().notify(ex); 590 } 591 } 592 593 if (root.getFileObject("Toolbars/Default/comment") == null) { 595 if (!((l.getGsfLanguage() == null) || 596 (l.getGsfLanguage().getLineCommentPrefix() == null))) { 597 try { 598 FileObject sep = 599 FileUtil.createData(root, 600 "Toolbars/Default/Separator-before-comment.instance"); 601 sep.setAttribute("instanceClass", "javax.swing.JSeparator"); 602 603 FileObject folder = root.getFileObject("Toolbars/Default"); 604 folder.setAttribute("stop-macro-recording/Separator-before-comment.instance", 605 Boolean.TRUE); 606 FileUtil.createData(root, "Toolbars/Default/comment"); 607 folder.setAttribute("Separator-before-comment.instance/comment", Boolean.TRUE); 608 FileUtil.createData(root, "Toolbars/Default/uncomment"); 609 folder.setAttribute("comment/uncomment", Boolean.TRUE); 610 } catch (IOException ex) { 611 ErrorManager.getDefault().notify(ex); 612 } 613 } 614 } 615 616 if (root.getFileObject("CodeTemplateProcessorFactories") == null) { 618 try { 619 FileObject fo = 620 FileUtil.createData(root, 621 "CodeTemplateProcessorFactories/org-netbeans-modules-retouche-editor-codetemplates-GsfCodeTemplateProcessor$Factory.instance"); 622 } catch (IOException ex) { 623 ErrorManager.getDefault().notify(ex); 624 } 625 } 626 627 } 630 631 } 742 | Popular Tags |