KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > languages > LanguagesManagerImpl


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.languages;
21
22 import java.io.IOException JavaDoc;
23 import org.netbeans.modules.languages.features.ActionCreator;
24 import org.netbeans.api.languages.LanguagesManager;
25 import org.netbeans.api.languages.ParseException;
26 import java.beans.PropertyChangeEvent JavaDoc;
27 import java.beans.PropertyChangeListener JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import org.netbeans.modules.languages.parser.LanguageDefinitionNotFoundException;
31 import org.netbeans.api.languages.ParseException;
32 import org.openide.ErrorManager;
33 import org.openide.filesystems.FileAttributeEvent;
34 import org.openide.filesystems.FileChangeListener;
35 import org.openide.filesystems.FileEvent;
36 import org.openide.filesystems.FileObject;
37 import org.openide.filesystems.FileRenameEvent;
38 import org.openide.filesystems.FileSystem;
39 import org.openide.filesystems.FileSystem.AtomicAction;
40 import org.openide.filesystems.FileUtil;
41 import org.openide.filesystems.Repository;
42 import java.io.IOException JavaDoc;
43 import java.io.InputStream JavaDoc;
44 import java.util.Collections JavaDoc;
45 import java.util.Enumeration JavaDoc;
46 import java.util.HashMap JavaDoc;
47 import java.util.Iterator JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.Map JavaDoc;
50 import java.util.Set JavaDoc;
51 import java.util.Vector JavaDoc;
52 import org.netbeans.modules.languages.features.ColorsManager;
53 import org.openide.modules.ModuleInfo;
54 import org.openide.util.Lookup;
55 import org.openide.util.LookupEvent;
56 import org.openide.util.LookupListener;
57
58
59 /**
60  *
61  * @author Jan Jancura
62  */

