Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2006-02-16 15:29:01 -0500
committerPascal Rapicault2006-02-16 15:29:01 -0500
commitfdf4ae81c01c37857f9f915106f1a75586e17304 (patch)
tree411a837072c75cfd51cdd4ac4d7ba4fa83ff4855
parent83dc53593d83b80e40b8a874184772cc554f1324 (diff)
downloadrt.equinox.bundles-fdf4ae81c01c37857f9f915106f1a75586e17304.tar.gz
rt.equinox.bundles-fdf4ae81c01c37857f9f915106f1a75586e17304.tar.xz
rt.equinox.bundles-fdf4ae81c01c37857f9f915106f1a75586e17304.zip
Bug 127783 - Clean up RegistryStrategy from the org.eclipse.equinox.registryv20060216
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java48
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java23
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/EquinoxRegistryStrategy.java78
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java75
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/RegistryFactory.java7
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/dynamichelpers/ExtensionTracker.java2
-rw-r--r--bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/spi/RegistryStrategy.java126
7 files changed, 186 insertions, 173 deletions
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java
index 0dbf750b..91eba625 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/ExtensionRegistry.java
@@ -541,10 +541,7 @@ public class ExtensionRegistry implements IExtensionRegistry {
if (registryStrategy != null)
strategy = registryStrategy;
else
- strategy = new RegistryStrategy(null, true);
-
- // create the file manager right away
- setFileManager(strategy.getStorage(), strategy.isCacheReadOnly());
+ strategy = new RegistryStrategy(null, null);
this.masterToken = masterToken;
this.userToken = userToken;
@@ -725,39 +722,30 @@ public class ExtensionRegistry implements IExtensionRegistry {
}
public long computeState() {
- return strategy.cacheComputeState();
+ return strategy.getContainerTimestamp();
}
public long computeTimeStamp() {
- return strategy.cacheComputeTimeStamp();
+ return strategy.getContributionsTimestamp();
}
- // Check that cache is actually present in the specified location
+ // Find the first location that contains a cache table file and set file manager to it.
protected boolean checkCache() {
- File cacheFile = null;
- if (cacheStorageManager != null) {
- try {
- cacheFile = cacheStorageManager.lookup(TableReader.getTestFileName(), false);
- } catch (IOException e) {
- //Ignore the exception. The registry will be rebuilt from the xml files.
- }
- }
- if (cacheFile != null && cacheFile.isFile())
- return true; // primary location is fine
-
- // check alternative cache location if available
- File alternativeBase = strategy.cacheAlternativeLocation();
- if (alternativeBase != null) {
- setFileManager(alternativeBase, true);
+ for (int index = 0; index < strategy.getLocationsLength(); index++) {
+ File possibleCacheLocation = strategy.getStorage(index);
+ if (possibleCacheLocation == null)
+ break; // bail out on the first null
+ setFileManager(possibleCacheLocation, strategy.isCacheReadOnly(index));
if (cacheStorageManager != null) {
// check this new location:
- cacheFile = null;
+ File cacheFile = null;
try {
cacheFile = cacheStorageManager.lookup(TableReader.getTestFileName(), false);
} catch (IOException e) {
//Ignore the exception. The registry will be rebuilt from the xml files.
}
- return (cacheFile != null && cacheFile.isFile());
+ if (cacheFile != null && cacheFile.isFile())
+ return true; // found the appropriate location
}
}
return false;
@@ -854,17 +842,14 @@ public class ExtensionRegistry implements IExtensionRegistry {
/**
* Access check for add/remove operations:
- * a) for modifiable registry key is not required (null is fine)
- * b) for non-modifiable registry master key allows all operations
- * c) for non-modifiable registry user key allows modifications of non-persisted elements
+ * - Master key allows all operations
+ * - User key allows modifications of non-persisted elements
*
* @param key key to the registry supplied by the user
* @param persist true if operation affects persisted elements
* @return true is the key grants read/write access to the registry
*/
private boolean checkReadWriteAccess(Object key, boolean persist) {
- if (strategy.isModifiable())
- return true;
if (masterToken == key)
return true;
if (userToken == key && !persist)
@@ -880,7 +865,7 @@ public class ExtensionRegistry implements IExtensionRegistry {
RegistryContributor internalContributor = (RegistryContributor) contributor;
registryObjects.addContributor(internalContributor); // only adds a contributor if it is not already present
-
+
String ownerName = internalContributor.getActualName();
String message = NLS.bind(RegistryMessages.parse_problems, ownerName);
MultiStatus problems = new MultiStatus(RegistryMessages.OWNER_NAME, ExtensionsParser.PARSE_PROBLEM, message, null);
@@ -924,8 +909,6 @@ public class ExtensionRegistry implements IExtensionRegistry {
* If the registry is not modifiable, this method is an access controlled method.
* Proper token should be passed as an argument for non-modifiable registries.
* </p>
- * @see org.eclipse.core.runtime.spi.RegistryStrategy#isModifiable()
- *
* @param identifier Id of the extension point. If non-qualified names is supplied,
* it will be converted internally into a fully qualified name
* @param contributor the contributor of this extension point
@@ -998,7 +981,6 @@ public class ExtensionRegistry implements IExtensionRegistry {
* If the registry is not modifiable, this method is an access controlled method.
* Proper token should be passed as an argument for non-modifiable registries.
* </p>
- * @see org.eclipse.core.runtime.spi.RegistryStrategy#isModifiable()
* @see org.eclipse.core.internal.registry.spi.ConfigurationElementDescription
*
* @param identifier Id of the extension. If non-qualified name is supplied,
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java
index 0fea3b04..f183ff9a 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/Activator.java
@@ -102,9 +102,28 @@ public class Activator implements BundleActivator {
if ("true".equals(bundleContext.getProperty(IRegistryConstants.PROP_REGISTRY_NULL_USER_TOKEN))) //$NON-NLS-1$
userRegistryKey = null;
+ // Determine primary and alternative registry locations. Eclipse extension registry cache
+ // can be found in one of the two locations:
+ // a) in the local configuration area (standard location passed in by the platform) -> priority
+ // b) in the shared configuration area (typically, shared install is used)
+ File[] registryLocations;
+ boolean[] readOnlyLocations;
+
Location configuration = OSGIUtils.getDefault().getConfigurationLocation();
- File theStorageDir = new File(configuration.getURL().getPath() + '/' + STORAGE_DIR);
- EquinoxRegistryStrategy registryStrategy = new EquinoxRegistryStrategy(theStorageDir, configuration.isReadOnly(), masterRegistryKey);
+ File primaryDir = new File(configuration.getURL().getPath() + '/' + STORAGE_DIR);
+ boolean primaryReadOnly = configuration.isReadOnly();
+
+ Location parentLocation = configuration.getParentLocation();
+ if (parentLocation != null) {
+ File secondaryDir = new File(parentLocation.getURL().getFile() + '/' + IRegistryConstants.RUNTIME_NAME);
+ registryLocations = new File[] {primaryDir, secondaryDir};
+ readOnlyLocations = new boolean[] {primaryReadOnly, true}; // secondary Eclipse location is always read only
+ } else {
+ registryLocations = new File[] {primaryDir};
+ readOnlyLocations = new boolean[] {primaryReadOnly};
+ }
+
+ EquinoxRegistryStrategy registryStrategy = new EquinoxRegistryStrategy(registryLocations, readOnlyLocations, masterRegistryKey);
defaultRegistry = RegistryFactory.createRegistry(registryStrategy, masterRegistryKey, userRegistryKey);
registryRegistration = Activator.getContext().registerService(IExtensionRegistry.class.getName(), defaultRegistry, new Hashtable());
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/EquinoxRegistryStrategy.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/EquinoxRegistryStrategy.java
index 907f88c7..26968a69 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/EquinoxRegistryStrategy.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/EquinoxRegistryStrategy.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
+ * Copyright (c) 2005, 2006 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
@@ -11,18 +11,23 @@
package org.eclipse.core.internal.registry.osgi;
import java.io.File;
-import org.eclipse.core.internal.registry.IRegistryConstants;
+import java.util.Map;
import org.eclipse.core.internal.runtime.RuntimeLog;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.spi.RegistryStrategy;
import org.eclipse.osgi.service.resolver.PlatformAdmin;
/**
- * The registry strategy used by the Equinox extension registry. Adds to the OSGi registry:
- * - Use debug information supplied via .options files
- * - Use Eclipse logging
- * - Use Eclipse platform state for cache validation
- * - Supplied alternative cache location (primarily used with shared installs)
+ * The registry strategy used by the Equinox extension registry. Adds to the
+ * OSGi registry:
+ * <p><ul>
+ * <li>Use debug information supplied via .options files</li>
+ * <li>Use Eclipse logging - Use Eclipse platform state for cache validation</li>
+ * <li>Event scheduling is done using Eclipse job scheduling mechanism</li>
+ * </ul></p>
*
* @since org.eclipse.equinox.registry 3.2
*/
@@ -35,7 +40,7 @@ public class EquinoxRegistryStrategy extends RegistryStrategyOSGI {
private static boolean DEBUG_ECLIPSE_REGISTRY = OSGIUtils.getDefault().getBooleanDebugOption(OPTION_DEBUG, false);
private static boolean DEBUG_ECLIPSE_EVENTS = OSGIUtils.getDefault().getBooleanDebugOption(OPTION_DEBUG_EVENTS, false);
- public EquinoxRegistryStrategy(File theStorageDir, boolean cacheReadOnly, Object key) {
+ public EquinoxRegistryStrategy(File[] theStorageDir, boolean[] cacheReadOnly, Object key) {
super(theStorageDir, cacheReadOnly, key);
}
@@ -46,31 +51,52 @@ public class EquinoxRegistryStrategy extends RegistryStrategyOSGI {
public boolean debugRegistryEvents() {
return DEBUG_ECLIPSE_EVENTS;
}
-
+
public final void log(IStatus status) {
RuntimeLog.log(status);
}
- public long cacheComputeState() {
+ public long getContainerTimestamp() {
PlatformAdmin admin = OSGIUtils.getDefault().getPlatformAdmin();
return admin == null ? -1 : admin.getState(false).getTimeStamp();
}
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // Use Eclipse job scheduling mechanism
+
+ private final static class ExtensionEventDispatcherJob extends Job {
+ // an "identy rule" that forces extension events to be queued
+ private final static ISchedulingRule EXTENSION_EVENT_RULE = new ISchedulingRule() {
+ public boolean contains(ISchedulingRule rule) {
+ return rule == this;
+ }
+
+ public boolean isConflicting(ISchedulingRule rule) {
+ return rule == this;
+ }
+ };
+ private Map deltas;
+ private Object[] listenerInfos;
+ private Object registry;
+
+ public ExtensionEventDispatcherJob(Object[] listenerInfos, Map deltas, Object registry) {
+ // name not NL'd since it is a system job
+ super("Registry event dispatcher"); //$NON-NLS-1$
+ setSystem(true);
+ this.listenerInfos = listenerInfos;
+ this.deltas = deltas;
+ this.registry = registry;
+ // all extension event dispatching jobs use this rule
+ setRule(EXTENSION_EVENT_RULE);
+ }
+
+ public IStatus run(IProgressMonitor monitor) {
+ return RegistryStrategy.processChangeEvent(listenerInfos, deltas, registry);
+ }
+ }
- // Eclipse extension registry cache can be found in one of the two locations:
- // a) in the local configuration area (standard location passed in by the platform)
- // b) in the shared configuration area (typically, shared install is used)
- public File cacheAlternativeLocation() {
- // In debug be careful of LocationManager.computeSharedConfigurationLocation
- // and PROP_SHARED_CONFIG_AREA = "osgi.sharedConfiguration.area" - it
- // seems to work differently comparing to stand-alone execution.
- Location currentLocation = OSGIUtils.getDefault().getConfigurationLocation();
- if (currentLocation == null)
- return null;
- Location parentLocation = currentLocation.getParentLocation();
- if (parentLocation == null)
- return null;
- String theRegistryLocation = parentLocation.getURL().getFile() + '/' + IRegistryConstants.RUNTIME_NAME;
- return new File(theRegistryLocation);
+ public final void scheduleChangeEvent(Object[] listeners, Map deltas, Object registry) {
+ new ExtensionEventDispatcherJob(listeners, deltas, registry).schedule();
}
}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java
index fbc03f84..4e94909a 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/internal/registry/osgi/RegistryStrategyOSGI.java
@@ -14,16 +14,12 @@ import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
-import java.util.Map;
import java.util.ResourceBundle;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.internal.registry.*;
import org.eclipse.core.internal.runtime.ResourceTranslator;
import org.eclipse.core.runtime.*;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.spi.RegistryContributor;
-import org.eclipse.core.runtime.spi.RegistryStrategy;
+import org.eclipse.core.runtime.spi.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -31,15 +27,13 @@ import org.osgi.util.tracker.ServiceTracker;
/**
* The registry strategy that can be used in OSGi world. It provides the following functionality:
- *
- * - Event scheduling is done using Eclipse job scheduling mechanism
- * - Translation is done with Equinox ResourceTranslator
- * - Uses OSGi bundles for namespace resolution (contributors: plugins and fragments)
- * - Registry is filled with information stored in plugin.xml / fragment.xml of OSGi bundles
- * - Uses bunlde-based class loading to create executable extensions
- * - Performs registry validation based on the time stamps of the plugin.xml / fragment.xml files
- * - XML parser is obtained via an OSGi service
- *
+ * <p><ul>
+ * <li>Translation is done with ResourceTranslator</li>
+ * <li>Registry is filled with information stored in plugin.xml / fragment.xml of OSGi bundles</li>
+ * <li>Uses bunlde-based class loading to create executable extensions</li>
+ * <li>Performs registry validation based on the time stamps of the plugin.xml / fragment.xml files</li>
+ * <li>XML parser is obtained via an OSGi service</li>
+ * </ul></p>
* @see RegistryFactory#setRegistryProvider(IRegistryProvider)
* @since org.eclipse.equinox.registry 3.2
*/
@@ -67,62 +61,21 @@ public class RegistryStrategyOSGI extends RegistryStrategy {
private ServiceTracker xmlTracker = null;
/**
- * @param theStorageDir - file system directory to store cache files; might be null
- * @param cacheReadOnly - true: cache is read only; false: cache is read/write
+ * @param theStorageDir - array of file system directories to store cache files; might be null
+ * @param cacheReadOnly - array of read only attributes. True: cache at this location is read
+ * only; false: cache is read/write
* @param key - control key for the registry (should be the same key as used in
* the RegistryManager#createExtensionRegistry() of this registry
*/
- public RegistryStrategyOSGI(File theStorageDir, boolean cacheReadOnly, Object key) {
+ public RegistryStrategyOSGI(File[] theStorageDir, boolean[] cacheReadOnly, Object key) {
super(theStorageDir, cacheReadOnly);
token = key;
}
- public boolean isModifiable() {
- return false; // Clients are not allowed to add information into this registry
- }
-
- public String translate(String key, ResourceBundle resources) {
+ public final String translate(String key, ResourceBundle resources) {
return ResourceTranslator.getResourceString(null, key, resources);
}
- //////////////////////////////////////////////////////////////////////////////////////////
- // Use Eclipse job scheduling mechanism
-
- private final static class ExtensionEventDispatcherJob extends Job {
- // an "identy rule" that forces extension events to be queued
- private final static ISchedulingRule EXTENSION_EVENT_RULE = new ISchedulingRule() {
- public boolean contains(ISchedulingRule rule) {
- return rule == this;
- }
-
- public boolean isConflicting(ISchedulingRule rule) {
- return rule == this;
- }
- };
- private Map deltas;
- private Object[] listenerInfos;
- private Object registry;
-
- public ExtensionEventDispatcherJob(Object[] listenerInfos, Map deltas, Object registry) {
- // name not NL'd since it is a system job
- super("Registry event dispatcher"); //$NON-NLS-1$
- setSystem(true);
- this.listenerInfos = listenerInfos;
- this.deltas = deltas;
- this.registry = registry;
- // all extension event dispatching jobs use this rule
- setRule(EXTENSION_EVENT_RULE);
- }
-
- public IStatus run(IProgressMonitor monitor) {
- return RegistryStrategy.processChangeEvent(listenerInfos, deltas, registry);
- }
- }
-
- public void scheduleChangeEvent(Object[] listeners, Map deltas, Object registry) {
- new ExtensionEventDispatcherJob(listeners, deltas, registry).schedule();
- }
-
////////////////////////////////////////////////////////////////////////////////////////
// Use OSGi bundles for namespace resolution (contributors: plugins and fragments)
@@ -252,7 +205,7 @@ public class RegistryStrategyOSGI extends RegistryStrategy {
return !("true".equalsIgnoreCase(RegistryProperties.getProperty(IRegistryConstants.PROP_NO_LAZY_CACHE_LOADING))); //$NON-NLS-1$
}
- public long cacheComputeTimeStamp() {
+ public long getContributionsTimestamp() {
BundleContext context = Activator.getContext();
if (context == null)
return 0;
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/RegistryFactory.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/RegistryFactory.java
index b91c69a7..660432cb 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/RegistryFactory.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/RegistryFactory.java
@@ -65,11 +65,12 @@ public final class RegistryFactory {
* adopters on the understanding that any code that uses this API will almost certainly
* be broken (repeatedly) as the API evolves.
* </p>
- * @param storageDir - file system directory to store cache files; might be null
- * @param cacheReadOnly - true: cache is read only; false: cache is read/write
+ * @param theStorageDir - array of file system directories to store cache files; might be null
+ * @param cacheReadOnly - array of read only attributes. True: cache at this location is read
+ * only; false: cache is read/write
* @param token - control token for the registry
*/
- public static RegistryStrategy createOSGiStrategy(File storageDir, boolean cacheReadOnly, Object token) {
+ public static RegistryStrategy createOSGiStrategy(File[] storageDir, boolean[] cacheReadOnly, Object token) {
return new RegistryStrategyOSGI(storageDir, cacheReadOnly, token);
}
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/dynamichelpers/ExtensionTracker.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/dynamichelpers/ExtensionTracker.java
index b7cf074c..d9571e09 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/dynamichelpers/ExtensionTracker.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/dynamichelpers/ExtensionTracker.java
@@ -61,7 +61,7 @@ public class ExtensionTracker implements IExtensionTracker, IRegistryChangeListe
}
/* (non-Javadoc)
- * @see IExtensionTracker@registerHandler(IExtensionChangeHandler, IFilter)
+ * @see org.eclipse.core.runtime.dynamichelpers.IExtensionTracker#registerHandler(org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler, org.eclipse.core.runtime.dynamichelpers.IFilter)
*/
public void registerHandler(IExtensionChangeHandler handler, IFilter filter) {
synchronized (lock) {
diff --git a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/spi/RegistryStrategy.java b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/spi/RegistryStrategy.java
index dbc040b6..60a6e862 100644
--- a/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/spi/RegistryStrategy.java
+++ b/bundles/org.eclipse.equinox.registry/src/org/eclipse/core/runtime/spi/RegistryStrategy.java
@@ -46,38 +46,65 @@ public class RegistryStrategy {
/**
* File system directory to store cache files; might be null
*/
- private final File theStorageDir;
+ private final File[] theStorageDir;
/**
* Specifies if the registry file cache is read only
*/
- private final boolean cacheReadOnly;
+ private final boolean[] cacheReadOnly;
/**
- * Public constructor.
- *
- * @param theStorageDir - file system directory to store cache files; might be null
- * @param cacheReadOnly - true: cache is read only; false: cache is read/write
+ * Public constructor; accepts list of the possible cache locations.
+ * <p>
+ * Locations in the list will be checked sequentially (starting with index 0)
+ * until cache files are found. The first location containing cache files will
+ * be used. It will be assigned the "read only" attribute specified in the
+ * corresponding slot of the cacheReadOnly array.
+ * </p>
+ * <p>
+ * The arrays of the storage files (theStorageDir) and read only flags (cacheReadOnly)
+ * must be same size.
+ * </p>
+ * @param theStorageDir - array of file system directories to store cache files; might be null
+ * @param cacheReadOnly - array of read only attributes. True: cache at this location is read
+ * only; false: cache is read/write
*/
- public RegistryStrategy(File theStorageDir, boolean cacheReadOnly) {
+ public RegistryStrategy(File[] theStorageDir, boolean[] cacheReadOnly) {
this.theStorageDir = theStorageDir;
this.cacheReadOnly = cacheReadOnly;
}
- public final File getStorage() {
- return theStorageDir;
+ /**
+ * Returns number of possible cache locations for this registry
+ * @return number of possible cache locations for this registry
+ */
+ public final int getLocationsLength() {
+ if (theStorageDir == null)
+ return 0;
+ return theStorageDir.length;
}
- public final boolean isCacheReadOnly() {
- return cacheReadOnly;
+ /**
+ * Returns the possible registry cache location identified by the index.
+ * Locations with lower index have higher priority and are considered first.
+ *
+ * @param index index of the possible registry location
+ * @return potential registry cache location
+ */
+ public final File getStorage(int index) {
+ if (theStorageDir != null)
+ return theStorageDir[index];
+ return null;
}
/**
- * Specifies if registry clients can add information into the registry.
- * @return true: clients can add information; false: proper token should be supplied
- * in order to add information into the registry.
+ * Returns read only status of the registry cache location.
+ * @param index index of the possible registry location
+ * @return true: location is read only; false: location is read/write
*/
- public boolean isModifiable() {
+ public final boolean isCacheReadOnly(int index) {
+ if (cacheReadOnly != null)
+ return cacheReadOnly[index];
return true;
}
@@ -184,8 +211,7 @@ public class RegistryStrategy {
* @param registry - the extension registry (NOT thread safe)
*/
public void scheduleChangeEvent(Object[] listeners, Map deltas, Object registry) {
- if (registry instanceof ExtensionRegistry)
- ((ExtensionRegistry) registry).scheduleChangeEvent(listeners, deltas);
+ ((ExtensionRegistry) registry).scheduleChangeEvent(listeners, deltas);
}
/**
@@ -256,52 +282,58 @@ public class RegistryStrategy {
/**
* This method is called as a part of the registry cache validation. The cache is valid
- * on the registry startup if the pair {state, time stamp} supplied by the application
- * is the same as the {state, time stamp} saved in the registry cache.
- *
- * This method produces a number that corresponds to the current state of the data stored
- * in the registry. Increment the state if registry content changed and the registry cache
- * is no longer valid.
- *
+ * on the registry startup if the pair {container time stamp, contributors time stamp}
+ * supplied by the registry strategy is the same as the {container time stamp, contributors time stamp}
+ * stored in the registry cache. The goal of this method is to be able to catch modifications
+ * made to the original data contributed into the registry and not reflected in the registry cache.
+ * <p>
+ * The method produces a number that corresponds to the current state of the data stored
+ * by the container. Increment the stamp if the data stored in the container has been updated
+ * so that the data cached by the registry is no longer valid.
+ * </p><p>
+ * For instance, in Eclipse addition or removal of a bundle results in the number returned by
+ * this method being incremented. As a result, if a bundle that contributed plugin.xml into
+ * the extension registry was modified, the state doesn't match the state stored in the registry
+ * cache. In this case the cache content becomes invalid and registry needs to be re-created from
+ * the original data.
+ * </p><p>
+ * Generally, treat this number as a hash code for the data stored in the registry.
+ * It stays the same as long as the registry content is not changing. It becomes a different
+ * number as the registry content gets modified.
+ * </p><p>
* Return 0 to indicate that state verification is not required.
*
* @return number indicating state of the application data
*/
- public long cacheComputeState() {
+ public long getContainerTimestamp() {
return 0;
}
/**
* This method is called as a part of the registry cache validation. The cache is valid
- * on the registry startup if the pair {state, time stamp} supplied by the application
- * is the same as the {state, time stamp} saved in the registry cache.
- *
- * This method calculates current time stamp for the elements stored in the extension
- * registry. Treat this number as a hash code for the data stored in the registry.
- * It stays the same as long as the registry content is not changing. It becomes a different
- * number as the registry content gets modified.
- *
+ * on the registry startup if the pair {container time stamp, contributors time stamp}
+ * supplied by the registry strategy is the same as the {container time stamp, contributors time stamp}
+ * stored in the registry cache. The goal of this method is to be able to catch modifications
+ * made to the original data contributed into the registry and not reflected in the registry cache.
+ * <p>
+ * The method calculates a number describing time when the contributions cached by
+ * the registry were last modified. For instance, in the Eclipse registry this number is calculated
+ * as a function of the time when plugin.xml files have been modified. If the number is not the same
+ * as the number stored in the cache, it means that plugin.xml file(s) have been updated and
+ * the cached information is no longer valid.
+ * </p><p>
+ * Generally, treat this number as a hash code for the time of modifications of contributions stored
+ * in the registry. It stays the same as long as the contributions aren't changing. It becomes
+ * a different number when contributions are modified.
+ * </p><p>
* Return 0 to indicate that no time stamp verification is required.
*
* @return the time stamp calculated with the application data
*/
- public long cacheComputeTimeStamp() {
+ public long getContributionsTimestamp() {
return 0;
}
- /**
- * In case if the primary cache location has no data in it, the registry
- * attemps to get cached information from this alternative location. The cache
- * at alternative location is always considered read-only.
- *
- * Return null if alternative cache location is not supported.
- *
- * @return - directory containing the alternative cache location
- */
- public File cacheAlternativeLocation() {
- return null;
- }
-
private SAXParserFactory theXMLParserFactory = null;
/**

Back to the top