KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > preferences > PreferenceServiceRegistryHelper


1 /*******************************************************************************
2  * Copyright (c) 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.preferences;
12
13 import java.lang.ref.WeakReference JavaDoc;
14 import java.util.*;
15 import org.eclipse.core.internal.preferences.exchange.ILegacyPreferences;
16 import org.eclipse.core.internal.runtime.RuntimeLog;
17 import org.eclipse.core.runtime.*;
18 import org.eclipse.core.runtime.preferences.*;
19 import org.eclipse.osgi.util.NLS;
20 import org.osgi.framework.Bundle;
21
22 /**
23  * Class which handles all registry-related work for the preferences. This code has
24  * been separated into a separate class to ensure that the preferences will be able
25  * to run without the registry being present.
26  */

27 public class PreferenceServiceRegistryHelper implements IRegistryChangeListener {
28
29     private static final String JavaDoc ELEMENT_INITIALIZER = "initializer"; //$NON-NLS-1$
30
private static final String JavaDoc ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
31
private static final String JavaDoc ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
32
private static final String JavaDoc ELEMENT_SCOPE = "scope"; //$NON-NLS-1$
33
private static final String JavaDoc ELEMENT_MODIFIER = "modifier"; //$NON-NLS-1$
34
// Store this around for performance
35
private final static IExtension[] EMPTY_EXTENSION_ARRAY = new IExtension[0];
36     private static final Map scopeRegistry = Collections.synchronizedMap(new HashMap());
37     private ListenerList modifyListeners;
38     private PreferencesService service;
39     private IExtensionRegistry registry;
40
41     /*
42      * Create and return an IStatus object with ERROR severity and the
43      * given message and exception.
44      */

45     private static IStatus createStatusError(String JavaDoc message, Exception JavaDoc e) {
46         return new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e);
47     }
48
49     /*
50      * Create and return an IStatus object with WARNING severity and the
51      * given message and exception.
52      */

53     private static IStatus createStatusWarning(String JavaDoc message, Exception JavaDoc e) {
54         return new Status(IStatus.WARNING, PrefsMessages.OWNER_NAME, IStatus.WARNING, message, e);
55     }
56
57     /*
58      * Log the given status.
59      */

60     private static void log(IStatus status) {
61         RuntimeLog.log(status);
62     }
63
64     /*
65      * Constructor for the class.
66      */

67     public PreferenceServiceRegistryHelper(PreferencesService service, Object JavaDoc registryObject) {
68         super();
69         this.service = service;
70         this.registry = (IExtensionRegistry) registryObject;
71         initializeScopes();
72         registry.addRegistryChangeListener(this);
73     }
74     
75     void stop() {
76         registry.removeRegistryChangeListener(this);
77     }
78
79     /*
80      * Add the given configuration element into our list of preference modify listeners.
81      */

82     private void addModifyListener(IConfigurationElement element) {
83         String JavaDoc key = element.getAttribute(ATTRIBUTE_CLASS);
84         if (key == null) {
85             String JavaDoc message = NLS.bind(PrefsMessages.preferences_missingClassAttribute, element.getDeclaringExtension().getUniqueIdentifier());
86             log(new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, null));
87             return;
88         }
89         try {
90             Object JavaDoc listener = element.createExecutableExtension(ATTRIBUTE_CLASS);
91             if (!(listener instanceof PreferenceModifyListener)) {
92                 log(new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, PrefsMessages.preferences_classCastListener, null));
93                 return;
94             }
95             modifyListeners.add(listener);
96         } catch (CoreException e) {
97             log(e.getStatus());
98         }
99     }
100
101     /*
102      * Apply the runtime defaults for the bundle with the given name. Check
103      * to see if there is a preference initializer registered and if so, then run it.
104      * Otherwise call the legacy Plugin preference initialization code.
105      */

