KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > EditorModule


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.editor;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.lang.reflect.Field JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Hashtable JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.logging.Level JavaDoc;
31 import java.util.logging.Logger JavaDoc;
32 import javax.swing.JEditorPane JavaDoc;
33 import javax.swing.SwingUtilities JavaDoc;
34 import javax.swing.text.EditorKit JavaDoc;
35 import javax.swing.text.html.HTMLEditorKit JavaDoc;
36 import javax.swing.text.rtf.RTFEditorKit JavaDoc;
37 import org.netbeans.api.editor.mimelookup.MimeLookup;
38 import org.netbeans.api.editor.mimelookup.MimePath;
39 import org.netbeans.editor.AnnotationType;
40 import org.netbeans.editor.AnnotationTypes;
41 import org.netbeans.editor.BaseKit;
42 import org.netbeans.editor.FindSupport;
43 import org.netbeans.editor.FindSupport.SearchPatternWrapper;
44 import org.netbeans.editor.LocaleSupport;
45 import org.netbeans.editor.Settings;
46 import org.netbeans.modules.editor.options.AllOptions;
47 import org.netbeans.modules.editor.options.AllOptionsFolder;
48 import org.netbeans.modules.editor.options.AnnotationTypesFolder;
49 import org.netbeans.modules.editor.options.BaseOptions;
50 import org.openide.cookies.EditorCookie;
51 import org.openide.modules.ModuleInstall;
52 import org.openide.nodes.Node;
53 import org.openide.text.CloneableEditor;
54 import org.openide.util.Lookup;
55 import org.openide.windows.TopComponent;
56 import org.openidex.search.SearchHistory;
57 import org.openidex.search.SearchPattern;
58
59 /**
60  * Module installation class for editor.
61  *
62  * @author Miloslav Metelka
63  */

