KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > settings > storage > SettingsProvider


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.settings.storage;
21
22 import java.beans.PropertyChangeEvent JavaDoc;
23 import java.beans.PropertyChangeListener JavaDoc;
24 import java.lang.ref.WeakReference JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.WeakHashMap JavaDoc;
31 import java.util.logging.Level JavaDoc;
32 import java.util.logging.Logger JavaDoc;
33 import org.netbeans.api.editor.mimelookup.MimeLookup;
34 import org.netbeans.api.editor.mimelookup.MimePath;
35 import org.netbeans.api.editor.settings.FontColorSettings;
36 import org.netbeans.api.editor.settings.KeyBindingSettings;
37 import org.netbeans.modules.editor.settings.storage.api.EditorSettings;
38 import org.netbeans.spi.editor.mimelookup.MimeDataProvider;
39 import org.openide.util.Lookup;
40 import org.openide.util.WeakListeners;
41 import org.openide.util.lookup.AbstractLookup;
42 import org.openide.util.lookup.InstanceContent;
43 import org.openide.util.lookup.Lookups;
44 import org.openide.util.lookup.ProxyLookup;
45
46 /**
47  *
48  * @author Jan Jancura
49  */

50 public final class SettingsProvider implements MimeDataProvider {
51
52     private static final Logger JavaDoc LOG = Logger.getLogger(SettingsProvider.class.getName());
53     
54     private final Map JavaDoc<MimePath, WeakReference JavaDoc<Lookup>> cache = new WeakHashMap JavaDoc<MimePath, WeakReference JavaDoc<Lookup>>();
55     
56     public SettingsProvider () {
57     }
58     
59     /**
60      * Lookup providing mime-type sensitive or global-level data
61      * depending on which level this initializer is defined.
62      *
63      * @return Lookup or null, if there are no lookup-able objects for mime or global level.
64      */

65     public Lookup getLookup(MimePath mimePath) {
66         synchronized (cache) {
67             WeakReference JavaDoc<Lookup> ref = cache.get(mimePath);
68             Lookup lookup = ref == null ? null : ref.get();
69             
70             if (lookup == null) {
71                 String JavaDoc path = mimePath.getPath();
72                 if (path.startsWith("test")) { //NOI18N
73
int idx = path.indexOf('_'); //NOI18N
74
if (idx == -1) {
75                         throw new IllegalStateException JavaDoc("Invalid mimePath: " + path); //NOI18N
76
}
77                     
78                     // Get the special test profile name and the real mime path
79
String JavaDoc profile = path.substring(0, idx);
80                     MimePath realMimePath = MimePath.parse(path.substring(idx + 1));
81                     
82                     lookup = new ProxyLookup(new Lookup [] {
83                         new MyLookup(realMimePath, profile),
84                         Lookups.exclude(
85                             MimeLookup.getLookup(realMimePath),
86                             new Class JavaDoc [] {
87                                 FontColorSettings.class,
88                                 KeyBindingSettings.class
89                             })
90                     });
91                 } else {
92                     lookup = new MyLookup(mimePath, null);
93                 }
94                 
95                 cache.put(mimePath, new WeakReference JavaDoc<Lookup>(lookup));
96             }
97             
98             return lookup;
99         }
100     }
101     
102     private static final class MyLookup extends AbstractLookup implements PropertyChangeListener JavaDoc {
103         
104         private final MimePath mimePath;
105         private final MimePath [] allMimePaths;
106         private final boolean specialFcsProfile;
107         private String JavaDoc fcsProfile;
108         
109         private final InstanceContent ic;
110         private Object JavaDoc fontColorSettings = null;
111         private Object JavaDoc keyBindingSettings = null;
112         
113         private KeyBindingSettingsImpl kbsi;
114         
115         public MyLookup(MimePath mimePath, String JavaDoc profile) {
116             this(mimePath, profile, new InstanceContent());
117         }
118         
119         private MyLookup(MimePath mimePath, String JavaDoc profile, InstanceContent ic) {
120             super(ic);
121
122             this.mimePath = mimePath;
123             this.allMimePaths = computeInheritedMimePaths(mimePath);
124             
125             if (profile == null) {
126                 // Use the selected current profile
127
String JavaDoc currentProfile = EditorSettings.getDefault().getCurrentFontColorProfile();
128                 this.fcsProfile = EditorSettingsImpl.getInstance().getInternalFontColorProfile(currentProfile);
129                 this.specialFcsProfile = false;
130             } else {
131                 // This is the special test profile derived from the mime path.
132
// It will never change.
133
this.fcsProfile = profile;
134                 this.specialFcsProfile = true;
135             }
136             
137             this.ic = ic;
138             
139             // Start listening
140
EditorSettings es = EditorSettings.getDefault();
141             es.addPropertyChangeListener(WeakListeners.propertyChange(this, es));
142             
143             this.kbsi = KeyBindingSettingsImpl.get(mimePath);
144             this.kbsi.addPropertyChangeListener(WeakListeners.propertyChange(this, this.kbsi));
145         }
146
147         protected void initialize() {
148             synchronized (this) {
149                 fontColorSettings = new CompositeFCS(allMimePaths, fcsProfile);
150                 keyBindingSettings = this.kbsi.createInstanceForLookup();
151
152                 ic.set(Arrays.asList(new Object JavaDoc [] {
153                     fontColorSettings,
154                     keyBindingSettings
155                 }), null);
156             }
157         }
158         
159         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
160             synchronized (this) {
161                 boolean fcsChanged = false;
162                 boolean kbsChanged = false;
163
164 // if (mimePath.getPath().contains("xml")) {
165
// System.out.println("@@@ propertyChange: mimePath = " + mimePath.getPath() + " profile = " + fcsProfile + " property = " + evt.getPropertyName() + " oldValue = " + (evt.getOldValue() instanceof MimePath ? ((MimePath) evt.getOldValue()).getPath() : evt.getOldValue()) + " newValue = " + evt.getNewValue());
166
// }
167

168                 // Determine what has changed
169
if (this.kbsi == evt.getSource()) {
170                     kbsChanged = true;
171                     
172                 } else if (evt.getPropertyName() == null) {
173                     // reset all
174
if (!specialFcsProfile) {
175                         String JavaDoc currentProfile = EditorSettings.getDefault().getCurrentFontColorProfile();
176                         fcsProfile = EditorSettingsImpl.getInstance().getInternalFontColorProfile(currentProfile);
177                     }
178                     fcsChanged = true;
179                     
180                 } else if (evt.getPropertyName().equals(EditorSettingsImpl.PROP_HIGHLIGHT_COLORINGS)) {
181                     String JavaDoc changedProfile = (String JavaDoc) evt.getNewValue();
182                     if (changedProfile.equals(fcsProfile)) {
183                         fcsChanged = true;
184                     }
185                     
186                 } else if (evt.getPropertyName().equals(EditorSettingsImpl.PROP_TOKEN_COLORINGS)) {
187                     String JavaDoc changedProfile = (String JavaDoc) evt.getNewValue();
188                     if (changedProfile.equals(fcsProfile)) {
189                         MimePath changedMimePath = (MimePath) evt.getOldValue();
190                         if (isDerivedFromMimePath(changedMimePath)) {
191                             fcsChanged = true;
192                         }
193                     }
194                     
195                 } else if (evt.getPropertyName().equals(EditorSettingsImpl.PROP_CURRENT_FONT_COLOR_PROFILE)) {
196                     if (!specialFcsProfile) {
197                         String JavaDoc newProfile = (String JavaDoc) evt.getNewValue();
198                         fcsProfile = EditorSettingsImpl.getInstance().getInternalFontColorProfile(newProfile);
199                         fcsChanged = true;
200                     }
201                 }
202                 
203                 // Update lookup contents
204
boolean updateContents = false;
205                 
206                 if (fcsChanged && fontColorSettings != null) {
207                     fontColorSettings = new CompositeFCS(allMimePaths, fcsProfile);
208                     updateContents = true;
209                 }
210                 
211                 if (kbsChanged && keyBindingSettings != null) {
212                     keyBindingSettings = this.kbsi.createInstanceForLookup();
213                     updateContents = true;
214                 }
215                 
216                 if (updateContents) {
217                     ic.set(Arrays.asList(new Object JavaDoc [] {
218                         fontColorSettings,
219                         keyBindingSettings
220                     }), null);
221                 }
222             }
223         }
224
225         private boolean isDerivedFromMimePath(MimePath mimePath) {
226             for(MimePath mp : allMimePaths) {
227                 if (mp == mimePath) {
228                     return true;
229                 }
230             }
231             return false;
232         }
233         
234         private static MimePath [] computeInheritedMimePaths(MimePath mimePath) {
235             List JavaDoc<String JavaDoc> paths = callSwitchLookupComputePaths(mimePath);
236
237             if (paths != null) {
238                 ArrayList JavaDoc<MimePath> mimePaths = new ArrayList JavaDoc<MimePath>(paths.size());
239
240                 for (String JavaDoc path : paths) {
241                     mimePaths.add(MimePath.parse(path));
242                 }
243
244                 return mimePaths.toArray(new MimePath[mimePaths.size()]);
245             } else {
246                 return new MimePath [] { mimePath, MimePath.EMPTY };
247             }
248         }
249
250         @SuppressWarnings JavaDoc("unchecked")
251         private static List JavaDoc<String JavaDoc> callSwitchLookupComputePaths(MimePath mimePath) {
252             try {
253                 ClassLoader JavaDoc classLoader = Lookup.getDefault().lookup(ClassLoader JavaDoc.class);
254                 Class JavaDoc clazz = classLoader.loadClass("org.netbeans.modules.editor.mimelookup.impl.SwitchLookup"); //NOI18N
255
Method JavaDoc method = clazz.getDeclaredMethod("computePaths", MimePath.class, String JavaDoc.class, String JavaDoc.class); //NOI18N
256
method.setAccessible(true);
257                 List JavaDoc<String JavaDoc> paths = (List JavaDoc<String JavaDoc>) method.invoke(null, mimePath, null, null);
258                 return paths;
259             } catch (Exception JavaDoc e) {
260                 LOG.log(Level.WARNING, "Can't call org.netbeans.modules.editor.mimelookup.impl.SwitchLookup.computePath(MimeLookup, String, String).", e); //NOI18N
261
return null;
262             }
263         }
264     } // End of MyLookup class
265
}
266
Popular Tags