106     public WeakReference JavaDoc applyRuntimeDefaults(String JavaDoc name, WeakReference JavaDoc pluginReference) {
107         IExtension[] extensions = getPrefExtensions();
108         if (extensions.length == 0) {
109             if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
110                 PrefsMessages.message("Skipping runtime default preference customization."); //$NON-NLS-1$
111
return null;
112         }
113         boolean foundInitializer = false;
114         for (int i = 0; i < extensions.length; i++) {
115             IConfigurationElement[] elements = extensions[i].getConfigurationElements();
116             for (int j = 0; j < elements.length; j++)
117                 if (ELEMENT_INITIALIZER.equals(elements[j].getName())) {
118                     if (name.equals(elements[j].getContributor().getName())) {
119                         if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL) {
120                             IExtension theExtension = elements[j].getDeclaringExtension();
121                             String JavaDoc extensionNamespace = theExtension.getContributor().getName();
122                             Bundle underlyingBundle = PreferencesOSGiUtils.getDefault().getBundle(extensionNamespace);
123                             String JavaDoc ownerName;
124                             if (underlyingBundle != null)
125                                 ownerName = underlyingBundle.getSymbolicName();
126                             else
127                                 ownerName = extensionNamespace;
128                             PrefsMessages.message("Running default preference customization as defined by: " + ownerName); //$NON-NLS-1$
129
}
130                         runInitializer(elements[j]);
131                         // don't return yet in case we have multiple initializers registered
132
foundInitializer = true;
133                     }
134                 }
135         }
136         if (foundInitializer)
137             return null;
138
139         // TODO this means that we don't call the legacy Plugin code if the registry isn't present.
140
// I don't think this is the desired behaviour
141

142         // Do legacy plugin preference initialization
143
Object JavaDoc plugin = pluginReference.get();
144         ILegacyPreferences initService = PreferencesOSGiUtils.getDefault().getLegacyPreferences();
145         if (initService != null)
146             plugin = initService.init(plugin, name);
147         return new WeakReference JavaDoc(plugin);
148     }
149
150     /*
151      * Create a new child node with the given parent. Look up the name
152      * in the registry as it may map to a configuration element. This is done
153      * for lazy initialization of user-contributed scopes.
154      */

155     public IEclipsePreferences createNode(RootPreferences parent, String JavaDoc name) {
156         IScope scope = null;
157         Object JavaDoc value = scopeRegistry.get(name);
158         if (value instanceof IConfigurationElement) {
159             try {
160                 scope = (IScope) ((IConfigurationElement) value).createExecutableExtension(ATTRIBUTE_CLASS);
161                 scopeRegistry.put(name, scope);
162             } catch (ClassCastException JavaDoc e) {
163                 log(createStatusError(PrefsMessages.preferences_classCastScope, e));
164                 return new EclipsePreferences(parent, name);
165             } catch (CoreException e) {
166                 log(e.getStatus());
167                 return new EclipsePreferences(parent, name);
168             }
169         } else
170             scope = (IScope) value;
171         return scope.create(parent, name);
172     }
173
174     /*
175      * Return a list of the preference modify listeners. They are called during preference
176      * import and given the chance to modify the imported tree.
177      */

178     public PreferenceModifyListener[] getModifyListeners() {
179         if (modifyListeners == null) {
180             modifyListeners = new ListenerList();
181             IExtension[] extensions = getPrefExtensions();
182             for (int i = 0; i < extensions.length; i++) {
183                 IConfigurationElement[] elements = extensions[i].getConfigurationElements();
184                 for (int j = 0; j < elements.length; j++)
185                     if (ELEMENT_MODIFIER.equalsIgnoreCase(elements[j].getName()))
186                         addModifyListener(elements[j]);
187             }
188         }
189         Object JavaDoc[] source = modifyListeners.getListeners();
190         PreferenceModifyListener[] result = new PreferenceModifyListener[source.length];
191         System.arraycopy(source, 0, result, 0, source.length);
192         return result;
193     }
194
195     /*
196      * Return a list of the extensions which are plugged into the preference
197      * extension point.
198      */

199     private IExtension[] getPrefExtensions() {
200         IExtension[] extensionsOld = EMPTY_EXTENSION_ARRAY;
201         IExtension[] extensionsNew = EMPTY_EXTENSION_ARRAY;
202         // "old"
203
IExtensionPoint pointOld = registry.getExtensionPoint(IPreferencesConstants.RUNTIME_NAME, IPreferencesConstants.PT_PREFERENCES);
204         if (pointOld != null)
205             extensionsOld = pointOld.getExtensions();
206         // "new"
207
IExtensionPoint pointNew = registry.getExtensionPoint(IPreferencesConstants.PREFERS_NAME, IPreferencesConstants.PT_PREFERENCES);
208         if (pointNew != null)
209             extensionsNew = pointNew.getExtensions();
210         // combine
211
IExtension[] extensions = new IExtension[extensionsOld.length + extensionsNew.length];
212         System.arraycopy(extensionsOld, 0, extensions, 0, extensionsOld.length);
213         System.arraycopy(extensionsNew, 0, extensions, extensionsOld.length, extensionsNew.length);
214
215         if (extensions.length == 0) {
216             if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
217                 PrefsMessages.message("No extensions for org.eclipse.core.contenttype."); //$NON-NLS-1$
218
}
219
220         return extensions;
221     }
222
223     /*
224      * See who is plugged into the extension point.
225      */