63 public class LanguagesManagerImpl extends LanguagesManager {
64     
65     
66     public static LanguagesManagerImpl get () {
67         return (LanguagesManagerImpl) LanguagesManager.getDefault ();
68     }
69     
70     
71     private Lookup.Result<ModuleInfo> result;
72     private LookupListener lookupListener;
73     private PropertyChangeListener JavaDoc moduleInfoListener;
74     private Set JavaDoc<ModuleInfo> moduleInfos;
75
76     
77     public LanguagesManagerImpl () {
78         result = Lookup.getDefault ().<ModuleInfo>lookupResult (ModuleInfo.class);
79         lookupListener = new LookupListener () {
80             public void resultChanged (LookupEvent ev) {
81                 Set JavaDoc<ModuleInfo> newModules = new HashSet JavaDoc<ModuleInfo> (result.allInstances ());
82                 newModules.removeAll (moduleInfos);
83                 Iterator JavaDoc<ModuleInfo> it = newModules.iterator ();
84                 while (it.hasNext ())
85                     it.next ().addPropertyChangeListener (moduleInfoListener);
86                 Set JavaDoc<ModuleInfo> oldModules = new HashSet JavaDoc<ModuleInfo> (moduleInfos);
87                 oldModules.removeAll (result.allInstances ());
88                 it = oldModules.iterator ();
89                 while (it.hasNext ())
90                     it.next ().removePropertyChangeListener (moduleInfoListener);
91                 moduleInfos = new HashSet JavaDoc<ModuleInfo> (result.allInstances ());
92                 refreshSupportedMimeTypes ();
93             }
94         };
95         result.addLookupListener (lookupListener);
96         moduleInfoListener = new PropertyChangeListener JavaDoc() {
97             public void propertyChange (PropertyChangeEvent JavaDoc a) {
98                 refreshSupportedMimeTypes ();
99             }
100         };
101         moduleInfos = new HashSet JavaDoc<ModuleInfo> (result.allInstances ());
102         Iterator JavaDoc<ModuleInfo> it = moduleInfos.iterator ();
103         while (it.hasNext ()) {
104             ModuleInfo info = it.next ();
105             info.addPropertyChangeListener (moduleInfoListener);
106         }
107     }
108     
109     private Set JavaDoc<String JavaDoc> mimeTypes = null;
110     
111     public Set JavaDoc<String JavaDoc> getSupportedMimeTypes () {
112         if (mimeTypes == null)
113             mimeTypes = loadMimeTypes ();
114         return Collections.<String JavaDoc>unmodifiableSet (mimeTypes);
115     }
116     
117 //
118
// private Map mimeTypeToName = new HashMap ();
119
//
120
// public String getLanguageName (String mimeType) {
121
// if (!mimeTypeToName.containsKey (mimeType)) {
122
// FileSystem fs = Repository.getDefault ().getDefaultFileSystem ();
123
// FileObject fo = fs.findResource ("Editors/" + mimeType);
124
// if (fo == null) return "???";
125
// String bundleName = (String) fo.getAttribute ("SystemFileSystem.localizingBundle");
126
// String name = mimeType;
127
// if (bundleName != null)
128
// try {
129
// name = NbBundle.getBundle (bundleName).getString (mimeType);
130
// } catch (MissingResourceException ex) {}
131
// mimeTypeToName.put (mimeType, name);
132
// }
133
// return (String) mimeTypeToName.get (mimeType);
134
// }
135

136     private Map JavaDoc<String JavaDoc,Object JavaDoc> mimeTypeToLanguage = new HashMap JavaDoc<String JavaDoc,Object JavaDoc> ();
137     
138     public synchronized Language getLanguage (String JavaDoc mimeType)
139     throws ParseException {
140         if (!mimeTypeToLanguage.containsKey (mimeType)) {
141             mimeTypeToLanguage.put (mimeType, new ParseException ("Already parisng " + mimeType));
142             try {
143                 FileSystem fs = Repository.getDefault ().getDefaultFileSystem ();
144                 FileObject fo = fs.findResource ("Editors/" + mimeType + "/language.nbs");
145                 if (fo == null)
146                     throw new LanguageDefinitionNotFoundException
147                         ("Language definition for " + mimeType + " not found.");
148                 addListener (fo);
149                 Language l = NBSLanguageReader.readLanguage (fo, mimeType);
150                 initLanguage (l);
151                 //l.print ();
152
mimeTypeToLanguage.put (mimeType, l);
153             } catch (ParseException ex) {
154                 mimeTypeToLanguage.put (mimeType, ex);
155                 throw ex;
156             } catch (Exception JavaDoc ex) {
157                 ParseException pe = new ParseException (ex);
158                 mimeTypeToLanguage.put (mimeType, pe);
159                 throw pe;
160             }
161         }
162         if (mimeTypeToLanguage.get (mimeType) instanceof ParseException)
163             throw (ParseException) mimeTypeToLanguage.get (mimeType);
164         return (Language) mimeTypeToLanguage.get (mimeType);
165     }
166     
167     private Vector JavaDoc<LanguagesManagerListener> listeners = new Vector JavaDoc<LanguagesManagerListener> ();
168     
169     public void addLanguagesManagerListener (LanguagesManagerListener l) {
170         listeners.add (l);
171     }
172     
173     public void removeLanguagesManagerListener (LanguagesManagerListener l) {
174         listeners.remove (l);
175     }
176
177     
178     // helper methods .....................................................................................................
179

180     private void refreshSupportedMimeTypes () {
181         Set JavaDoc<String JavaDoc> mimeTypes = loadMimeTypes ();
182         if (mimeTypes.equals (this.mimeTypes))
183             return;
184         Set JavaDoc<String JavaDoc> added = new HashSet JavaDoc<String JavaDoc> (mimeTypes);
185         added.removeAll (this.mimeTypes);
186         Set JavaDoc<String JavaDoc> removed = new HashSet JavaDoc<String JavaDoc> (this.mimeTypes);
187         removed.removeAll (mimeTypes);
188         Iterator JavaDoc<String JavaDoc> it = removed.iterator ();
189         while (it.hasNext ()) {
190             String JavaDoc mimeType = it.next ();
191             this.mimeTypes.remove (mimeType);
192             fireLanguageRemoved (mimeType);
193         }
194         it = added.iterator ();
195         while (it.hasNext ()) {
196             String JavaDoc mimeType = it.next ();
197             this.mimeTypes.add (mimeType);
198             fireLanguageAdded (mimeType);
199         }
200     }
201     
202     private void languageChanged (String JavaDoc mimeType) {
203         mimeTypeToLanguage.remove (mimeType);
204         Vector JavaDoc<LanguagesManagerListener> v = (Vector JavaDoc<LanguagesManagerListener>) listeners.clone ();
205         Iterator JavaDoc<LanguagesManagerListener> it = v.iterator ();
206         while (it.hasNext ()) {
207             LanguagesManagerListener l = it.next ();
208             l.languageChanged (mimeType);
209         }
210     }
211     
212     private void fireLanguageAdded (String JavaDoc mimeType) {
213         Vector JavaDoc<LanguagesManagerListener> v = (Vector JavaDoc<LanguagesManagerListener>) listeners.clone ();
214         Iterator JavaDoc<LanguagesManagerListener> it = v.iterator ();
215         while (it.hasNext ()) {
216             LanguagesManagerListener l = it.next ();
217             l.languageAdded (mimeType);
218         }
219     }
220     
221     private void fireLanguageRemoved (String JavaDoc mimeType) {
222         Vector JavaDoc<LanguagesManagerListener> v = (Vector JavaDoc<LanguagesManagerListener>) listeners.clone ();
223         Iterator JavaDoc<LanguagesManagerListener> it = v.iterator ();
224         while (it.hasNext ()) {
225             LanguagesManagerListener l = it.next ();
226             l.languageRemoved (mimeType);
227         }
228     }
229
230     private Set JavaDoc<FileObject> listeningOn = new HashSet JavaDoc<FileObject> ();
231     private Listener JavaDoc listener;
232     
233     private void addListener (FileObject fo) {
234         if (!listeningOn.contains (fo)) {
235             if (listener == null)
236                 listener = new Listener JavaDoc ();
237             fo.addFileChangeListener (listener);
238             listeningOn.add (fo);
239         }
240     }
241     
242     private void initLanguage (Language l) {
243         try {
244             
245             FileSystem fs = Repository.getDefault ().getDefaultFileSystem ();
246             final FileObject root = fs.findResource ("Editors/" + l.getMimeType ());
247
248             // init old options
249
if (root.getFileObject ("Settings.settings") == null)
250                 fs.runAtomicAction (new AtomicAction () {
251                     public void run () {
252                         try {
253                             InputStream JavaDoc is = getClass().getClassLoader().getResourceAsStream("org/netbeans/modules/languages/resources/LanguagesOptions.settings");
254                             try {
255                                 FileObject fo = root.createData("Settings.settings");
256                                 OutputStream JavaDoc os = fo.getOutputStream();
257                                 try {
258                                     FileUtil.copy(is, os);
259     // System.out.println("@@@ Successfully created " + fo.getPath());
260
} finally {
261                                     os.close();
262                                 }
263                             } finally {
264                                 is.close();
265                             }
266                         } catch (IOException JavaDoc ex) {
267                             ErrorManager.getDefault ().notify (ex);
268                         }
269                     }
270                 });
271
272             // init code folding bar
273
if (root.getFileObject ("SideBar/org-netbeans-modules-languages-features-CodeFoldingSideBarFactory.instance") == null
274                 //l.supportsCodeFolding () does not work if you first open language without folding than no languages will have foding.
275
) {
276                 FileUtil.createData (root, "FoldManager/org-netbeans-modules-languages-features-LanguagesFoldManager$Factory.instance");
277                 FileUtil.createData (root, "SideBar/org-netbeans-modules-languages-features-CodeFoldingSideBarFactory.instance");
278                 FileObject fo = root.getFileObject ("SideBar");
279                 fo.setAttribute ("org-netbeans-editor-GlyphGutter.instance/org-netbeans-modules-languages-features-CodeFoldingSideBarFactory.instance", Boolean.TRUE);
280             }
281
282             // init error stripe
283
if (root.getFileObject ("UpToDateStatusProvider/org-netbeans-modules-languages-features-UpToDateStatusProviderFactoryImpl.instance") == null
284                 //l.supportsCodeFolding () does not work if you first open language without folding than no languages will have foding.
285
)
286                 FileUtil.createData (root, "UpToDateStatusProvider/org-netbeans-modules-languages-features-UpToDateStatusProviderFactoryImpl.instance");
287
288                 
289             initPopupMenu (root, l);
290
291             // init navigator
292
if (l.getFeatures ("NAVIGATOR") != null) {
293                 String JavaDoc foldFileName = "Navigator/Panels/" + l.getMimeType () +
294                     "/org-netbeans-modules-languages-features-LanguagesNavigator.instance";
295                 if (fs.findResource (foldFileName) == null)
296                     FileUtil.createData (fs.getRoot (), foldFileName);
297             }
298
299             // init tooltips
300
if (l.getFeatures ("TOOLTIP") != null)
301                 FileUtil.createData (root, "ToolTips/org-netbeans-modules-languages-features-ToolTipAnnotation.instance");
302
303             } catch (IOException JavaDoc ex) {
304                 ErrorManager.getDefault ().notify (ex);
305             }
306         
307         // init coloring
308
ColorsManager.initColorings (l);
309     }
310
311     private static void initPopupMenu (FileObject root, Language l) throws IOException JavaDoc {
312             FileObject popup = FileUtil.createFolder (root, "Popup");
313             createSeparator (popup, "SeparatorAfterSelectInPopupAction", "org-netbeans-modules-editor-NbSelectInPopupAction.instance", null);
314             List JavaDoc<Feature> actions = l.getFeatures ("ACTION");
315             String JavaDoc lastAction = "SeparatorAfterSelectInPopupAction.instance";
316             Iterator JavaDoc<Feature> it = actions.iterator ();
317             while (it.hasNext ()) {
318                 Feature action = it.next ();
319                 if (action.getBoolean ("explorer", false))
320                     continue;
321                 String JavaDoc name = action.getSelector ().getAsString ();
322                 String JavaDoc displayName= (String JavaDoc) action.getValue ("name");
323                 String JavaDoc performer = action.getMethodName ("performer");
324                 String JavaDoc enabler = action.getMethodName ("enabled");
325                 String JavaDoc installAfter = (String JavaDoc) action.getValue ("install_after");
326                 String JavaDoc installBefore = (String JavaDoc) action.getValue ("install_before");
327                 boolean separatorBefore = action.getBoolean ("separator_before", false);
328                 boolean separatorAfter = action.getBoolean ("separator_after", false);
329                 FileObject fobj = FileUtil.createData (popup, name + ".instance"); // NOI18N
330
fobj.setAttribute("instanceCreate", new ActionCreator (new Object JavaDoc[] {displayName, performer, enabler})); // NOI18N
331
fobj.setAttribute("instanceClass", "org.netbeans.modules.languages.features.GenericAction"); // NOI18N
332
if (separatorBefore) {
333                     createSeparator (popup, name + "_separator_before", installBefore, name + ".instance");
334                     popup.setAttribute (name + "_separator_before/" + name + ".instance", Boolean.TRUE);
335                 } else
336                 if (installBefore != null)
337                     popup.setAttribute (installBefore + "/" + name + ".instance", Boolean.TRUE);
338                 else
339                 popup.setAttribute (lastAction + "/" + name + ".instance", Boolean.TRUE);
340                 if (separatorAfter) {
341                     createSeparator (popup, name + "_separator_after", installAfter, name + ".instance");
342                     popup.setAttribute (name + "_separator_after/" + name + ".instance", Boolean.TRUE);
343                 } else
344                 if (installAfter != null)
345                     popup.setAttribute (installAfter + "/" + name + ".instance", Boolean.TRUE);
346                 if (installAfter == null && installBefore == null)
347                     lastAction = name + ".instance";
348             }
349             popup.setAttribute (lastAction + "/org-netbeans-modules-languages-features-FormatAction.instance", Boolean.TRUE);
350             FileUtil.createData (popup, "org-netbeans-modules-languages-features-FormatAction.instance");
351             createSeparator (popup, "SeparatorBeforeCut", "org-netbeans-modules-languages-features-FormatAction.instance", "org-openide-actions-CutAction.instance");
352             createSeparator (popup, "SeparatorAfterPaste", "org-openide-actions-PasteAction.instance", "generate-fold-popup");
353             FileUtil.createData (popup, "generate-fold-popup");
354             // init actions
355
}
356     
357     private String JavaDoc spacesToDashes(String JavaDoc text) {
358         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
359         int length = text.length();
360         for (int x = 0; x < length; x++) {
361             char c = text.charAt(x);
362             buf.append(Character.isWhitespace(c) ? '_' : c);
363         }
364         return buf.toString();
365     }
366     
367     static Set JavaDoc<String JavaDoc> loadMimeTypes () {
368         Set JavaDoc<String JavaDoc> result = new HashSet JavaDoc<String JavaDoc> ();
369         FileSystem fs = Repository.getDefault ().getDefaultFileSystem ();
370         FileObject root = fs.findResource ("Editors");
371         Enumeration JavaDoc e1 = root.getChildren (false);
372         while (e1.hasMoreElements ()) {
373             FileObject f1 = (FileObject) e1.nextElement ();
374             if (f1.isData ()) continue;
375             Enumeration JavaDoc e2 = f1.getChildren (false);
376             while (e2.hasMoreElements ()) {
377                 FileObject f2 = (FileObject) e2.nextElement ();
378                 if (f2.isData ()) continue;
379                 FileObject fo = f2.getFileObject ("language.nbs");
380                 if (fo == null) continue;
381                 result.add (f1.getName () + '/' + f2.getName ());
382             }
383         }
384         return result;
385     }
386
387     private static void createSeparator (
388         FileObject folder,
389         String JavaDoc name,
390         String JavaDoc after,
391         String JavaDoc before
392     ) throws IOException JavaDoc {
393         name += ".instance";
394         FileObject separator = FileUtil.createData (folder, name);
395         separator.setAttribute ("instanceClass", "javax.swing.JSeparator");
396         if (after != null)
397             folder.setAttribute (after + "/" + name, Boolean.TRUE);
398         if (before != null)
399             folder.setAttribute (name + "/" + before, Boolean.TRUE);
400     }
401     
402     
403     // innerclasses ............................................................
404

405     public static interface LanguagesManagerListener {
406         
407         public void languageAdded (String JavaDoc mimeType);
408         public void languageRemoved (String JavaDoc mimeType);
409         public void languageChanged (String JavaDoc mimeType);
410     }
411     
412     private class Listener implements FileChangeListener {
413         
414         public void fileAttributeChanged (FileAttributeEvent fe) {
415         }
416         public void fileChanged (FileEvent fe) {
417             FileObject fo = fe.getFile ();
418             String JavaDoc mimeType = fo.getParent ().getParent ().getName () +
419                 '/' + fo.getParent ().getName ();
420             languageChanged (mimeType);
421         }
422         public void fileDataCreated (FileEvent fe) {
423         }
424         public void fileDeleted (FileEvent fe) {
425             FileObject fo = fe.getFile ();
426             String JavaDoc mimeType = fo.getParent ().getName ();
427             languageChanged (mimeType);
428         }
429         public void fileFolderCreated (FileEvent fe) {
430         }
431         public void fileRenamed (FileRenameEvent fe) {
432         }
433     }
434 }
435
436
437
438
Popular Tags