Added
Link Here
|
1 |
/******************************************************************************* |
2 |
* Copyright (c) 2010 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.net; |
12 |
|
13 |
import org.eclipse.core.net.proxy.IProxyData; |
14 |
import org.eclipse.core.runtime.preferences.ConfigurationScope; |
15 |
import org.eclipse.core.runtime.preferences.DefaultScope; |
16 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences; |
17 |
import org.eclipse.core.runtime.preferences.InstanceScope; |
18 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener; |
19 |
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; |
20 |
import org.osgi.service.prefs.BackingStoreException; |
21 |
import org.osgi.service.prefs.Preferences; |
22 |
|
23 |
|
24 |
/** |
25 |
* Provides set of methods to operate on preferences |
26 |
*/ |
27 |
public class PreferenceManager { |
28 |
|
29 |
public static final String ROOT = ""; //$NON-NLS-1$ |
30 |
|
31 |
private static final String PREF_HAS_MIGRATED = "org.eclipse.core.net.hasMigrated"; //$NON-NLS-1$ |
32 |
|
33 |
/** |
34 |
* Preference constants used by Update to record the HTTP proxy |
35 |
*/ |
36 |
private static String HTTP_PROXY_HOST = "org.eclipse.update.core.proxy.host"; //$NON-NLS-1$ |
37 |
private static String HTTP_PROXY_PORT = "org.eclipse.update.core.proxy.port"; //$NON-NLS-1$ |
38 |
private static String HTTP_PROXY_ENABLE = "org.eclipse.update.core.proxy.enable"; //$NON-NLS-1$ |
39 |
|
40 |
private static final int DEFAULT_INT = -1; |
41 |
private static final String DEFAULT_STRING = null; |
42 |
private static final boolean DEFAULT_BOOLEAN = false; |
43 |
|
44 |
private static boolean migrated = false; |
45 |
|
46 |
private IEclipsePreferences defaultScope; |
47 |
private IEclipsePreferences instanceScope; |
48 |
private IEclipsePreferences currentScope; |
49 |
|
50 |
private PreferenceManager(String id) { |
51 |
this.defaultScope = new DefaultScope().getNode(id); |
52 |
this.instanceScope = new InstanceScope().getNode(id); |
53 |
} |
54 |
|
55 |
/** |
56 |
* Creates the preferences manager for the node defined by id |
57 |
* in configuration scope. |
58 |
* @param id node name for which node should be created in configuration scope |
59 |
* @return {@link PreferenceManager} |
60 |
*/ |
61 |
public static PreferenceManager createConfigurationManager(String id) { |
62 |
PreferenceManager manager = new PreferenceManager(id); |
63 |
manager.currentScope = new ConfigurationScope().getNode(id); |
64 |
return manager; |
65 |
} |
66 |
|
67 |
/** |
68 |
* Checks if preference migration was already performed. |
69 |
* @return <code>boolean</code> |
70 |
*/ |
71 |
public boolean isMigrated() { |
72 |
return migrated; |
73 |
} |
74 |
|
75 |
/** |
76 |
* Returns the <code>boolean</code> value associated with the specified <code>key</code> |
77 |
* for specified <code>node</code> in current scope. |
78 |
* |
79 |
* <p> |
80 |
* Returns the value specified in the default scope if there is no value associated with the |
81 |
* <code>key</code> in the current scope, the backing store is inaccessible, or if the associated |
82 |
* value is something that can not be parsed as an integer value. |
83 |
* Use {@link #putBoolean(String, String, boolean)} to set the value of this preference key. |
84 |
* </p> |
85 |
* @param node node |
86 |
* @param key key whose associated value is to be returned as an <code>boolean</code>. |
87 |
* @return the <code>boolean</code> value associated with <code>key</code>, or |
88 |
* <code>false</code> if the associated value does not exist in either scope or cannot |
89 |
* be interpreted as an <code>boolean</code>. |
90 |
* @see #putBoolean(String, String, boolean) |
91 |
*/ |
92 |
public boolean getBoolean(String node, String key) { |
93 |
return currentScope.node(node).getBoolean(key, defaultScope.node(node).getBoolean(key, DEFAULT_BOOLEAN)); |
94 |
} |
95 |
|
96 |
/** |
97 |
* Returns the <code>int</code> value associated with the specified <code>key</code> |
98 |
* for specified <code>node</code> in current scope. |
99 |
* |
100 |
* <p> |
101 |
* Returns the value specified in the default scope if there is no value associated with the |
102 |
* <code>key</code> in the current scope, the backing store is inaccessible, or if the associated |
103 |
* value is something that can not be parsed as an integer value. |
104 |
* Use {@link #putInt(String, String, int)} to set the value of this preference key. |
105 |
* </p> |
106 |
* @param node node |
107 |
* @param key key whose associated value is to be returned as an <code>int</code>. |
108 |
* @return the <code>int</code> value associated with <code>key</code>, or |
109 |
* <code>-1</code> if the associated value does not exist in either scope or cannot |
110 |
* be interpreted as an <code>int</code>. |
111 |
* @see #putInt(String, String, int) |
112 |
*/ |
113 |
public int getInt(String node, String key) { |
114 |
return currentScope.node(node).getInt(key, defaultScope.node(node).getInt(key, DEFAULT_INT)); |
115 |
} |
116 |
|
117 |
/** |
118 |
* Returns the <code>String</code> value associated with the specified <code>key</code> |
119 |
* for specified <code>node</code> in current scope. |
120 |
* |
121 |
* <p> |
122 |
* Returns the value specified in the default scope if there is no value associated with the |
123 |
* <code>key</code> in the current scope, the backing store is inaccessible, or if the associated |
124 |
* value is something that can not be parsed as an integer value. |
125 |
* Use {@link #putString(String, String, String)} to set the value of this preference key. |
126 |
* </p> |
127 |
* @param node node |
128 |
* @param key key whose associated value is to be returned as an <code>String</code>. |
129 |
* @return the <code>String</code> value associated with <code>key</code>, or |
130 |
* <code>null</code> if the associated value does not exist in either scope or cannot |
131 |
* be interpreted as an <code>String</code>. |
132 |
* @see #putString(String, String, String) |
133 |
*/ |
134 |
public String getString(String node, String key) { |
135 |
return currentScope.node(node).get(key, defaultScope.node(node).get(key, DEFAULT_STRING)); |
136 |
} |
137 |
|
138 |
/** |
139 |
* Associates the specified <code>int</code> value with the specified key |
140 |
* for specified <code>node</code> in current scope. |
141 |
* |
142 |
* @param node node |
143 |
* @param key <code>key</code> with which the string form of value is to be associated. |
144 |
* @param value <code>value</code> to be associated with <code>key</code>. |
145 |
* @see #getInt(String, String) |
146 |
*/ |
147 |
public void putInt(String node, String key, int value) { |
148 |
currentScope.node(node).putInt(key, value); |
149 |
} |
150 |
|
151 |
/** |
152 |
* Associates the specified <code>boolean</code> value with the specified key |
153 |
* for specified <code>node</code> in current scope. |
154 |
* |
155 |
* @param node node |
156 |
* @param key <code>key</code> with which the string form of value is to be associated. |
157 |
* @param value <code>value</code> to be associated with <code>key</code>. |
158 |
* @see #getBoolean(String, String) |
159 |
*/ |
160 |
public void putBoolean(String node, String key, boolean value) { |
161 |
currentScope.node(node).putBoolean(key, value); |
162 |
} |
163 |
|
164 |
/** |
165 |
* Associates the specified <code>String</code> value with the specified key |
166 |
* for specified <code>node</code> in current scope. |
167 |
* |
168 |
* @param node node |
169 |
* @param key <code>key</code> with which the string form of value is to be associated. |
170 |
* @param value <code>value</code> to be associated with <code>key</code>. |
171 |
* @see #getString(String, String) |
172 |
*/ |
173 |
public void putString(String node, String key, String value) { |
174 |
currentScope.node(node).put(key, value); |
175 |
} |
176 |
|
177 |
/** |
178 |
* Register the given listener for notification of preference changes. |
179 |
* Calling this method multiple times with the same listener has no effect. The |
180 |
* given listener argument must not be <code>null</code>. |
181 |
* |
182 |
* @param node node |
183 |
* @param listener the preference change listener to register |
184 |
* @see #removePreferenceChangeListener(String, IEclipsePreferences.IPreferenceChangeListener) |
185 |
* @see IEclipsePreferences.IPreferenceChangeListener |
186 |
*/ |
187 |
public void addPreferenceChangeListener(String node, IPreferenceChangeListener listener) { |
188 |
((IEclipsePreferences)currentScope.node(node)).addPreferenceChangeListener(listener); |
189 |
} |
190 |
|
191 |
/** |
192 |
* De-register the given listener from receiving notification of preference changes |
193 |
* Calling this method multiple times with the same listener has no |
194 |
* effect. The given listener argument must not be <code>null</code>. |
195 |
* @param node node |
196 |
* @param listener the preference change listener to remove |
197 |
* @see #addPreferenceChangeListener(String, IEclipsePreferences.IPreferenceChangeListener) |
198 |
* @see IEclipsePreferences.IPreferenceChangeListener |
199 |
*/ |
200 |
public void removePreferenceChangeListener(String node, IPreferenceChangeListener listener) { |
201 |
((IEclipsePreferences)currentScope.node(node)).removePreferenceChangeListener(listener); |
202 |
} |
203 |
|
204 |
/** |
205 |
* Register the given listener for changes to this node. |
206 |
* Calling this method multiple times with the same listener has no effect. The |
207 |
* given listener argument must not be <code>null</code>. |
208 |
* |
209 |
* @param node node |
210 |
* @param listener the preference change listener to register |
211 |
* @see #removeNodeChangeListener(String, IEclipsePreferences.INodeChangeListener) |
212 |
* @see IEclipsePreferences.IPreferenceChangeListener |
213 |
*/ |
214 |
public void addNodeChangeListener(String node, INodeChangeListener listener) { |
215 |
((IEclipsePreferences)currentScope.node(node)).addNodeChangeListener(listener); |
216 |
} |
217 |
|
218 |
/** |
219 |
* De-register the given listener from receiving event change notifications for this node. |
220 |
* Calling this method multiple times with the same listener has no |
221 |
* effect. The given listener argument must not be <code>null</code>. |
222 |
* @param node node |
223 |
* @param listener the preference change listener to remove |
224 |
* @see #addPreferenceChangeListener(String, IEclipsePreferences.IPreferenceChangeListener) |
225 |
* @see IEclipsePreferences.IPreferenceChangeListener |
226 |
*/ |
227 |
public void removeNodeChangeListener(String node, INodeChangeListener listener) { |
228 |
((IEclipsePreferences)currentScope.node(node)).removeNodeChangeListener(listener); |
229 |
} |
230 |
|
231 |
/** |
232 |
* Removes this node and all of its descendants, |
233 |
* invalidating any properties contained in the removed nodes. |
234 |
* @param node name of a node which should be removed |
235 |
* @throws BackingStoreException - if this operation cannot be completed |
236 |
* due to a failure in the backing store, or inability to communicate with it. |
237 |
*/ |
238 |
public void removeNode(String node) throws BackingStoreException { |
239 |
currentScope.node(node).removeNode(); |
240 |
} |
241 |
|
242 |
/** |
243 |
* Forces any changes in the contents of current scope |
244 |
* and its descendants to the persistent store. |
245 |
* @throws BackingStoreException - if this operation cannot be completed |
246 |
* due to a failure in the backing store, or inability to communicate with it. |
247 |
*/ |
248 |
public void flush() throws BackingStoreException { |
249 |
currentScope.flush(); |
250 |
} |
251 |
|
252 |
/** |
253 |
* Migrate preferences from instance scope to current scope. |
254 |
* @param proxies proxy types for which migration should be performed {@link ProxyType} |
255 |
*/ |
256 |
public void migrate(ProxyType[] proxies) { |
257 |
migrated = true; |
258 |
if (currentScope.getBoolean(PREF_HAS_MIGRATED, false) |
259 |
|| currentScope.name().equals(InstanceScope.SCOPE)) { |
260 |
return; |
261 |
} |
262 |
currentScope.putBoolean(PREF_HAS_MIGRATED, true); |
263 |
migrateInstanceScopePreferences(proxies, true); |
264 |
} |
265 |
|
266 |
void migrateInstanceScopePreferences(ProxyType[] proxies, boolean isInitialize) { |
267 |
migrateUpdateHttpProxy(proxies, isInitialize); |
268 |
|
269 |
// migrate enabled status |
270 |
if (currentScope.get(ProxyManager.PREF_ENABLED, null) == null) { |
271 |
String instanceEnabled = instanceScope.get(ProxyManager.PREF_ENABLED, null); |
272 |
if (instanceEnabled != null) |
273 |
currentScope.put(ProxyManager.PREF_ENABLED, instanceEnabled); |
274 |
} |
275 |
|
276 |
// migrate enabled status |
277 |
if (currentScope.get(ProxyManager.PREF_OS, null) == null) { |
278 |
String instanceEnabled = instanceScope.get(ProxyManager.PREF_OS, null); |
279 |
if (instanceEnabled != null) |
280 |
currentScope.put(ProxyManager.PREF_OS, instanceEnabled); |
281 |
} |
282 |
|
283 |
// migrate non proxied hosts if not already set |
284 |
if (currentScope.get(ProxyManager.PREF_NON_PROXIED_HOSTS, null) == null) { |
285 |
String instanceNonProxiedHosts = instanceScope.get(ProxyManager.PREF_NON_PROXIED_HOSTS, null); |
286 |
if (instanceNonProxiedHosts != null) { |
287 |
currentScope.put(ProxyManager.PREF_NON_PROXIED_HOSTS, instanceNonProxiedHosts); |
288 |
} |
289 |
} |
290 |
|
291 |
// migrate proxy data |
292 |
PreferenceManager instanceManager = PreferenceManager.createInstanceManager(Activator.ID); |
293 |
for (int i = 0; i < proxies.length; i++) { |
294 |
ProxyType type = proxies[i]; |
295 |
IProxyData data = type.getProxyData(ProxyType.DO_NOT_VERIFY); |
296 |
if (data.getHost() == null) { |
297 |
ProxyType instanceType = new ProxyType(type.getName(), instanceManager); |
298 |
IProxyData instanceData = instanceType.getProxyData(ProxyType.DO_NOT_VERIFY); |
299 |
if (instanceData.getHost() != null) |
300 |
type.setProxyData(instanceData); |
301 |
} |
302 |
} |
303 |
|
304 |
// if this an import we should remove the old node |
305 |
if (!isInitialize) { |
306 |
try { |
307 |
instanceScope.removeNode(); |
308 |
} catch (BackingStoreException e) { |
309 |
// ignore |
310 |
} |
311 |
} |
312 |
} |
313 |
|
314 |
private void migrateUpdateHttpProxy(ProxyType[] proxies, boolean isInitialize) { |
315 |
if (!instanceScope.getBoolean(PREF_HAS_MIGRATED, false)) { |
316 |
// Only set the migration bit when initializing |
317 |
if (isInitialize) |
318 |
instanceScope.putBoolean(PREF_HAS_MIGRATED, true); |
319 |
Preferences updatePrefs = instanceScope.parent().node("org.eclipse.update.core"); //$NON-NLS-1$ |
320 |
String httpProxyHost = getHostToMigrate(updatePrefs, isInitialize /* checkSystemProperties */); |
321 |
int port = getPortToMigrate(updatePrefs, isInitialize /* checkSystemProperties */); |
322 |
boolean httpProxyEnable = getEnablementToMigrate(updatePrefs, isInitialize /* checkSystemProperties */); |
323 |
if (httpProxyHost != null) { |
324 |
ProxyData proxyData = new ProxyData(IProxyData.HTTP_PROXY_TYPE, |
325 |
httpProxyHost, port, false, null); |
326 |
for (int i = 0; i < proxies.length; i++) { |
327 |
ProxyType type = proxies[i]; |
328 |
if (type.getName().equals(proxyData.getType())) { |
329 |
type.updatePreferencesIfMissing(proxyData); |
330 |
} |
331 |
} |
332 |
if (httpProxyEnable) { |
333 |
instanceScope.putBoolean(ProxyManager.PREF_ENABLED, true); |
334 |
} |
335 |
} |
336 |
} |
337 |
} |
338 |
|
339 |
private String getHostToMigrate(Preferences updatePrefs, boolean checkSystemProperties) { |
340 |
String httpProxyHost = updatePrefs.get(HTTP_PROXY_HOST, ""); //$NON-NLS-1$ |
341 |
if (checkSystemProperties && "".equals(httpProxyHost)) { //$NON-NLS-1$ |
342 |
httpProxyHost = System.getProperty("http.proxyHost", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
343 |
} |
344 |
if ("".equals(httpProxyHost)) //$NON-NLS-1$ |
345 |
httpProxyHost = null; |
346 |
updatePrefs.remove(HTTP_PROXY_HOST); |
347 |
return httpProxyHost; |
348 |
} |
349 |
|
350 |
private int getPortToMigrate(Preferences updatePrefs, boolean checkSystemProperties) { |
351 |
String httpProxyPort = updatePrefs.get(HTTP_PROXY_PORT, ""); //$NON-NLS-1$ |
352 |
if (checkSystemProperties && "".equals(httpProxyPort)) { //$NON-NLS-1$ |
353 |
httpProxyPort = System.getProperty("http.proxyPort", ""); //$NON-NLS-1$ //$NON-NLS-2$ |
354 |
} |
355 |
updatePrefs.remove(HTTP_PROXY_PORT); |
356 |
int port = -1; |
357 |
if (httpProxyPort != null && !"".equals(httpProxyPort)) //$NON-NLS-1$ |
358 |
try { |
359 |
port = Integer.parseInt(httpProxyPort); |
360 |
} catch (NumberFormatException e) { |
361 |
// Ignore |
362 |
} |
363 |
return port; |
364 |
} |
365 |
|
366 |
private boolean getEnablementToMigrate(Preferences updatePrefs, boolean checkSystemProperties) { |
367 |
boolean httpProxyEnable = false; |
368 |
if (checkSystemProperties && updatePrefs.get(HTTP_PROXY_ENABLE, null) == null) { |
369 |
httpProxyEnable = Boolean.getBoolean("http.proxySet"); //$NON-NLS-1$ |
370 |
} else { |
371 |
httpProxyEnable = updatePrefs.getBoolean(HTTP_PROXY_ENABLE, false); |
372 |
updatePrefs.remove(HTTP_PROXY_ENABLE); |
373 |
} |
374 |
return httpProxyEnable; |
375 |
} |
376 |
|
377 |
private static PreferenceManager createInstanceManager(String id) { |
378 |
PreferenceManager manager = new PreferenceManager(id); |
379 |
manager.currentScope = manager.instanceScope; |
380 |
return manager; |
381 |
} |
382 |
|
383 |
} |