226     private void initializeScopes() {
227         IExtension[] extensions = getPrefExtensions();
228         for (int i = 0; i < extensions.length; i++) {
229             IConfigurationElement[] elements = extensions[i].getConfigurationElements();
230             for (int j = 0; j < elements.length; j++)
231                 if (ELEMENT_SCOPE.equalsIgnoreCase(elements[j].getName()))
232                     scopeAdded(elements[j]);
233         }
234     }
235
236     /* (non-Javadoc)
237      * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
238      */

239     public void registryChanged(IRegistryChangeEvent event) {
240         IExtensionDelta[] deltasOld = event.getExtensionDeltas(IPreferencesConstants.RUNTIME_NAME, IPreferencesConstants.PT_PREFERENCES);
241         IExtensionDelta[] deltasNew = event.getExtensionDeltas(IPreferencesConstants.PREFERS_NAME, IPreferencesConstants.PT_PREFERENCES);
242         IExtensionDelta[] deltas = new IExtensionDelta[deltasOld.length + deltasNew.length];
243         System.arraycopy(deltasOld, 0, deltas, 0, deltasOld.length);
244         System.arraycopy(deltasNew, 0, deltas, deltasOld.length, deltasNew.length);
245
246         if (deltas.length == 0)
247             return;
248         // dynamically adjust the registered scopes
249
for (int i = 0; i < deltas.length; i++) {
250             IConfigurationElement[] elements = deltas[i].getExtension().getConfigurationElements();
251             for (int j = 0; j < elements.length; j++) {
252                 switch (deltas[i].getKind()) {
253                     case IExtensionDelta.ADDED :
254                         if (ELEMENT_SCOPE.equalsIgnoreCase(elements[j].getName()))
255                             scopeAdded(elements[j]);
256                         break;
257                     case IExtensionDelta.REMOVED :
258                         String JavaDoc scope = elements[j].getAttribute(ATTRIBUTE_NAME);
259                         if (scope != null)
260                             scopeRemoved(scope);
261                         break;
262                 }
263             }
264         }
265         // initialize the preference modify listeners
266
modifyListeners = null;
267     }
268
269     /*
270      * Run the preference initializer as specified by the given configuration element.
271      */

272     private void runInitializer(IConfigurationElement element) {
273         AbstractPreferenceInitializer initializer = null;
274         try {
275             initializer = (AbstractPreferenceInitializer) element.createExecutableExtension(ATTRIBUTE_CLASS);
276             initializer.initializeDefaultPreferences();
277         } catch (ClassCastException JavaDoc e) {
278             IStatus status = new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, PrefsMessages.preferences_invalidExtensionSuperclass, e);
279             log(status);
280         } catch (CoreException e) {
281             log(e.getStatus());
282         }
283     }
284
285     /*
286      * A preference scope defined by the given element was added to the extension
287      * registry. Add it to our registry and make it a child of the root.
288      */

289     private void scopeAdded(IConfigurationElement element) {
290         String JavaDoc key = element.getAttribute(ATTRIBUTE_NAME);
291         if (key == null) {
292             String JavaDoc message = NLS.bind(PrefsMessages.preferences_missingScopeAttribute, element.getDeclaringExtension().getUniqueIdentifier());
293             log(createStatusWarning(message, null));
294             return;
295         }
296         scopeRegistry.put(key, element);
297         ((RootPreferences) service.getRootNode()).addChild(key, null);
298     }
299
300     /*
301      * A preference scope with the given name was removed from the extension
302      * registry. Remove the node and its children from the preference tree.
303      */

304     private void scopeRemoved(String JavaDoc key) {
305         IEclipsePreferences node = (IEclipsePreferences) ((RootPreferences) service.getRootNode()).getNode(key, false);
306         if (node != null)
307             ((RootPreferences) service.getRootNode()).removeNode(node);
308         else
309             ((RootPreferences) service.getRootNode()).removeNode(key);
310         scopeRegistry.remove(key);
311     }
312
313 }
314
Popular Tags