From fdf4ae81c01c37857f9f915106f1a75586e17304 Mon Sep 17 00:00:00 2001 From: Pascal Rapicault Date: Thu, 16 Feb 2006 20:29:01 +0000 Subject: Bug 127783 - Clean up RegistryStrategy from the org.eclipse.equinox.registry --- .../core/internal/registry/ExtensionRegistry.java | 48 +++----- .../core/internal/registry/osgi/Activator.java | 23 +++- .../registry/osgi/EquinoxRegistryStrategy.java | 78 ++++++++----- .../registry/osgi/RegistryStrategyOSGI.java | 75 +++--------- .../org/eclipse/core/runtime/RegistryFactory.java | 7 +- .../runtime/dynamichelpers/ExtensionTracker.java | 2 +- .../eclipse/core/runtime/spi/RegistryStrategy.java | 126 +++++++++++++-------- 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 0dbf750b4..91eba625c 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. *

- * @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. *

- * @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 0fea3b049..f183ff9ad 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 907f88c70..26968a69a 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: + *

* * @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 fbc03f847..4e94909a2 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 - * + *

* @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 b91c69a75..660432cbd 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. *

- * @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 b7cf074c2..d9571e095 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 dbc040b63..60a6e862f 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. + *

+ * 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. + *

+ *

+ * The arrays of the storage files (theStorageDir) and read only flags (cacheReadOnly) + * must be same size. + *

+ * @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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

* 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. + *

+ * 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. + *

+ * 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. + *

* 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; /** -- cgit v1.2.3