Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDJ Houghton2009-03-27 17:24:27 -0400
committerDJ Houghton2009-03-27 17:24:27 -0400
commit03e64b3582aab73563f08b63b38d217dfa148bde (patch)
treee7af2f7a396145e4010368d809450ad14f95f45f
parent3a54b7510f6b59ed50a88a0638116eb3fc71b3c6 (diff)
downloadrt.equinox.p2-03e64b3582aab73563f08b63b38d217dfa148bde.tar.gz
rt.equinox.p2-03e64b3582aab73563f08b63b38d217dfa148bde.tar.xz
rt.equinox.p2-03e64b3582aab73563f08b63b38d217dfa148bde.zip
Bug 269297 - Links in dropins directory are never rescanned
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Activator.java185
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/DropinsRepositoryListener.java56
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Messages.java5
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/messages.properties7
5 files changed, 156 insertions, 99 deletions
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Activator.java b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Activator.java
index 0eade47b6..a8ac4abf4 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Activator.java
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Activator.java
@@ -43,11 +43,16 @@ public class Activator implements BundleActivator {
private static final String CONFIG_INI = "config.ini"; //$NON-NLS-1$
private static final String PLATFORM_CFG = "org.eclipse.update/platform.xml"; //$NON-NLS-1$
private static final String CACHE_FILENAME = "cache.timestamps"; //$NON-NLS-1$
+ private static final String DIR_ECLIPSE = "eclipse"; //$NON-NLS-1$
+ private static final String DIR_PLUGINS = "plugins"; //$NON-NLS-1$
+ private static final String DIR_FEATURES = "features"; //$NON-NLS-1$
+ private static final String EXT_LINK = ".link"; //$NON-NLS-1$
private static PackageAdmin packageAdmin;
private static BundleContext bundleContext;
private ServiceReference packageAdminRef;
private List watchers = new ArrayList();
private final static Set repositories = new HashSet();
+ private Collection filesToCheck = null;
/**
* Helper method to create an extension location metadata repository at the given URI.
@@ -143,8 +148,11 @@ public class Activator implements BundleActivator {
// check to see if there is really any work to do. Do this after setting the context, and
// doing other initialization in case others call our public methods later.
- if (isUpToDate())
+ if (isUpToDate()) {
+ // clear the cache
+ filesToCheck = null;
return;
+ }
if (!startEarly("org.eclipse.equinox.p2.exemplarysetup")) //$NON-NLS-1$
return;
@@ -167,6 +175,7 @@ public class Activator implements BundleActivator {
// see Bug 223422
// for now explicitly nulling out these repos to allow GC to occur
repositories.clear();
+ filesToCheck = null;
}
private void checkConfigIni() {
@@ -215,55 +224,22 @@ public class Activator implements BundleActivator {
if (timestamps.isEmpty())
return false;
- // check platform.xml
- File configuration = getConfigurationLocation();
- if (configuration != null) {
- File platformXML = new File(configuration, PLATFORM_CFG);
- if (!Long.toString(platformXML.lastModified()).equals(timestamps.getProperty(platformXML.getAbsolutePath())))
+ // gather the list of files/folders that we need to check
+ Collection files = getFilesToCheck();
+ for (Iterator iter = files.iterator(); iter.hasNext();) {
+ File file = (File) iter.next();
+ String key = file.getAbsolutePath();
+ String timestamp = timestamps.getProperty(key);
+ if (timestamp == null)
return false;
- // the plugins and features directories are always siblings to the configuration directory
- File parent = configuration.getParentFile();
- if (parent != null) {
- File plugins = new File(parent, "plugins"); //$NON-NLS-1$
- if (!Long.toString(plugins.lastModified()).equals(timestamps.getProperty(plugins.getAbsolutePath())))
- return false;
- File features = new File(parent, "features"); //$NON-NLS-1$
- if (!Long.toString(features.lastModified()).equals(timestamps.getProperty(features.getAbsolutePath())))
- return false;
- }
- }
-
- // if we are in shared mode then check the timestamps of the parent configuration
- File parentConfiguration = getParentConfigurationLocation();
- if (parentConfiguration != null) {
- File platformXML = new File(parentConfiguration, PLATFORM_CFG);
- if (!Long.toString(platformXML.lastModified()).equals(timestamps.getProperty(platformXML.getAbsolutePath())))
+ if (!Long.toString(file.lastModified()).equals(timestamp))
return false;
- // the plugins and features directories are always siblings to the configuration directory
- File parent = parentConfiguration.getParentFile();
- if (parent != null) {
- File plugins = new File(parent, "plugins"); //$NON-NLS-1$
- if (!Long.toString(plugins.lastModified()).equals(timestamps.getProperty(plugins.getAbsolutePath())))
- return false;
- File features = new File(parent, "features"); //$NON-NLS-1$
- if (!Long.toString(features.lastModified()).equals(timestamps.getProperty(features.getAbsolutePath())))
- return false;
- }
+ timestamps.remove(key);
}
- // check dropins folders
- File[] dropins = getDropinsDirectories();
- for (int i = 0; i < dropins.length; i++) {
- if (!Long.toString(dropins[i].lastModified()).equals(timestamps.getProperty(dropins[i].getAbsolutePath())))
- return false;
- }
- // check links folder
- File[] links = getLinksDirectories();
- for (int i = 0; i < links.length; i++) {
- if (!Long.toString(links[i].lastModified()).equals(timestamps.getProperty(links[i].getAbsolutePath())))
- return false;
- }
- return true;
+ // if we had some extra timestamps in the file, then signal that something has
+ // changed and we need to reconcile
+ return timestamps.isEmpty();
}
/*
@@ -292,50 +268,119 @@ public class Activator implements BundleActivator {
}
/*
- * Persist the cache timestamp values.
+ * Return a collection of files which are interesting to us when we want to record timestamps
+ * to figure out if something has changed and perhaps avoid an unnecessary reconcilation.
*/
- private void writeTimestamps() {
- Properties timestamps = new Properties();
- // cache the platform.xml file timestamp
+ private Collection getFilesToCheck() {
+ if (filesToCheck != null)
+ return filesToCheck;
+
+ Set result = new HashSet();
+
+ // configuration/org.eclipse.update/platform.xml, configuration/../plugins, configuration/../features
File configuration = getConfigurationLocation();
if (configuration != null) {
- File platformXML = new File(configuration, PLATFORM_CFG);
- // always write out the timestamp even if it doesn't exist so we can detect addition/removal
- timestamps.put(platformXML.getAbsolutePath(), Long.toString(platformXML.lastModified()));
+ result.add(new File(configuration, PLATFORM_CFG));
File parent = configuration.getParentFile();
if (parent != null) {
File plugins = new File(parent, "plugins"); //$NON-NLS-1$
- timestamps.put(plugins.getAbsolutePath(), Long.toString(plugins.lastModified()));
+ result.add(plugins);
File features = new File(parent, "features"); //$NON-NLS-1$
- timestamps.put(features.getAbsolutePath(), Long.toString(features.lastModified()));
+ result.add(features);
}
}
- // if we are in shared mode then write out the information for the parent configuration
+
+ // if we are in shared mode then record the same files for the parent configuration
File parentConfiguration = getParentConfigurationLocation();
if (parentConfiguration != null) {
- File platformXML = new File(parentConfiguration, PLATFORM_CFG);
- // always write out the timestamp even if it doesn't exist so we can detect addition/removal
- timestamps.put(platformXML.getAbsolutePath(), Long.toString(platformXML.lastModified()));
+ result.add(new File(parentConfiguration, PLATFORM_CFG));
File parent = parentConfiguration.getParentFile();
if (parent != null) {
File plugins = new File(parent, "plugins"); //$NON-NLS-1$
- timestamps.put(plugins.getAbsolutePath(), Long.toString(plugins.lastModified()));
+ result.add(plugins);
File features = new File(parent, "features"); //$NON-NLS-1$
- timestamps.put(features.getAbsolutePath(), Long.toString(features.lastModified()));
+ result.add(features);
}
}
- // cache the dropins folders timestamp
- // always write out the timestamp even if it doesn't exist so we can detect addition/removal
+ // dropins folders
File[] dropins = getDropinsDirectories();
- for (int i = 0; i < dropins.length; i++) {
- timestamps.put(dropins[i].getAbsolutePath(), Long.toString(dropins[i].lastModified()));
- }
- // cache links folders timestamps
- // always write out the timestamp even if it doesn't exist so we can detect addition/removal
+ result.addAll(getDropinsToCheck(dropins));
+
+ // links folders
File[] links = getLinksDirectories();
- for (int i = 0; i < links.length; i++) {
- timestamps.put(links[i].getAbsolutePath(), Long.toString(links[i].lastModified()));
+ result.addAll(getDropinsToCheck(links));
+
+ filesToCheck = result;
+ return filesToCheck;
+ }
+
+ /*
+ * Iterate over the given collection of files (could be dropins or links folders) and
+ * return a collection of files that might be interesting to check the timestamps of.
+ */
+ private Collection getDropinsToCheck(File[] files) {
+ Collection result = new HashSet();
+ for (int outer = 0; outer < files.length; outer++) {
+ // add top-level file/folder
+ result.add(files[outer]);
+
+ File[] children = files[outer].listFiles();
+ for (int inner = 0; children != null && inner < children.length; inner++) {
+ File child = children[inner];
+ if (child.isFile() && child.getName().toLowerCase().endsWith(EXT_LINK)) {
+ // if we have a link file then add the link file and its target
+ File target = DropinsRepositoryListener.getLinkedFile(child);
+ if (target == null || !target.exists())
+ continue;
+ result.add(child);
+ result.add(target);
+ File eclipse = new File(target, DIR_ECLIPSE);
+ result.add(eclipse);
+ result.add(new File(eclipse, DIR_PLUGINS));
+ result.add(new File(eclipse, DIR_FEATURES));
+
+ } else if (child.getName().equalsIgnoreCase(DIR_ECLIPSE)) {
+ // if it is an "eclipse" dir then add it as well as "plugins" and "features"
+ result.add(child);
+ result.add(new File(child, DIR_PLUGINS));
+ result.add(new File(child, DIR_FEATURES));
+
+ } else if (child.isDirectory()) {
+ // look for "dropins/foo/plugins" (and "features") and
+ // "dropins/foo/eclipse/plugins" (and "features")
+ // Note: we could have a directory-based bundle here but we
+ // will still add it since it won't hurt anything (one extra timestamp check)
+ result.add(child);
+ File parent;
+ File eclipse = new File(child, DIR_ECLIPSE);
+ if (eclipse.exists()) {
+ result.add(eclipse);
+ parent = eclipse;
+ } else {
+ parent = child;
+ }
+ File plugins = new File(parent, DIR_PLUGINS);
+ if (plugins.exists())
+ result.add(plugins);
+ File features = new File(parent, DIR_FEATURES);
+ if (features.exists())
+ result.add(features);
+ }
+ }
+ }
+ return result;
+ }
+
+ /*
+ * Persist the cache timestamp values.
+ */
+ private void writeTimestamps() {
+ Properties timestamps = new Properties();
+ Collection files = getFilesToCheck();
+ for (Iterator iter = files.iterator(); iter.hasNext();) {
+ File file = (File) iter.next();
+ timestamps.put(file.getAbsolutePath(), Long.toString(file.lastModified()));
}
// write out the file
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/DropinsRepositoryListener.java b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/DropinsRepositoryListener.java
index 9b780727b..d2fe079c9 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/DropinsRepositoryListener.java
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/DropinsRepositoryListener.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 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
@@ -28,6 +28,7 @@ import org.eclipse.equinox.internal.provisional.p2.core.repository.IRepository;
import org.eclipse.equinox.internal.provisional.p2.directorywatcher.RepositoryListener;
import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository;
import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepositoryManager;
+import org.eclipse.osgi.util.NLS;
public class DropinsRepositoryListener extends RepositoryListener {
private static final String PLUGINS = "plugins"; //$NON-NLS-1$
@@ -67,22 +68,22 @@ public class DropinsRepositoryListener extends RepositoryListener {
private void addRepository(File file) {
URI repoLocation = createRepositoryLocation(file);
Properties properties = new Properties();
- try {
- // if the file pointed to a link file, keep track of the attribute
- // so we can add it to the repo later
- URI linkLocation = getLinkRepository(file, false);
- if (linkLocation != null)
- properties.put(Site.PROP_LINK_FILE, file.getAbsolutePath());
- } catch (IOException e) {
- // ignore
- }
+ // if the file pointed to a link file, keep track of the attribute
+ // so we can add it to the repo later
+ URI linkLocation = getLinkRepository(file, false);
+ if (linkLocation != null)
+ properties.put(Site.PROP_LINK_FILE, file.getAbsolutePath());
if (repoLocation != null) {
getMetadataRepository(repoLocation, properties);
getArtifactRepository(repoLocation, properties);
}
}
- private String getLinkPath(File file) {
+ /*
+ * Return the file pointed to by the given link file. Return null if there is a problem
+ * reading the file or resolving the location.
+ */
+ static File getLinkedFile(File file) {
Properties links = new Properties();
try {
InputStream input = new BufferedInputStream(new FileInputStream(file));
@@ -92,11 +93,11 @@ public class DropinsRepositoryListener extends RepositoryListener {
input.close();
}
} catch (IOException e) {
- // ignore
+ LogHelper.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.error_reading_link, file.getAbsolutePath()), e));
+ return null;
}
String path = links.getProperty(LINKS_PATH);
if (path == null) {
- // log
return null;
}
@@ -108,7 +109,19 @@ public class DropinsRepositoryListener extends RepositoryListener {
} else {
path = path.trim();
}
- return path;
+ File linkedFile = new File(path);
+ if (!linkedFile.isAbsolute()) {
+ // link support is relative to the install root
+ File root = Activator.getEclipseHome();
+ if (root != null)
+ linkedFile = new File(root, path);
+ }
+ try {
+ return linkedFile.getCanonicalFile();
+ } catch (IOException e) {
+ LogHelper.log(new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.error_resolving_link, linkedFile.getAbsolutePath(), file.getAbsolutePath()), e));
+ return null;
+ }
}
private URI createRepositoryLocation(File file) {
@@ -149,21 +162,14 @@ public class DropinsRepositoryListener extends RepositoryListener {
return null;
}
- private URI getLinkRepository(File file, boolean logMissingLink) throws IOException {
- String path = getLinkPath(file);
- if (path == null) {
+ private URI getLinkRepository(File file, boolean logMissingLink) {
+ File repo = getLinkedFile(file);
+ if (repo == null) {
if (logMissingLink)
LogHelper.log(new Status(IStatus.ERROR, Activator.ID, "Unable to determine link location from file: " + file.getAbsolutePath())); //$NON-NLS-1$
return null;
}
- File linkedFile = new File(path);
- if (!linkedFile.isAbsolute()) {
- // link support is relative to the install root
- File root = Activator.getEclipseHome();
- if (root != null)
- linkedFile = new File(root, path);
- }
- return linkedFile.getCanonicalFile().toURI();
+ return repo.toURI();
}
public void getMetadataRepository(URI repoURL, Properties properties) {
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Messages.java b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Messages.java
index d20774237..79296ff8f 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/Messages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 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
@@ -21,6 +21,9 @@ public class Messages extends NLS {
public static String errorLoadingRepository;
public static String errorProcessingConfg;
public static String metadata_repo_manager_not_registered;
+ public static String error_reading_link;
+ public static String error_resolving_link;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java
index 3a61c402b..aa4088a95 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/ProfileSynchronizer.java
@@ -152,7 +152,7 @@ public class ProfileSynchronizer {
File file = Activator.getContext().getDataFile(TIMESTAMPS_FILE_PREFIX + profile.getProfileId().hashCode());
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
try {
- timestamps.save(os, "Timestamps for " + profile.getProfileId()); //$NON-NLS-1$
+ timestamps.store(os, "Timestamps for " + profile.getProfileId()); //$NON-NLS-1$
} finally {
if (os != null)
os.close();
diff --git a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/messages.properties b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/messages.properties
index d8066d062..c8b618c8f 100644
--- a/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2007, 2008 IBM Corporation and others.
+# Copyright (c) 2007, 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
@@ -11,4 +11,7 @@
artifact_repo_manager_not_registered=ArtifactRepositoryManager not registered.
errorLoadingRepository=Error occurred while loading repository at {0}.
errorProcessingConfg=Exception while processing configuration.
-metadata_repo_manager_not_registered=MetadataRepositoryManager not registered. \ No newline at end of file
+metadata_repo_manager_not_registered=MetadataRepositoryManager not registered.
+error_reading_link = Error occurred while reading link file at {0}.
+error_resolving_link = Error occurred while resolving linked folder {0} from {1}.
+ \ No newline at end of file

Back to the top