diff options
author | DJ Houghton | 2010-01-19 20:30:34 +0000 |
---|---|---|
committer | DJ Houghton | 2010-01-19 20:30:34 +0000 |
commit | e4eb90e7667876c2a0d280d59404bdf805743054 (patch) | |
tree | 1677d419c5d13bb5d6b6334d96eb96eb0e5f8606 | |
parent | cdcaf976b5399762363680438d906aabaf8f1507 (diff) | |
download | rt.equinox.p2-e4eb90e7667876c2a0d280d59404bdf805743054.tar.gz rt.equinox.p2-e4eb90e7667876c2a0d280d59404bdf805743054.tar.xz rt.equinox.p2-e4eb90e7667876c2a0d280d59404bdf805743054.zip |
Bug 299544 - Links in dropins directory are never rescannedv20100201-1055R34x_v20100119
4 files changed, 144 insertions, 89 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 1d61916c2..dac8868ba 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2009 IBM Corporation and others. All rights reserved. + * Copyright (c) 2007, 2010 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 @@ -42,11 +42,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 URL. @@ -136,8 +141,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; @@ -166,6 +174,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() { @@ -214,55 +223,127 @@ public class Activator implements BundleActivator { if (timestamps.isEmpty()) return false; - // check platform.xml + // 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; + if (!Long.toString(file.lastModified()).equals(timestamp)) + return false; + timestamps.remove(key); + } + + // if we had some extra timestamps in the file, then signal that something has + // changed and we need to reconcile + return timestamps.isEmpty(); + } + + /* + * 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 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); - if (!Long.toString(platformXML.lastModified()).equals(timestamps.getProperty(platformXML.getAbsolutePath()))) - return false; - // the plugins and features directories are always siblings to the configuration directory + result.add(new File(configuration, PLATFORM_CFG)); 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; + result.add(plugins); File features = new File(parent, "features"); //$NON-NLS-1$ - if (!Long.toString(features.lastModified()).equals(timestamps.getProperty(features.getAbsolutePath()))) - return false; + result.add(features); } } - // if we are in shared mode then check the timestamps of 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); - if (!Long.toString(platformXML.lastModified()).equals(timestamps.getProperty(platformXML.getAbsolutePath()))) - return false; - // the plugins and features directories are always siblings to the configuration directory + result.add(new File(parentConfiguration, PLATFORM_CFG)); 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; + result.add(plugins); File features = new File(parent, "features"); //$NON-NLS-1$ - if (!Long.toString(features.lastModified()).equals(timestamps.getProperty(features.getAbsolutePath()))) - return false; + result.add(features); } } - // check dropins folders + // 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 + result.addAll(getDropinsToCheck(dropins)); + + // links folders 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; + 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 true; + return result; } /* @@ -295,46 +376,10 @@ public class Activator implements BundleActivator { */ private void writeTimestamps() { Properties timestamps = new Properties(); - // cache the platform.xml file timestamp - 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())); - File parent = configuration.getParentFile(); - if (parent != null) { - File plugins = new File(parent, "plugins"); //$NON-NLS-1$ - timestamps.put(plugins.getAbsolutePath(), Long.toString(plugins.lastModified())); - File features = new File(parent, "features"); //$NON-NLS-1$ - timestamps.put(features.getAbsolutePath(), Long.toString(features.lastModified())); - } - } - // if we are in shared mode then write out the information 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())); - File parent = parentConfiguration.getParentFile(); - if (parent != null) { - File plugins = new File(parent, "plugins"); //$NON-NLS-1$ - timestamps.put(plugins.getAbsolutePath(), Long.toString(plugins.lastModified())); - File features = new File(parent, "features"); //$NON-NLS-1$ - timestamps.put(features.getAbsolutePath(), Long.toString(features.lastModified())); - } - } - - // cache the dropins folders timestamp - // always write out the timestamp even if it doesn't exist so we can detect addition/removal - 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 - File[] links = getLinksDirectories(); - for (int i = 0; i < links.length; i++) { - timestamps.put(links[i].getAbsolutePath(), Long.toString(links[i].lastModified())); + 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 8771e00f3..42a863046 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, 2010 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 @@ -26,6 +26,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; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -77,7 +78,7 @@ public class DropinsRepositoryListener extends RepositoryListener { return true; } - private String getLinkPath(File file) { + static File getLinkedFile(File file) { Properties links = new Properties(); try { InputStream input = new BufferedInputStream(new FileInputStream(file)); @@ -87,11 +88,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; } @@ -103,7 +104,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 URL createRepositoryURL(File file) { @@ -142,21 +155,13 @@ public class DropinsRepositoryListener extends RepositoryListener { } private URL getLinkRepository(File file, boolean logMissingLink) throws IOException { - String path = getLinkPath(file); - if (path == null) { + File linkedFile = getLinkedFile(file); + if (linkedFile == 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); - } - File canonicalFile = linkedFile.getCanonicalFile(); - return canonicalFile.toURL(); + return linkedFile.toURL(); } public void getMetadataRepository(URL repoURL) { 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..816a6c799 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, 2010 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/messages.properties b/bundles/org.eclipse.equinox.p2.reconciler.dropins/src/org/eclipse/equinox/internal/p2/reconciler/dropins/messages.properties index d8066d062..b4276f25c 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, 2010 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,6 @@ 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}. |