64 public class EditorModule extends ModuleInstall {
65
66     private static final Logger JavaDoc LOG = Logger.getLogger(EditorModule.class.getName());
67     
68     private static final boolean debug = Boolean.getBoolean("netbeans.debug.editor.kits");
69
70     private PropertyChangeListener JavaDoc searchSelectedPatternListener;
71     private PropertyChangeListener JavaDoc editorHistoryChangeListener;
72
73     /** Module installed again. */
74     public void restored () {
75         LocaleSupport.addLocalizer(new NbLocalizer(AllOptions.class));
76         LocaleSupport.addLocalizer(new NbLocalizer(BaseKit.class));
77
78         // register loader for annotation types
79
AnnotationTypes.getTypes().registerLoader( new AnnotationTypes.Loader() {
80                 public void loadTypes() {
81                     AnnotationTypesFolder.getAnnotationTypesFolder();
82                 }
83                 public void loadSettings() {
84                     // AnnotationType properties are stored in BaseOption, so let's read them now
85
BaseOptions bo = (BaseOptions)BaseOptions.findObject(BaseOptions.class, true);
86
87                     Integer JavaDoc i = (Integer JavaDoc)bo.getSettingValue(AnnotationTypes.PROP_BACKGROUND_GLYPH_ALPHA);
88                     if (i != null)
89                         AnnotationTypes.getTypes().setBackgroundGlyphAlpha(i.intValue());
90                     Boolean JavaDoc b = (Boolean JavaDoc)bo.getSettingValue(AnnotationTypes.PROP_BACKGROUND_DRAWING);
91                     if (b != null)
92                         AnnotationTypes.getTypes().setBackgroundDrawing(b);
93                     b = (Boolean JavaDoc)bo.getSettingValue(AnnotationTypes.PROP_COMBINE_GLYPHS);
94                     if (b != null)
95                         AnnotationTypes.getTypes().setCombineGlyphs(b);
96                     b = (Boolean JavaDoc)bo.getSettingValue(AnnotationTypes.PROP_GLYPHS_OVER_LINE_NUMBERS);
97                     if (b != null)
98                         AnnotationTypes.getTypes().setGlyphsOverLineNumbers(b);
99                     b = (Boolean JavaDoc)bo.getSettingValue(AnnotationTypes.PROP_SHOW_GLYPH_GUTTER);
100                     if (b != null)
101                         AnnotationTypes.getTypes().setShowGlyphGutter(b);
102                 }
103                 public void saveType(AnnotationType type) {
104                     AnnotationTypesFolder.getAnnotationTypesFolder().saveAnnotationType(type);
105                 }
106                 public void saveSetting(String JavaDoc settingName, Object JavaDoc value) {
107                     // AnnotationType properties are stored to BaseOption
108
BaseOptions bo = (BaseOptions)BaseOptions.findObject(BaseOptions.class, true);
109                     bo.setSettingValue(settingName, value);
110                 }
111             } );
112
113         // ------------------------------------------------------------
114
// Autoregistration
115

116         // First, initialize JDK's editor kit types registry
117
initAndCheckEditorKitTypeRegistry("text/plain", null);
118         initAndCheckEditorKitTypeRegistry("text/html", HTMLEditorKit JavaDoc.class.getName());
119         initAndCheckEditorKitTypeRegistry("text/rtf", RTFEditorKit JavaDoc.class.getName());
120         initAndCheckEditorKitTypeRegistry("application/rtf", RTFEditorKit JavaDoc.class.getName());
121             
122         // Now hook up to the JDK's editor kit registry
123
try {
124             Field JavaDoc keyField = JEditorPane JavaDoc.class.getDeclaredField("kitRegistryKey"); // NOI18N
125
keyField.setAccessible(true);
126             Object JavaDoc key = keyField.get(JEditorPane JavaDoc.class);
127             // XXX this is illegal! Must use reflection and have a proper fallback.
128
Hashtable JavaDoc kitMapping = (Hashtable JavaDoc)sun.awt.AppContext.getAppContext().get(key);
129             sun.awt.AppContext.getAppContext().put(key, new HackMap(kitMapping));
130         } catch (Throwable JavaDoc t) {
131             t.printStackTrace();
132         }
133             
134         // Registration of the editor kits to JEditorPane
135
// for (int i = 0; i < replacements.length; i++) {
136
// JEditorPane.registerEditorKitForContentType(
137
// replacements[i].contentType,
138
// replacements[i].newKitClassName,
139
// getClass().getClassLoader()
140
// );
141
// }
142

143         // ------------------------------------------------------------
144

145          searchSelectedPatternListener = new PropertyChangeListener JavaDoc(){
146              
147              public void propertyChange(PropertyChangeEvent JavaDoc evt){
148                  if (evt == null){
149                      return;
150                  }
151
152                  FindSupport fs = FindSupport.getFindSupport();
153                  if (SearchHistory.LAST_SELECTED.equals(evt.getPropertyName())){
154                      //System.out.println("API -> editor:");
155
SearchPattern sp = SearchHistory.getDefault().getLastSelected();
156                      if (sp==null){
157                          return;
158                      }
159
160                      FindSupport.SearchPatternWrapper spw = new FindSupport.SearchPatternWrapper(sp.getSearchExpression(),
161                              sp.isWholeWords(), sp.isMatchCase(), sp.isRegExp());
162                      //System.out.println("spw:"+spw);
163
fs.setLastSelected(spw);
164                  } else if (SearchHistory.ADD_TO_HISTORY.equals(evt.getPropertyName())){
165                      List JavaDoc searchPatterns = SearchHistory.getDefault().getSearchPatterns();
166
167                      List JavaDoc history = new ArrayList JavaDoc();
168                      for (int i = 0; i<searchPatterns.size(); i++){
169                          SearchPattern sptr = ((SearchPattern)searchPatterns.get(i));
170                          SearchPatternWrapper spwrap = new SearchPatternWrapper(sptr.getSearchExpression(),
171                                  sptr.isWholeWords(), sptr.isMatchCase(), sptr.isRegExp());
172                          history.add(spwrap);
173                      }
174
175                      fs.setHistory(history);
176                  }
177              }
178          };
179          
180          editorHistoryChangeListener = new PropertyChangeListener JavaDoc(){
181              public void propertyChange(PropertyChangeEvent JavaDoc evt){
182                  
183                  if (evt == null || !FindSupport.FIND_HISTORY_PROP.equals(evt.getPropertyName())){
184                      return;
185                  }
186  
187                  //System.out.println("");
188
//System.out.println("editor -> API");
189

190                  SearchPatternWrapper spw = (SearchPatternWrapper)evt.getNewValue();
191                  SearchPattern spLast = SearchHistory.getDefault().getLastSelected();
192                  
193                  if (spw == null || spw.getSearchExpression()==null || "".equals(spw.getSearchExpression()) ){ //NOI18N
194
return;
195                  }
196                  //System.out.println("spw:"+spw);
197

198                  SearchPattern sp = SearchPattern.create(spw.getSearchExpression(),
199                          spw.isWholeWords(), spw.isMatchCase(), spw.isRegExp());
200                  
201                  if (sp == null || (sp.equals(spLast))){
202                      return;
203                  }
204                  
205                  SearchHistory.getDefault().add(sp);
206                  SearchHistory.getDefault().setLastSelected(sp);
207              }
208          };
209  
210          SearchHistory.getDefault().addPropertyChangeListener(searchSelectedPatternListener);
211          FindSupport.getFindSupport().addPropertyChangeListener(editorHistoryChangeListener);
212          
213          // TEMP start
214
/*
215          final int fired[] = new int[1];
216          fired[0] = 0;
217          
218          Timer timer;
219          timer = new Timer(15000, new ActionListener(){
220                  public void actionPerformed(ActionEvent e){
221                     SearchPattern p;
222                      p = SearchPattern.create(String.valueOf(fired[0]),false,false,false);
223                      SearchHistory.getDefault().add(p);
224                      SearchHistory.getDefault().setLastSelected(p);
225                      fired[0] ++;
226                  }
227          });
228          timer.start();
229          */

230          //TEMP end
231

232             
233     }
234
235     /** Called when module is uninstalled. Overrides superclass method. */
236     public void uninstalled() {
237
238         AllOptionsFolder.unregisterModuleRegListener();
239
240         /* [TEMP]
241         if (searchSelectedPatternListener!=null){
242             SearchHistory.getDefault().removePropertyChangeListener(searchSelectedPatternListener);
243         }
244         */

245          
246         // unregister our registry
247
try {
248             Field JavaDoc keyField = JEditorPane JavaDoc.class.getDeclaredField("kitRegistryKey"); // NOI18N
249
keyField.setAccessible(true);
250             Object JavaDoc key = keyField.get(JEditorPane JavaDoc.class);
251             HackMap kitMapping = (HackMap)sun.awt.AppContext.getAppContext().get(key);
252             if (kitMapping.getOriginal() != null) {
253                 sun.awt.AppContext.getAppContext().put(key, kitMapping.getOriginal());
254             } else {
255                 sun.awt.AppContext.getAppContext().remove(key);
256             }
257
258         } catch (Throwable JavaDoc t) {
259             t.printStackTrace();
260         }
261
262         // #42970 - Possible closing of opened editor top components must happen in AWT thread
263
SwingUtilities.invokeLater(new Runnable JavaDoc() {
264             public void run() {
265
266                 // issue #16110
267
// close all TopComponents which contain editor based on BaseKit
268
HashSet JavaDoc set = new HashSet JavaDoc();
269                 set.addAll(TopComponent.getRegistry().getOpened());
270
271                 for (Iterator JavaDoc it = set.iterator(); it.hasNext(); ) {
272                     TopComponent topComp = (TopComponent)it.next();
273                     // top components in which we are interested must be of type CloneableEditor
274
if (!(topComp instanceof CloneableEditor))
275                         continue;
276                     Node[] arr = topComp.getActivatedNodes();
277                     if (arr == null)
278                         continue;
279                     for (int i=0; i<arr.length; i++) {
280                         EditorCookie ec = (EditorCookie)arr[i].getCookie(EditorCookie.class);
281                         if (ec == null)
282                             continue;
283                         JEditorPane JavaDoc[] pane = ec.getOpenedPanes();
284                         if (pane == null)
285                             continue;
286                         for (int j=0; j<pane.length; j++) {
287                             if (pane[j].getEditorKit() instanceof BaseKit) {
288                                 topComp.close();
289                             }
290                         }
291                     }
292                 }
293
294             }
295         });
296     }
297
298     
299     private static class HackMap extends Hashtable JavaDoc {
300         
301     private Hashtable JavaDoc delegate;
302
303         HackMap(Hashtable JavaDoc h) {
304             delegate = h;
305             
306             if (debug) {
307                 LOG.log(Level.INFO, "Original kit mappings: " + h); //NOI18N
308

309                 try {
310                     Field JavaDoc keyField = JEditorPane JavaDoc.class.getDeclaredField("kitTypeRegistryKey"); // NOI18N
311
keyField.setAccessible(true);
312                     Object JavaDoc key = keyField.get(JEditorPane JavaDoc.class);
313                     Hashtable JavaDoc kitTypeMapping = (Hashtable JavaDoc)sun.awt.AppContext.getAppContext().get(key);
314                     if (kitTypeMapping != null) {
315                         sun.awt.AppContext.getAppContext().put(key, new DebugHashtable(kitTypeMapping));
316                     }
317                 } catch (Throwable JavaDoc t) {
318                     t.printStackTrace();
319                 }
320             }
321         }
322
323         private String JavaDoc getKitClassName(String JavaDoc type) {
324             try {
325                 Field JavaDoc keyField = JEditorPane JavaDoc.class.getDeclaredField("kitTypeRegistryKey"); // NOI18N
326
keyField.setAccessible(true);
327                 Object JavaDoc key = keyField.get(JEditorPane JavaDoc.class);
328                 Hashtable JavaDoc kitTypeMapping = (Hashtable JavaDoc)sun.awt.AppContext.getAppContext().get(key);
329                 if (kitTypeMapping != null) {
330                     return (String JavaDoc)kitTypeMapping.get(type);
331                 }
332             } catch (Throwable JavaDoc t) {
333                 t.printStackTrace();
334             }
335             
336             return null;
337         }
338         
339         public Object JavaDoc get(Object JavaDoc key) {
340             synchronized (Settings.class) {
341             if (debug) LOG.log(Level.INFO, "HackMap.get key=" + key); //NOI18N
342

343             Object JavaDoc retVal = null;
344             
345             if (delegate != null) {
346                 retVal = delegate.get(key);
347                 if (debug && retVal != null) {
348                     LOG.log(Level.INFO, "Found cached instance kit=" + retVal + " for mimeType=" + key); //NOI18N
349
}
350             }
351
352             if (key instanceof String JavaDoc) {
353                 String JavaDoc mimeType = (String JavaDoc) key;
354                 if (retVal == null || shouldUseNbKit(retVal.getClass().getName(), mimeType)) {
355                     // first check the type registry
356
String JavaDoc kitClassName = getKitClassName(mimeType);
357                     if (debug) {
358                         LOG.log(Level.INFO, "Found kitClassName=" + kitClassName + " for mimeType=" + mimeType); //NOI18N
359
}
360
361                     if (kitClassName == null || shouldUseNbKit(kitClassName, mimeType)) {
362                         Object JavaDoc kit = findKit(mimeType);
363                         if (kit != null) {
364                             retVal = kit;
365                             if (debug) {
366                                 LOG.log(Level.INFO, "Found kit=" + retVal + " in xml layers for mimeType=" + mimeType); //NOI18N
367
}
368                         }
369                     }
370                 }
371             }
372             
373             return retVal;
374             } // synchronized (Settings.class)
375
}
376         
377         public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
378             synchronized (Settings.class) {
379             if (debug) LOG.log(Level.INFO, "HackMap.put key=" + key + " value=" + value); //NOI18N
380

381             if (delegate == null) {
382                 delegate = new Hashtable JavaDoc();
383             }
384
385             Object JavaDoc ret = delegate.put(key,value);
386             
387             if (debug) {
388                 LOG.log(Level.INFO, "registering mimeType=" + key //NOI18N
389
+ " -> kitInstance=" + value // NOI18N
390
+ " original was " + ret); // NOI18N
391
}
392              
393             return ret;
394             } // synchronized (Settings.class)
395
}
396
397         public Object JavaDoc remove(Object JavaDoc key) {
398             synchronized (Settings.class) {
399             if (debug) LOG.log(Level.INFO, "HackMap.remove key=" + key); //NOI18N
400

401             Object JavaDoc ret = (delegate != null) ? delegate.remove(key) : null;
402             
403             if (debug) {
404                 LOG.log(Level.INFO, "removing kitInstance=" + ret //NOI18N
405
+ " for mimeType=" + key); // NOI18N
406
}
407             
408             return ret;
409             } // synchronized (Settings.class)
410
}
411         
412         Hashtable JavaDoc getOriginal() {
413             return delegate;
414         }
415
416         private boolean shouldUseNbKit(String JavaDoc kitClass, String JavaDoc mimeType) {
417             if (mimeType.startsWith("text/html") || //NOI18N
418
mimeType.startsWith("text/rtf") || //NOI18N
419
mimeType.startsWith("application/rtf")) //NOI18N
420
{
421                 return false;
422             } else {
423                 return kitClass.startsWith("javax.swing."); //NOI18N
424
}
425         }
426
427         // Don't use CloneableEditorSupport.getEditorKit so that it can safely
428
// fallback to JEP.createEKForCT if it doesn't find Netbeans kit.
429
private EditorKit JavaDoc findKit(String JavaDoc mimeType) {
430             Lookup lookup = MimeLookup.getLookup(MimePath.parse(mimeType));
431             EditorKit JavaDoc kit = (EditorKit JavaDoc) lookup.lookup(EditorKit JavaDoc.class);
432             return kit == null ? null : (EditorKit JavaDoc) kit.clone();
433         }
434     }
435     
436     private static final class DebugHashtable extends Hashtable JavaDoc {
437         
438         DebugHashtable(Hashtable JavaDoc h) {
439             if (h != null) {
440                 putAll(h);
441                 LOG.log(Level.INFO, "Existing kit classNames mappings: " + this); //NOI18N
442
}
443         }
444         
445         public Object JavaDoc put(Object JavaDoc key, Object JavaDoc value) {
446             Object JavaDoc ret = super.put(key, value);
447             LOG.log(Level.INFO, "registering mimeType=" + key //NOI18N
448
+ " -> kitClassName=" + value // NOI18N
449
+ " original was " + ret); // NOI18N
450
return ret;
451         }
452         
453         public Object JavaDoc remove(Object JavaDoc key) {
454             Object JavaDoc ret = super.remove(key);
455             LOG.log(Level.INFO, "removing kitClassName=" + ret //NOI18N
456
+ " for mimeType=" + key); // NOI18N
457
return ret;
458         }
459         
460     }
461
462     private void initAndCheckEditorKitTypeRegistry(String JavaDoc mimeType, String JavaDoc expectedKitClass) {
463         String JavaDoc kitClass = JEditorPane.getEditorKitClassNameForContentType(mimeType);
464         if (kitClass == null) {
465             LOG.log(Level.WARNING, "Can't find JDK editor kit class for " + mimeType); //NOI18N
466
} else if (expectedKitClass != null && !expectedKitClass.equals(kitClass)) {
467             LOG.log(Level.WARNING, "Wrong JDK editor kit class for " + mimeType + //NOI18N
468
". Expecting: " + expectedKitClass + //NOI18N
469
", but was: " + kitClass); //NOI18N
470
}
471     }
472 }
473
Popular Tags