KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2004, 2007 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  * Gunnar Wagenknecht - Bug 179695 - [prefs] NPE when using Preferences API without a product
11  *******************************************************************************/

12 package org.eclipse.core.internal.preferences;
13
14 import java.io.*;
15 import java.lang.ref.WeakReference JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.util.*;
18 import org.eclipse.core.internal.preferences.exchange.IProductPreferencesService;
19 import org.eclipse.core.internal.runtime.RuntimeLog;
20 import org.eclipse.core.runtime.*;
21 import org.eclipse.core.runtime.preferences.*;
22 import org.eclipse.osgi.util.NLS;
23 import org.osgi.framework.Bundle;
24 import org.osgi.framework.BundleContext;
25 import org.osgi.util.tracker.ServiceTracker;
26
27 /**
28  * @since 3.0
29  */

30 public class DefaultPreferences extends EclipsePreferences {
31     // cache which nodes have been loaded from disk
32
private static Set loadedNodes = new HashSet();
33     private static final String JavaDoc KEY_PREFIX = "%"; //$NON-NLS-1$
34
private static final String JavaDoc KEY_DOUBLE_PREFIX = "%%"; //$NON-NLS-1$
35
private static final IPath NL_DIR = new Path("$nl$"); //$NON-NLS-1$
36

37     private static final String JavaDoc PROPERTIES_FILE_EXTENSION = "properties"; //$NON-NLS-1$
38
private static Properties productCustomization;
39     private static Properties productTranslation;
40     private static Properties commandLineCustomization;
41     private EclipsePreferences loadLevel;
42
43     // cached values
44
private String JavaDoc qualifier;
45     private int segmentCount;
46     private WeakReference JavaDoc pluginReference;
47
48     public static String JavaDoc pluginCustomizationFile = null;
49
50     /**
51      * Default constructor for this class.
52      */

53     public DefaultPreferences() {
54         this(null, null);
55     }
56
57     private DefaultPreferences(EclipsePreferences parent, String JavaDoc name, Object JavaDoc context) {
58         this(parent, name);
59         this.pluginReference = new WeakReference JavaDoc(context);
60     }
61
62     private DefaultPreferences(EclipsePreferences parent, String JavaDoc name) {
63         super(parent, name);
64
65         if (parent instanceof DefaultPreferences)
66             this.pluginReference = ((DefaultPreferences) parent).pluginReference;
67
68         // cache the segment count
69
String JavaDoc path = absolutePath();
70         segmentCount = getSegmentCount(path);
71         if (segmentCount < 2)
72             return;
73
74         // cache the qualifier
75
qualifier = getSegment(path, 1);
76     }
77
78     /*
79      * Apply the values set in the bundle's install directory.
80      *
81      * In Eclipse 2.1 this is equivalent to:
82      * /eclipse/plugins/<pluginID>/prefs.ini
83      */

84     private void applyBundleDefaults() {
85         Bundle bundle = PreferencesOSGiUtils.getDefault().getBundle(name());
86         if (bundle == null)
87             return;
88         URL JavaDoc url = FileLocator.find(bundle, new Path(IPreferencesConstants.PREFERENCES_DEFAULT_OVERRIDE_FILE_NAME), null);
89         if (url == null) {
90             if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
91                 PrefsMessages.message("Preference default override file not found for bundle: " + bundle.getSymbolicName()); //$NON-NLS-1$
92
return;
93         }
94         URL JavaDoc transURL = FileLocator.find(bundle, NL_DIR.append(IPreferencesConstants.PREFERENCES_DEFAULT_OVERRIDE_BASE_NAME).addFileExtension(PROPERTIES_FILE_EXTENSION), null);
95         if (transURL == null && EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
96             PrefsMessages.message("Preference translation file not found for bundle: " + bundle.getSymbolicName()); //$NON-NLS-1$
97
applyDefaults(name(), loadProperties(url), loadProperties(transURL));
98     }
99
100     /*
101      * Apply the default values as specified in the file
102      * as an argument on the command-line.
103      */

104     private void applyCommandLineDefaults() {
105         // prime the cache the first time
106
if (commandLineCustomization == null) {
107             String JavaDoc filename = pluginCustomizationFile;
108             if (filename == null) {
109                 if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
110                     PrefsMessages.message("Command-line preferences customization file not specified."); //$NON-NLS-1$
111
return;
112             }
113             if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
114                 PrefsMessages.message("Using command-line preference customization file: " + filename); //$NON-NLS-1$
115
commandLineCustomization = loadProperties(filename);
116         }
117         applyDefaults(null, commandLineCustomization, null);
118     }
119
120     /*
121      * If the qualifier is null then the file is of the format:
122      * pluginID/key=value
123      * otherwise the file is of the format:
124      * key=value
125      */

126     private void applyDefaults(String JavaDoc id, Properties defaultValues, Properties translations) {
127         for (Enumeration e = defaultValues.keys(); e.hasMoreElements();) {
128             String JavaDoc fullKey = (String JavaDoc) e.nextElement();
129             String JavaDoc value = defaultValues.getProperty(fullKey);
130             if (value == null)
131                 continue;
132             IPath childPath = new Path(fullKey);
133             String JavaDoc key = childPath.lastSegment();
134             childPath = childPath.removeLastSegments(1);
135             String JavaDoc localQualifier = id;
136             if (id == null) {
137                 localQualifier = childPath.segment(0);
138                 childPath = childPath.removeFirstSegments(1);
139             }
140             if (name().equals(localQualifier)) {
141                 value = translatePreference(value, translations);
142                 if (EclipsePreferences.DEBUG_PREFERENCE_SET)
143                     PrefsMessages.message("Setting default preference: " + (new Path(absolutePath()).append(childPath).append(key)) + '=' + value); //$NON-NLS-1$
144
((EclipsePreferences) internalNode(childPath.toString(), false, null)).internalPut(key, value);
145             }
146         }
147     }
148
149     public IEclipsePreferences node(String JavaDoc childName, Object JavaDoc context) {
150         return internalNode(childName, true, context);
151     }
152
153     /*
154      * Runtime defaults are the ones which are specified in code at runtime.
155      *
156      * In the Eclipse 2.1 world they were the ones which were specified in the
157      * over-ridden Plugin#initializeDefaultPluginPreferences() method.
158      *
159      * In Eclipse 3.0 they are set in the code which is indicated by the
160      * extension to the plug-in default customizer extension point.
161      */

162     private void applyRuntimeDefaults() {
163         WeakReference JavaDoc ref = PreferencesService.getDefault().applyRuntimeDefaults(name(), pluginReference);
164         if (ref != null)
165             pluginReference = ref;
166     }
167
168     /*
169      * Apply the default values as specified by the file
170      * in the product extension.
171      *
172      * In Eclipse 2.1 this is equivalent to the plugin_customization.ini
173      * file in the primary feature's plug-in directory.
174      */

175     private void applyProductDefaults() {
176         // prime the cache the first time
177
if (productCustomization == null) {
178             BundleContext context = Activator.getContext();
179             if (context != null) {
180                 ServiceTracker productTracker = new ServiceTracker(context, IProductPreferencesService.class.getName(), null);
181                 productTracker.open();
182                 IProductPreferencesService productSpecials = (IProductPreferencesService) productTracker.getService();
183                 if (productSpecials != null) {
184                     productCustomization = productSpecials.getProductCustomization();
185                     productTranslation = productSpecials.getProductTranslation();
186                 }
187                 productTracker.close();
188             } else {
189                 PrefsMessages.message("Product-specified preferences called before plugin is started"); //$NON-NLS-1$
190
}
191             if (productCustomization == null)
192                 productCustomization = new Properties();
193         }
194         if (!productCustomization.isEmpty())
195             applyDefaults(null, productCustomization, productTranslation);
196     }
197
198     /* (non-Javadoc)
199      * @see org.osgi.service.prefs.Preferences#flush()
200      */

201     public void flush() {
202         // default values are not persisted
203
}
204
205     protected IEclipsePreferences getLoadLevel() {
206         if (loadLevel == null) {
207             if (qualifier == null)
208                 return null;
209             // Make it relative to this node rather than navigating to it from the root.
210
// Walk backwards up the tree starting at this node.
211
// This is important to avoid a chicken/egg thing on startup.
212
EclipsePreferences node = this;
213             for (int i = 2; i < segmentCount; i++)
214                 node = (EclipsePreferences) node.parent();
215             loadLevel = node;
216         }
217         return loadLevel;
218     }
219
220     protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String JavaDoc nodeName, Object JavaDoc context) {
221         return new DefaultPreferences(nodeParent, nodeName, context);
222     }
223
224     protected boolean isAlreadyLoaded(IEclipsePreferences node) {
225         return loadedNodes.contains(node.name());
226     }
227
228     /* (non-Javadoc)
229      * @see org.eclipse.core.internal.preferences.EclipsePreferences#load()
230      */

231     protected void load() {
232         loadDefaults();
233     }
234
235     private void loadDefaults() {
236         applyRuntimeDefaults();
237         applyBundleDefaults();
238         applyProductDefaults();
239         applyCommandLineDefaults();
240     }
241
242     private Properties loadProperties(URL JavaDoc url) {
243         Properties result = new Properties();
244         if (url == null)
245             return result;
246         InputStream input = null;
247         try {
248             input = url.openStream();
249             result.load(input);
250         } catch (IOException e) {
251             if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL) {
252                 PrefsMessages.message("Problem opening stream to preference customization file: " + url); //$NON-NLS-1$
253
e.printStackTrace();
254             }
255         } finally {
256             if (input != null)
257                 try {
258                     input.close();
259                 } catch (IOException e) {
260                     // ignore
261
}
262         }
263         return result;
264     }
265
266     private Properties loadProperties(String JavaDoc filename) {
267         Properties result = new Properties();
268         InputStream input = null;
269         try {
270             input = new BufferedInputStream(new FileInputStream(filename));
271             result.load(input);
272         } catch (FileNotFoundException e) {
273             if (EclipsePreferences.DEBUG_PREFERENCE_GENERAL)
274                 PrefsMessages.message("Preference customization file not found: " + filename); //$NON-NLS-1$
275
} catch (IOException e) {
276             String JavaDoc message = NLS.bind(PrefsMessages.preferences_loadException, filename);
277             IStatus status = new Status(IStatus.ERROR, PrefsMessages.OWNER_NAME, IStatus.ERROR, message, e);
278             RuntimeLog.log(status);
279         } finally {
280             if (input != null)
281                 try {
282                     input.close();
283                 } catch (IOException e) {
284                     // ignore
285
}
286         }
287         return result;
288     }
289
290     protected void loaded() {
291         loadedNodes.add(name());
292     }
293
294     /* (non-Javadoc)
295      * @see org.osgi.service.prefs.Preferences#sync()
296      */

297     public void sync() {
298         // default values are not persisted
299
}
300
301     /**
302      * Takes a preference value and a related resource bundle and
303      * returns the translated version of this value (if one exists).
304      */

305     private String JavaDoc translatePreference(String JavaDoc value, Properties props) {
306         value = value.trim();
307         if (props == null || value.startsWith(KEY_DOUBLE_PREFIX))
308             return value;
309         if (value.startsWith(KEY_PREFIX)) {
310             int ix = value.indexOf(" "); //$NON-NLS-1$
311
String JavaDoc key = ix == -1 ? value.substring(1) : value.substring(1, ix);
312             String JavaDoc dflt = ix == -1 ? value : value.substring(ix + 1);
313             return props.getProperty(key, dflt);
314         }
315         return value;
316     }
317 }
318
Popular Tags