Author: gnodet Date: Tue Oct 13 19:54:37 2009 New Revision: 824895 URL: http://svn.apache.org/viewvc?rev=824895&view=rev Log: FELIX-1578: fileinstall issue when updating already installed bundles at startup time
Modified: felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Artifact.java felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Util.java Modified: felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Artifact.java URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Artifact.java?rev=824895&r1=824894&r2=824895&view=diff ============================================================================== --- felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Artifact.java (original) +++ felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Artifact.java Tue Oct 13 19:54:37 2009 @@ -29,10 +29,10 @@ private File path; private File jaredDirectory; - private long lastModified = -1; private ArtifactListener listener; private File transformed; private long bundleId = -1; + private long checksum; public File getPath() { return path; @@ -50,14 +50,6 @@ this.jaredDirectory = jaredDirectory; } - public long getLastModified() { - return lastModified; - } - - public void setLastModified(long lastModified) { - this.lastModified = lastModified; - } - public ArtifactListener getListener() { return listener; } @@ -81,4 +73,12 @@ public void setBundleId(long bundleId) { this.bundleId = bundleId; } + + public long getChecksum() { + return checksum; + } + + public void setChecksum(long checksum) { + this.checksum = checksum; + } } Modified: felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java?rev=824895&r1=824894&r2=824895&view=diff ============================================================================== --- felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java (original) +++ felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/DirectoryWatcher.java Tue Oct 13 19:54:37 2009 @@ -135,7 +135,6 @@ { log("Starting initial scan", null); initializeCurrentManagedBundles(); - scanner.initialize(currentManagedArtifacts.keySet()); Set/*<File>*/ files = scanner.scan(true); if (files != null) { @@ -161,7 +160,6 @@ if (!noInitialDelay) { initializeCurrentManagedBundles(); - scanner.initialize(currentManagedArtifacts.keySet()); } while (!interrupted()) @@ -248,10 +246,11 @@ // the possibility of the jar being replaced by an older one // or the content changed without the date being modified, but // else, we'd have to reinstall all the deployed bundles on restart. - if (artifact.getLastModified() > Util.getLastModified(file)) - { - continue; - } +// if (artifact.getLastModified() > Util.getLastModified(file)) +// { +// continue; +// } + artifact.setChecksum(scanner.getChecksum(file)); // If there's no listener, this is because this artifact has been installed before // fileinstall has been restarted. In this case, try to find a listener. if (artifact.getListener() == null) @@ -307,6 +306,7 @@ artifact.setPath(file); artifact.setJaredDirectory(jar); artifact.setListener(listener); + artifact.setChecksum(scanner.getChecksum(file)); if (transformArtifact(artifact)) { created.add(artifact); @@ -547,11 +547,12 @@ { Bundle[] bundles = this.context.getBundles(); String watchedDirPath = watchedDirectory.toURI().normalize().getPath(); + Map /*<File, Long>*/ checksums = new HashMap/*<File, Long>*/(); for (int i = 0; i < bundles.length; i++) { Artifact artifact = new Artifact(); artifact.setBundleId(bundles[i].getBundleId()); - artifact.setLastModified(bundles[i].getLastModified()); + artifact.setChecksum(Util.loadChecksum(bundles[i], context)); artifact.setListener(null); // Convert to a URI because the location of a bundle // is typically a URI. At least, that's the case for @@ -588,8 +589,10 @@ if (index != -1 && path.startsWith(watchedDirPath)) { currentManagedArtifacts.put(new File(path), artifact); + checksums.put(new File(path), new Long(artifact.getChecksum())); } } + scanner.initialize(checksums); } /** @@ -603,11 +606,11 @@ for (Iterator iter = artifacts.iterator(); iter.hasNext();) { Artifact artifact = (Artifact) iter.next(); - Bundle bundle = install(artifact); if (bundle != null) { bundles.add(bundle); + Util.storeChecksum(bundle, artifact.getChecksum(), context); } } return bundles; @@ -623,11 +626,11 @@ List bundles = new ArrayList(); for (Iterator iter = artifacts.iterator(); iter.hasNext();) { - final Artifact artifact = (Artifact) iter.next(); - Bundle b = uninstall(artifact); - if (b != null) + Artifact artifact = (Artifact) iter.next(); + Bundle bundle = uninstall(artifact); + if (bundle != null) { - bundles.add(b); + bundles.add(bundle); } } return bundles; @@ -644,11 +647,12 @@ List bundles = new ArrayList(); for (Iterator iter = artifacts.iterator(); iter.hasNext(); ) { - Artifact e = (Artifact) iter.next(); - Bundle b = update(e); - if (b != null) + Artifact artifact = (Artifact) iter.next(); + Bundle bundle = update(artifact); + if (bundle != null) { - bundles.add(b); + bundles.add(bundle); + Util.storeChecksum(bundle, artifact.getChecksum(), context); } } return bundles; @@ -683,7 +687,7 @@ { File transformed = artifact.getTransformed(); Artifact badArtifact = (Artifact) installationFailures.get(artifact.getPath()); - if (badArtifact != null && badArtifact.getLastModified() == artifact.getLastModified()) + if (badArtifact != null && badArtifact.getChecksum() == artifact.getChecksum()) { return null; // Don't attempt to install it; nothing has changed. } @@ -700,7 +704,6 @@ } artifact.setBundleId(bundle.getBundleId()); } - artifact.setLastModified(Util.getLastModified(path)); installationFailures.remove(path); currentManagedArtifacts.put(path, artifact); log("Installed " + path, null); @@ -798,7 +801,6 @@ in.close(); } } - artifact.setLastModified(Util.getLastModified(path)); log("Updated " + path, null); } catch (Throwable t) Modified: felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java?rev=824895&r1=824894&r2=824895&view=diff ============================================================================== --- felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java (original) +++ felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Scanner.java Tue Oct 13 19:54:37 2009 @@ -78,14 +78,11 @@ * the list of known files. The purpose is to be able to detect * files that have been deleted while the scanner was inactive. * - * @param files a list of known files + * @param checksums a map of checksums */ - public void initialize(Collection/*<File>*/ files) + public void initialize(Map/*<File, Long>*/ checksums) { - for (Iterator it = files.iterator(); it.hasNext();) - { - storedChecksums.put(it.next(), new Long(0)); - } + storedChecksums.putAll(checksums); } /** @@ -135,6 +132,18 @@ } /** + * Retrieve the previously computed checksum for a give file. + * + * @param file the file to retrieve the checksum + * @return the checksum + */ + public long getChecksum(File file) + { + Long c = (Long) storedChecksums.get(file); + return c != null ? c.longValue() : 0; + } + + /** * Compute a cheksum for the file or directory that consists of the name, length and the last modified date * for a file and its children in case of a directory * Modified: felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Util.java URL: http://svn.apache.org/viewvc/felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Util.java?rev=824895&r1=824894&r2=824895&view=diff ============================================================================== --- felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Util.java (original) +++ felix/trunk/fileinstall/src/main/java/org/apache/felix/fileinstall/internal/Util.java Tue Oct 13 19:54:37 2009 @@ -18,6 +18,8 @@ */ package org.apache.felix.fileinstall.internal; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.IOException; import java.io.FileInputStream; import java.io.File; @@ -34,6 +36,7 @@ import java.util.jar.JarFile; import java.util.jar.JarOutputStream; +import org.osgi.framework.Bundle; import org.osgi.service.log.LogService; import org.osgi.framework.ServiceReference; import org.osgi.framework.BundleContext; @@ -342,32 +345,81 @@ } /** - * Return the latest time at which this file or any child if the file denotes - * a directory has been modified - * - * @param file file or directory to check - * @return the latest modification time + * Stores the checksum into a bundle data file. + * @param b The bundle whose checksum must be stored + * @param checksum the lastModified date to be stored in bc + * @param bc the FileInstall's bundle context where to store the checksum. */ - public static long getLastModified(File file) + public static void storeChecksum( Bundle b, long checksum, BundleContext bc ) { - if (file.isFile()) + String key = getBundleKey(b); + File f = bc.getDataFile( key + ".checksum" ); + DataOutputStream dout = null; + try + { + dout = new DataOutputStream( new FileOutputStream( f ) ); + dout.writeLong( checksum ); + } + catch ( Exception e ) { - return file.lastModified(); + e.printStackTrace(); } - else if (file.isDirectory()) + finally { - File[] children = file.listFiles(); - long lastModified = 0; - for (int i = 0; i < children.length; i++) + if ( dout != null ) { - lastModified = Math.max(lastModified, getLastModified(children[i])); + try + { + dout.close(); + } + catch ( IOException ignored ) + { + } } - return lastModified; } - else + } + + /** + * Returns the stored checksum of the bundle. + * @param b the bundle whose checksum must be returned + * @param bc the FileInstall's bundle context. + * @return the stored checksum of the bundle + */ + public static long loadChecksum( Bundle b, BundleContext bc ) + { + String key = getBundleKey(b); + File f = bc.getDataFile( key + ".checksum" ); + DataInputStream in = null; + try + { + in = new DataInputStream( new FileInputStream( f ) ); + return in.readLong(); + } + catch ( Exception e ) { - return 0; + return Long.MIN_VALUE; } + finally + { + if ( in != null ) + { + try + { + in.close(); + } + catch ( IOException e ) + { + } + } + } + } + + private static String getBundleKey(Bundle b) { + StringBuffer sb = new StringBuffer(); + sb.append(b.getSymbolicName()).append("_"); + String version = (String) b.getHeaders().get( "Bundle-Version" ); + sb.append(version != null ? version : "0.0.0"); + return sb.toString(); } }