Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDJ Houghton2009-12-01 18:34:24 +0000
committerDJ Houghton2009-12-01 18:34:24 +0000
commitd0667de09b490da27f357759f89accbac42dbbff (patch)
tree01f5feecf138e200552aede396fbd2f8e23b5969 /bundles/org.eclipse.equinox.preferences/src
parent7143726365b6921b405cf0ce6e067aefe10224e5 (diff)
downloadrt.equinox.bundles-d0667de09b490da27f357759f89accbac42dbbff.tar.gz
rt.equinox.bundles-d0667de09b490da27f357759f89accbac42dbbff.tar.xz
rt.equinox.bundles-d0667de09b490da27f357759f89accbac42dbbff.zip
Bug 293331 - API to determine when preference settings have been overridden
Diffstat (limited to 'bundles/org.eclipse.equinox.preferences/src')
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/BundleDefaultPreferences.java111
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java91
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java2
-rw-r--r--bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/runtime/preferences/BundleDefaultsScope.java74
4 files changed, 271 insertions, 7 deletions
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/BundleDefaultPreferences.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/BundleDefaultPreferences.java
new file mode 100644
index 000000000..acbf2cd94
--- /dev/null
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/BundleDefaultPreferences.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.preferences;
+
+import java.util.*;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.*;
+
+/**
+ * This class represents a preference node in the "bundle_defaults" scope. This scope is
+ * used to represent default values which are set by the bundle in either its preference
+ * initializer or in a file included with the bundle.
+ *
+ * This differs from the regular default scope because it does not contain values set
+ * by the product preference customization or the command-line.
+ *
+ * @since 3.3
+ */
+public class BundleDefaultPreferences extends EclipsePreferences {
+
+ private static Set loadedNodes = Collections.synchronizedSet(new HashSet());
+ private String qualifier;
+ private int segmentCount;
+ private IEclipsePreferences loadLevel;
+
+ /*
+ * Default constructor.
+ */
+ public BundleDefaultPreferences() {
+ this(null, null);
+ }
+
+ private BundleDefaultPreferences(EclipsePreferences parent, String name) {
+ super(parent, name);
+ // cache the segment count
+ IPath path = new Path(absolutePath());
+ segmentCount = path.segmentCount();
+ if (segmentCount < 2)
+ return;
+
+ // cache the qualifier
+ String scope = path.segment(0);
+ if (BundleDefaultsScope.SCOPE.equals(scope))
+ qualifier = path.segment(1);
+
+ // cache the location
+ if (qualifier == null)
+ return;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.preferences.EclipsePreferences#getLoadLevel()
+ */
+ protected IEclipsePreferences getLoadLevel() {
+ if (loadLevel == null) {
+ if (qualifier == null)
+ return null;
+ // Make it relative to this node rather than navigating to it from the root.
+ // Walk backwards up the tree starting at this node.
+ // This is important to avoid a chicken/egg thing on startup.
+ IEclipsePreferences node = this;
+ for (int i = 2; i < segmentCount; i++)
+ node = (IEclipsePreferences) node.parent();
+ loadLevel = node;
+ }
+ return loadLevel;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.preferences.EclipsePreferences#isAlreadyLoaded(org.eclipse.core.runtime.preferences.IEclipsePreferences)
+ */
+ protected boolean isAlreadyLoaded(IEclipsePreferences node) {
+ return loadedNodes.contains(node.name());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.preferences.EclipsePreferences#loaded()
+ */
+ protected void loaded() {
+ loadedNodes.add(name());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.preferences.EclipsePreferences#load()
+ */
+ protected void load() {
+ // ensure that the same node in the "default" scope is loaded so this one is
+ // initialized properly
+ String relativePath = DefaultPreferences.getScopeRelativePath(absolutePath());
+ if (relativePath != null) {
+ // touch the node to force a load
+ PreferencesService.getDefault().getRootNode().node(DefaultScope.SCOPE).node(relativePath);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.preferences.EclipsePreferences#internalCreate(org.eclipse.core.internal.preferences.EclipsePreferences, java.lang.String, java.lang.Object)
+ */
+ protected EclipsePreferences internalCreate(EclipsePreferences nodeParent, String nodeName, Object context) {
+ return new BundleDefaultPreferences(nodeParent, nodeName);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java
index c42f904b2..d96f1ab88 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/DefaultPreferences.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2009 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
@@ -18,10 +18,12 @@ import java.util.*;
import org.eclipse.core.internal.preferences.exchange.IProductPreferencesService;
import org.eclipse.core.internal.runtime.RuntimeLog;
import org.eclipse.core.runtime.*;
+import org.eclipse.core.runtime.preferences.BundleDefaultsScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.service.prefs.Preferences;
import org.osgi.util.tracker.ServiceTracker;
/**
@@ -39,6 +41,7 @@ public class DefaultPreferences extends EclipsePreferences {
private static Properties productTranslation;
private static Properties commandLineCustomization;
private EclipsePreferences loadLevel;
+ private Thread initializingThread;
// cached values
private String qualifier;
@@ -229,16 +232,90 @@ public class DefaultPreferences extends EclipsePreferences {
* @see org.eclipse.core.internal.preferences.EclipsePreferences#load()
*/
protected void load() {
- loadDefaults();
- }
-
- private void loadDefaults() {
- applyRuntimeDefaults();
- applyBundleDefaults();
+ setInitializingBundleDefaults();
+ try {
+ applyRuntimeDefaults();
+ applyBundleDefaults();
+ } finally {
+ clearInitializingBundleDefaults();
+ }
applyProductDefaults();
applyCommandLineDefaults();
}
+ /* (non-Javadoc)
+ * @see org.eclipse.core.internal.preferences.EclipsePreferences#internalPut(java.lang.String, java.lang.String)
+ */
+ protected String internalPut(String key, String newValue) {
+ // set the value in this node
+ String result = super.internalPut(key, newValue);
+
+ // if we are setting the bundle defaults, then set the corresponding value in
+ // the bundle_defaults scope
+ if (isInitializingBundleDefaults()) {
+ String relativePath = getScopeRelativePath(absolutePath());
+ if (relativePath != null) {
+ Preferences node = PreferencesService.getDefault().getRootNode().node(BundleDefaultsScope.SCOPE).node(relativePath);
+ node.put(key, newValue);
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Set that we are in the middle of initializing the bundle defaults.
+ * This is stored on the load level so we know where to look when
+ * we are setting values on sub-nodes.
+ */
+ private void setInitializingBundleDefaults() {
+ IEclipsePreferences node = getLoadLevel();
+ if (node instanceof DefaultPreferences) {
+ DefaultPreferences loader = (DefaultPreferences) node;
+ loader.initializingThread = Thread.currentThread();
+ }
+ }
+
+ /*
+ * Clear the bit saying we are in the middle of initializing the bundle defaults.
+ * This is stored on the load level so we know where to look when
+ * we are setting values on sub-nodes.
+ */
+ private void clearInitializingBundleDefaults() {
+ IEclipsePreferences node = getLoadLevel();
+ if (node instanceof DefaultPreferences) {
+ DefaultPreferences loader = (DefaultPreferences) node;
+ loader.initializingThread = null;
+ }
+ }
+
+ /*
+ * Are we in the middle of initializing defaults from the bundle
+ * initializer or found in the bundle itself? Look on the load level in
+ * case we are in a sub-node.
+ */
+ private boolean isInitializingBundleDefaults() {
+ IEclipsePreferences node = getLoadLevel();
+ if (node instanceof DefaultPreferences) {
+ DefaultPreferences loader = (DefaultPreferences) node;
+ return loader.initializingThread == Thread.currentThread();
+ }
+ return false;
+ }
+
+ /*
+ * Return a path which is relative to the scope of this node.
+ * e.g. com.example.foo for /instance/com.example.foo
+ */
+ protected static String getScopeRelativePath(String absolutePath) {
+ // shouldn't happen but handle empty or root
+ if (absolutePath.length() < 2)
+ return null;
+ int index = absolutePath.indexOf('/', 1);
+ if (index == -1 || index + 1 >= absolutePath.length())
+ return null;
+ return absolutePath.substring(index + 1);
+ }
+
private Properties loadProperties(URL url) {
Properties result = new Properties();
if (url == null)
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java
index a563f9876..62df2fc7d 100644
--- a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/internal/preferences/PreferencesService.java
@@ -370,6 +370,8 @@ public class PreferencesService implements IPreferencesService {
}
private void initializeDefaultScopes() {
+ defaultScopes.put(BundleDefaultsScope.SCOPE, new BundleDefaultPreferences());
+ root.addChild(BundleDefaultsScope.SCOPE, null);
defaultScopes.put(DefaultScope.SCOPE, new DefaultPreferences());
root.addChild(DefaultScope.SCOPE, null);
defaultScopes.put(InstanceScope.SCOPE, new InstancePreferences());
diff --git a/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/runtime/preferences/BundleDefaultsScope.java b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/runtime/preferences/BundleDefaultsScope.java
new file mode 100644
index 000000000..bbeb9ab6b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.preferences/src/org/eclipse/core/runtime/preferences/BundleDefaultsScope.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.runtime.preferences;
+
+import org.eclipse.core.internal.preferences.AbstractScope;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Object representing the bundle defaults scope in the Eclipse preferences
+ * hierarchy. Can be used as a context for searching for preference
+ * values (in the IPreferencesService APIs) or for determining the
+ * correct preference node to set values in the store.
+ * <p>
+ * The bundle defaults are the defaults are default values which have
+ * been set either by the bundle's preference initializer or by a customization
+ * file supplied with the bundle.
+ * <p>
+ * Bundle default preferences are not persisted to disk.
+ * </p>
+ * <p>
+ * The path for preferences defined in the bundle defaults scope hierarchy
+ * is as follows: <code>/bundle_defaults/&lt;qualifier&gt;</code>
+ * </p>
+ * <p>
+ * This class is not intended to be subclassed. This class may be instantiated.
+ * </p>
+ * @since 3.3
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public final class BundleDefaultsScope extends AbstractScope implements IScopeContext {
+
+ /**
+ * String constant (value of <code>"default"</code>) used for the
+ * scope name for the default preference scope.
+ */
+ public static final String SCOPE = "bundle_defaults"; //$NON-NLS-1$
+
+ /**
+ * Create and return a new default scope instance.
+ */
+ public BundleDefaultsScope() {
+ super();
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.preferences.IScopeContext#getName()
+ */
+ public String getName() {
+ return SCOPE;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.preferences.IScopeContext#getNode(java.lang.String)
+ */
+ public IEclipsePreferences getNode(String qualifier) {
+ return super.getNode(qualifier);
+ }
+
+ /*
+ * @see org.eclipse.core.runtime.preferences.IScopeContext#getLocation()
+ */
+ public IPath getLocation() {
+ // We don't persist defaults so return null.
+ return null;
+ }
+}

Back to the top