blob: a8a4b1c0422a0457f760aba3128a0190b810a21e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.net;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* Provides set of methods to operate on preferences
*/
public class PreferenceManager {
public static final String ROOT = ""; //$NON-NLS-1$
private static final String PREF_HAS_MIGRATED = "org.eclipse.core.net.hasMigrated"; //$NON-NLS-1$
private static final int DEFAULT_INT = -1;
private static final String DEFAULT_STRING = null;
private static final boolean DEFAULT_BOOLEAN = false;
private static boolean migrated = false;
private IEclipsePreferences defaultScope;
private IEclipsePreferences currentScope;
private PreferenceManager(String id) {
this.defaultScope = DefaultScope.INSTANCE.getNode(id);
}
/**
* Creates the preferences manager for the node defined by id
* in configuration scope.
* @param id node name for which node should be created in configuration scope
* @return {@link PreferenceManager}
*/
public static PreferenceManager createConfigurationManager(String id) {
PreferenceManager manager = new PreferenceManager(id);
manager.currentScope = ConfigurationScope.INSTANCE.getNode(id);
return manager;
}
/**
* Checks if preference migration was already performed.
* @return <code>boolean</code>
*/
public boolean isMigrated() {
return migrated;
}
/**
* Returns the <code>boolean</code> value associated with the specified <code>key</code>
* for specified <code>node</code> in current scope.
*
* <p>
* Returns the value specified in the default scope if there is no value associated with the
* <code>key</code> in the current scope, the backing store is inaccessible, or if the associated
* value is something that can not be parsed as an integer value.
* Use {@link #putBoolean(String, String, boolean)} to set the value of this preference key.
* </p>
* @param node node
* @param key key whose associated value is to be returned as an <code>boolean</code>.
* @return the <code>boolean</code> value associated with <code>key</code>, or
* <code>false</code> if the associated value does not exist in either scope or cannot
* be interpreted as an <code>boolean</code>.
* @see #putBoolean(String, String, boolean)
*/
public boolean getBoolean(String node, String key) {
return currentScope.node(node).getBoolean(key, defaultScope.node(node).getBoolean(key, DEFAULT_BOOLEAN));
}
/**
* Returns the <code>int</code> value associated with the specified <code>key</code>
* for specified <code>node</code> in current scope.
*
* <p>
* Returns the value specified in the default scope if there is no value associated with the
* <code>key</code> in the current scope, the backing store is inaccessible, or if the associated
* value is something that can not be parsed as an integer value.
* Use {@link #putInt(String, String, int)} to set the value of this preference key.
* </p>
* @param node node
* @param key key whose associated value is to be returned as an <code>int</code>.
* @return the <code>int</code> value associated with <code>key</code>, or
* <code>-1</code> if the associated value does not exist in either scope or cannot
* be interpreted as an <code>int</code>.
* @see #putInt(String, String, int)
*/
public int getInt(String node, String key) {
return currentScope.node(node).getInt(key, defaultScope.node(node).getInt(key, DEFAULT_INT));
}
/**
* Returns the <code>String</code> value associated with the specified <code>key</code>
* for specified <code>node</code> in current scope.
*
* <p>
* Returns the value specified in the default scope if there is no value associated with the
* <code>key</code> in the current scope, the backing store is inaccessible, or if the associated
* value is something that can not be parsed as an integer value.
* Use {@link #putString(String, String, String)} to set the value of this preference key.
* </p>
* @param node node
* @param key key whose associated value is to be returned as an <code>String</code>.
* @return the <code>String</code> value associated with <code>key</code>, or
* <code>null</code> if the associated value does not exist in either scope or cannot
* be interpreted as an <code>String</code>.
* @see #putString(String, String, String)
*/
public String getString(String node, String key) {
return currentScope.node(node).get(key, defaultScope.node(node).get(key, DEFAULT_STRING));
}
/**
* Associates the specified <code>int</code> value with the specified key
* for specified <code>node</code> in current scope.
*
* @param node node
* @param key <code>key</code> with which the string form of value is to be associated.
* @param value <code>value</code> to be associated with <code>key</code>.
* @see #getInt(String, String)
*/
public void putInt(String node, String key, int value) {
currentScope.node(node).putInt(key, value);
}
/**
* Associates the specified <code>boolean</code> value with the specified key
* for specified <code>node</code> in current scope.
*
* @param node node
* @param key <code>key</code> with which the string form of value is to be associated.
* @param value <code>value</code> to be associated with <code>key</code>.
* @see #getBoolean(String, String)
*/
public void putBoolean(String node, String key, boolean value) {
currentScope.node(node).putBoolean(key, value);
}
/**
* Associates the specified <code>String</code> value with the specified key
* for specified <code>node</code> in current scope.
*
* @param node node
* @param key <code>key</code> with which the string form of value is to be associated.
* @param value <code>value</code> to be associated with <code>key</code>.
* @see #getString(String, String)
*/
public void putString(String node, String key, String value) {
currentScope.node(node).put(key, value);
}
/**
* Register the given listener for notification of preference changes.
* Calling this method multiple times with the same listener has no effect. The
* given listener argument must not be <code>null</code>.
*
* @param node node
* @param listener the preference change listener to register
* @see #removePreferenceChangeListener(String, IEclipsePreferences.IPreferenceChangeListener)
* @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener
*/
public void addPreferenceChangeListener(String node, IPreferenceChangeListener listener) {
((IEclipsePreferences)currentScope.node(node)).addPreferenceChangeListener(listener);
}
/**
* De-register the given listener from receiving notification of preference changes
* Calling this method multiple times with the same listener has no
* effect. The given listener argument must not be <code>null</code>.
* @param node node
* @param listener the preference change listener to remove
* @see #addPreferenceChangeListener(String, IEclipsePreferences.IPreferenceChangeListener)
* @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener
*/
public void removePreferenceChangeListener(String node, IPreferenceChangeListener listener) {
((IEclipsePreferences)currentScope.node(node)).removePreferenceChangeListener(listener);
}
/**
* Register the given listener for changes to this node.
* Calling this method multiple times with the same listener has no effect. The
* given listener argument must not be <code>null</code>.
*
* @param node node
* @param listener the preference change listener to register
* @see #removeNodeChangeListener(String, IEclipsePreferences.INodeChangeListener)
* @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener
*/
public void addNodeChangeListener(String node, INodeChangeListener listener) {
((IEclipsePreferences)currentScope.node(node)).addNodeChangeListener(listener);
}
/**
* De-register the given listener from receiving event change notifications for this node.
* Calling this method multiple times with the same listener has no
* effect. The given listener argument must not be <code>null</code>.
* @param node node
* @param listener the preference change listener to remove
* @see #addPreferenceChangeListener(String, IEclipsePreferences.IPreferenceChangeListener)
* @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener
*/
public void removeNodeChangeListener(String node, INodeChangeListener listener) {
((IEclipsePreferences)currentScope.node(node)).removeNodeChangeListener(listener);
}
/**
* Removes this node and all of its descendants,
* invalidating any properties contained in the removed nodes.
* @param node name of a node which should be removed
* @throws BackingStoreException - if this operation cannot be completed
* due to a failure in the backing store, or inability to communicate with it.
*/
public void removeNode(String node) throws BackingStoreException {
currentScope.node(node).removeNode();
}
/**
* Forces any changes in the contents of current scope
* and its descendants to the persistent store.
* @throws BackingStoreException - if this operation cannot be completed
* due to a failure in the backing store, or inability to communicate with it.
*/
public void flush() throws BackingStoreException {
currentScope.flush();
}
/**
* Migrate preferences from instance scope to current scope.
* @param proxies proxy types for which migration should be performed {@link ProxyType}
*/
public void migrate(ProxyType[] proxies) {
migrated = true;
if (currentScope.getBoolean(PREF_HAS_MIGRATED, false)
|| currentScope.name().equals(InstanceScope.SCOPE)) {
return;
}
currentScope.putBoolean(PREF_HAS_MIGRATED, true);
migrateInstanceScopePreferences(InstanceScope.INSTANCE.getNode(Activator.ID), currentScope, proxies, true);
}
void migrateInstanceScopePreferences(Preferences instanceScope, Preferences configuration, ProxyType[] proxies, boolean isInitialize) {
migrateUpdateHttpProxy(instanceScope, proxies, isInitialize);
// migrate enabled status
if (configuration.get(ProxyManager.PREF_ENABLED, null) == null) {
String instanceEnabled = instanceScope.get(ProxyManager.PREF_ENABLED, null);
if (instanceEnabled != null)
configuration.put(ProxyManager.PREF_ENABLED, instanceEnabled);
}
// migrate enabled status
if (configuration.get(ProxyManager.PREF_OS, null) == null) {
String instanceEnabled = instanceScope.get(ProxyManager.PREF_OS, null);
if (instanceEnabled != null)
configuration.put(ProxyManager.PREF_OS, instanceEnabled);
}
// migrate non proxied hosts if not already set
if (configuration.get(ProxyManager.PREF_NON_PROXIED_HOSTS, null) == null) {
String instanceNonProxiedHosts = instanceScope.get(ProxyManager.PREF_NON_PROXIED_HOSTS, null);
if (instanceNonProxiedHosts != null) {
configuration.put(ProxyManager.PREF_NON_PROXIED_HOSTS, instanceNonProxiedHosts);
}
}
// migrate proxy data
PreferenceManager instanceManager = PreferenceManager.createInstanceManager(instanceScope);
for (int i = 0; i < proxies.length; i++) {
ProxyType type = proxies[i];
IProxyData data = type.getProxyData(ProxyType.DO_NOT_VERIFY);
if (data.getHost() == null) {
ProxyType instanceType = new ProxyType(type.getName(), instanceManager);
IProxyData instanceData = instanceType.getProxyData(ProxyType.DO_NOT_VERIFY);
if (instanceData.getHost() != null)
type.setProxyData(instanceData);
}
}
// if this an import we should remove the old node
if (!isInitialize) {
try {
instanceScope.removeNode();
} catch (BackingStoreException e) {
// ignore
}
}
}
private void migrateUpdateHttpProxy(Preferences instanceScope, ProxyType[] proxies, boolean isInitialize) {
if (!instanceScope.getBoolean(PREF_HAS_MIGRATED, false)) {
// Only set the migration bit when initializing
if (isInitialize)
instanceScope.putBoolean(PREF_HAS_MIGRATED, true);
String httpProxyHost = getHostToMigrate(isInitialize /* checkSystemProperties */);
int port = getPortToMigrate(isInitialize /* checkSystemProperties */);
boolean httpProxyEnable = getEnablementToMigrate(isInitialize /* checkSystemProperties */);
if (httpProxyHost != null) {
ProxyData proxyData = new ProxyData(IProxyData.HTTP_PROXY_TYPE,
httpProxyHost, port, false, null);
for (int i = 0; i < proxies.length; i++) {
ProxyType type = proxies[i];
if (type.getName().equals(proxyData.getType())) {
type.updatePreferencesIfMissing(proxyData);
}
}
if (httpProxyEnable) {
instanceScope.putBoolean(ProxyManager.PREF_ENABLED, true);
}
}
}
}
private String getHostToMigrate(boolean checkSystemProperties) {
String httpProxyHost = ""; //$NON-NLS-1$
if (checkSystemProperties && "".equals(httpProxyHost)) { //$NON-NLS-1$
httpProxyHost = System.getProperty("http.proxyHost", ""); //$NON-NLS-1$ //$NON-NLS-2$
}
if ("".equals(httpProxyHost)) //$NON-NLS-1$
httpProxyHost = null;
return httpProxyHost;
}
private int getPortToMigrate(boolean checkSystemProperties) {
String httpProxyPort = ""; //$NON-NLS-1$
if (checkSystemProperties && "".equals(httpProxyPort)) { //$NON-NLS-1$
httpProxyPort = System.getProperty("http.proxyPort", ""); //$NON-NLS-1$ //$NON-NLS-2$
}
int port = -1;
if (httpProxyPort != null && !"".equals(httpProxyPort)) //$NON-NLS-1$
try {
port = Integer.parseInt(httpProxyPort);
} catch (NumberFormatException e) {
// Ignore
}
return port;
}
private boolean getEnablementToMigrate(boolean checkSystemProperties) {
boolean httpProxyEnable = false;
if (checkSystemProperties) {
httpProxyEnable = Boolean.getBoolean("http.proxySet"); //$NON-NLS-1$
}
return httpProxyEnable;
}
private static PreferenceManager createInstanceManager(Preferences instance) {
PreferenceManager manager = new PreferenceManager(Activator.ID);
manager.currentScope = (IEclipsePreferences) instance;
return manager;
}
}