You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2011/01/12 12:00:27 UTC

svn commit: r1058067 - in /sling/trunk/installer/core/src: main/java/org/apache/sling/installer/core/impl/ test/java/org/apache/sling/installer/core/impl/

Author: cziegeler
Date: Wed Jan 12 11:00:27 2011
New Revision: 1058067

URL: http://svn.apache.org/viewvc?rev=1058067&view=rev
Log:
SLING-1923 : Improve the (internal) resource handling

Added:
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java   (contents, props changed)
      - copied, changed from r1057284, sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileUtil.java
Removed:
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileUtil.java
Modified:
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/InternalResource.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java
    sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java
    sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/DictionaryDigestTest.java
    sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceComparatorTest.java
    sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceTest.java
    sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/TaskOrderingTest.java

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/EntityResourceList.java Wed Jan 12 11:00:27 2011
@@ -135,6 +135,9 @@ public class EntityResourceList implemen
                 }
             }
             toActivate.setState(state);
+            if ( state == RegisteredResource.State.UNINSTALLED ) {
+                this.cleanup(toActivate);
+            }
         }
     }
 
@@ -195,6 +198,9 @@ public class EntityResourceList implemen
         }
     }
 
+    /**
+     * Compact the resource group by removing uninstalled entries
+     */
     public boolean compact() {
         boolean changed = false;
         final List<RegisteredResource> toDelete = new ArrayList<RegisteredResource>();

Copied: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java (from r1057284, sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileUtil.java)
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java?p2=sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java&p1=sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileUtil.java&r1=1057284&r2=1058067&rev=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileUtil.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java Wed Jan 12 11:00:27 2011
@@ -24,13 +24,16 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.osgi.framework.BundleContext;
+import org.slf4j.LoggerFactory;
 
 /**
  * Utility class for all file handling.
  */
-public class FileUtil {
+public class FileDataStore {
 
     /**
      * The name of the bundle context property defining the location for the
@@ -46,12 +49,16 @@ public class FileUtil {
 
     private final File directory;
 
-    public static FileUtil SHARED;
+    /** Public instance - to avoid passing a reference to this service to each data object. */
+    public static FileDataStore SHARED;
+
+    /** Cache for url to digest mapping. */
+    private final Map<String, String> digestCache = new HashMap<String, String>();
 
     /**
      * Create a file util instance and detect the installer directory.
      */
-    public FileUtil( final BundleContext bundleContext ) {
+    public FileDataStore( final BundleContext bundleContext ) {
         String location = bundleContext.getProperty(CONFIG_DIR);
 
         // no configured location, use the config dir in the bundle persistent
@@ -97,13 +104,6 @@ public class FileUtil {
     }
 
     /**
-     * Return the installer directory.
-     */
-    public File getDirectory() {
-        return this.directory;
-    }
-
-    /**
      * Return a file with the given name in the installer directory.
      * @param fileName The file name
      */
@@ -120,16 +120,46 @@ public class FileUtil {
         }
     }
 
-    /** Create a new unique data file. */
-    public File createNewDataFile(final String hint) {
+    /**
+     * Create a new unique data file.
+     */
+    public File createNewDataFile(final InputStream stream,
+            final String url,
+            final String digest,
+            final String hint)
+    throws IOException {
+        // check if we already have this data
+        if ( digest != null ) {
+            synchronized ( this.digestCache ) {
+                final String storedDigest = this.digestCache.get(url);
+                if ( storedDigest != null && storedDigest.equals(digest) ) {
+                    return null;
+                }
+            }
+        }
         final String filename = hint + "-resource-" + getNextSerialNumber() + ".ser";
-        return this.getDataFile(filename);
+        final File file = this.getDataFile(filename);
+
+        this.copyToLocalStorage(stream, file);
+
+        if ( digest != null ) {
+            synchronized ( this.digestCache ) {
+                this.digestCache.put(url, digest);
+            }
+        }
+        return file;
+    }
+
+    public void updateDigestCache(final String url, final String digest) {
+        synchronized ( this.digestCache ) {
+            this.digestCache.put(url, digest);
+        }
     }
 
     /**
      * Copy data to local storage.
      */
-    public void copyToLocalStorage(final InputStream data,
+    protected void copyToLocalStorage(final InputStream data,
             final File dataFile) throws IOException {
         final OutputStream os = new BufferedOutputStream(new FileOutputStream(dataFile));
         try {
@@ -143,4 +173,24 @@ public class FileUtil {
             os.close();
         }
     }
+
+    public File createNewDataFile(final String hint, final InputStream stream)
+    throws IOException {
+        final String filename = hint + "-resource-" + getNextSerialNumber() + ".ser";
+        final File file = this.getDataFile(filename);
+
+        this.copyToLocalStorage(stream, file);
+
+        return file;
+    }
+
+    public void removeFromDigestCache(final String url, final String digest) {
+        synchronized ( this.digestCache ) {
+            final String storedDigest = this.digestCache.get(url);
+            if ( storedDigest != null && storedDigest.equals(digest) ) {
+                LoggerFactory.getLogger(this.getClass()).warn("Remove {} : {}", url, digest);
+                this.digestCache.remove(url);
+            }
+        }
+    }
 }
\ No newline at end of file

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/FileDataStore.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/InternalResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/InternalResource.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/InternalResource.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/InternalResource.java Wed Jan 12 11:00:27 2011
@@ -85,14 +85,18 @@ public class InternalResource extends In
             digest = (resource.getDigest() != null && resource.getDigest().length() > 0
                       ? resource.getDigest() : resource.getId() + ":" + computeDigest(dict));
         } else {
+            final String url = scheme + ':' + resource.getId();
             // if input stream is not null, file is expected!
-            dataFile = FileUtil.SHARED.createNewDataFile(resource.getType());
-            FileUtil.SHARED.copyToLocalStorage(is, dataFile);
+            dataFile = FileDataStore.SHARED.createNewDataFile(is,
+                    url,
+                    resource.getDigest(),
+                    resource.getType());
             type = (type != null ? type : InstallableResource.TYPE_FILE);
             if (resource.getDigest() != null && resource.getDigest().length() > 0) {
                 digest = resource.getDigest();
             } else {
                 digest = computeDigest(dataFile);
+                FileDataStore.SHARED.updateDigestCache(url, digest);
             }
         }
         return new InternalResource(scheme,
@@ -152,10 +156,6 @@ public class InternalResource extends In
      * Copy the given file and return it.
      */
     public File getPrivateCopyOfFile() throws IOException {
-        if ( this.dataFile == null && this.getInputStream() != null ) {
-            this.dataFile = FileUtil.SHARED.createNewDataFile(this.getType());
-            FileUtil.SHARED.copyToLocalStorage(this.getInputStream(), this.dataFile);
-        }
         return this.dataFile;
     }
 

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/OsgiInstallerImpl.java Wed Jan 12 11:00:27 2011
@@ -105,8 +105,8 @@ public class OsgiInstallerImpl
     public OsgiInstallerImpl(final BundleContext ctx) {
         this.ctx = ctx;
         // Initialize file util
-        new FileUtil(ctx);
-        final File f = FileUtil.SHARED.getDataFile("RegisteredResourceList.ser");
+        new FileDataStore(ctx);
+        final File f = FileDataStore.SHARED.getDataFile("RegisteredResourceList.ser");
         this.persistentList = new PersistentResourceList(f);
     }
 
@@ -124,9 +124,6 @@ public class OsgiInstallerImpl
         ctx.removeBundleListener(this);
         ctx.removeFrameworkListener(this);
 
-        // remove file util
-        FileUtil.SHARED = null;
-
         // wake up sleeping thread
         this.wakeUp();
         this.logger.debug("Waiting for installer thread to stop");
@@ -136,6 +133,9 @@ public class OsgiInstallerImpl
             // we simply ignore this
         }
 
+        // remove file util
+        FileDataStore.SHARED = null;
+
         this.logger.info("Apache Sling OSGi Installer Service stopped.");
     }
 

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/PersistentResourceList.java Wed Jan 12 11:00:27 2011
@@ -100,8 +100,30 @@ public class PersistentResourceList {
         }
         data = restoredData != null ? restoredData : new HashMap<String, EntityResourceList>();
         this.unknownResources = unknownList != null ? unknownList : new ArrayList<RegisteredResource>();
+
+        this.updateCache();
+    }
+
+    /**
+     * Update the url to digest cache
+     */
+    private void updateCache() {
+        for(final EntityResourceList group : this.data.values()) {
+            for(final RegisteredResource rr : group.getResources()) {
+                try {
+                    if ( rr.getInputStream() != null ) {
+                        FileDataStore.SHARED.updateDigestCache(rr.getURL(), rr.getDigest());
+                    }
+                } catch (final IOException ioe) {
+                    // we just ignore this
+                }
+            }
+        }
     }
 
+    /**
+     * Persist the current state
+     */
     public void save() {
         try {
             final ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));
@@ -188,6 +210,9 @@ public class PersistentResourceList {
         }
     }
 
+    /**
+     * Remove a resource.
+     */
     public void remove(final RegisteredResource r) {
         final EntityResourceList group = this.data.get(r.getEntityId());
         if ( group != null ) {
@@ -199,6 +224,9 @@ public class PersistentResourceList {
         return this.data.get(entityId);
     }
 
+    /**
+     * Compact the internal state and remove empty groups.
+     */
     public boolean compact() {
         boolean changed = false;
         final Iterator<Map.Entry<String, EntityResourceList>> i = this.data.entrySet().iterator();

Modified: sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java (original)
+++ sling/trunk/installer/core/src/main/java/org/apache/sling/installer/core/impl/RegisteredResourceImpl.java Wed Jan 12 11:00:27 2011
@@ -77,6 +77,8 @@ public class RegisteredResourceImpl
     /** Temporary attributes. */
     private transient Map<String, Object> temporaryAttributes;
 
+    private boolean cleanedUp = false;
+
     /**
      * Serialize the object
      * - write version id
@@ -169,12 +171,23 @@ public class RegisteredResourceImpl
 	}
 
 	/**
+	 * Remove the data file
+	 */
+	private void removeDataFile() {
+        if ( this.dataFile != null && this.dataFile.exists() ) {
+            dataFile.delete();
+        }
+	}
+
+	/**
 	 * Clean up used data files.
 	 */
 	public void cleanup() {
-	    if ( this.dataFile != null && this.dataFile.exists() ) {
-			dataFile.delete();
-		}
+	    if ( !cleanedUp ) {
+	        cleanedUp = true;
+	        this.removeDataFile();
+	        FileDataStore.SHARED.removeFromDigestCache(this.url, this.digest);
+	    }
 	}
 
 	/**
@@ -397,9 +410,8 @@ public class RegisteredResourceImpl
         }
         if ( is != null ) {
             try {
-                final File newDataFile = FileUtil.SHARED.createNewDataFile(this.getType());
-                FileUtil.SHARED.copyToLocalStorage(is, newDataFile);
-                this.cleanup();
+                final File newDataFile = FileDataStore.SHARED.createNewDataFile(this.getType(), is);
+                this.removeDataFile();
                 this.dataFile = newDataFile;
             } finally {
                 try {

Modified: sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/DictionaryDigestTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/DictionaryDigestTest.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/DictionaryDigestTest.java (original)
+++ sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/DictionaryDigestTest.java Wed Jan 12 11:00:27 2011
@@ -37,7 +37,7 @@ public class DictionaryDigestTest {
 	}
 
     private InternalResource create(final InstallableResource is) throws IOException {
-        new FileUtil(new MockBundleContext());
+        new FileDataStore(new MockBundleContext());
         return InternalResource.create("test", is);
     }
 

Modified: sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceComparatorTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceComparatorTest.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceComparatorTest.java (original)
+++ sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceComparatorTest.java Wed Jan 12 11:00:27 2011
@@ -54,7 +54,7 @@ public class RegisteredResourceComparato
             data = new Hashtable<String, Object>();
             data.put("foo", "bar");
         }
-        new FileUtil(new MockBundleContext());
+        new FileDataStore(new MockBundleContext());
         final InstallableResource r = new InstallableResource(url, null, data, digest, null, priority);
         final InternalResource internal = InternalResource.create("test", r);
         final RegisteredResourceImpl rr = RegisteredResourceImpl.create(internal);

Modified: sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceTest.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceTest.java (original)
+++ sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/RegisteredResourceTest.java Wed Jan 12 11:00:27 2011
@@ -84,10 +84,12 @@ public class RegisteredResourceTest {
 	    final BundleContext bc = new MockBundleContext();
 	    final File f = getTestBundle("testbundle-1.0.jar");
         final InputStream s = new FileInputStream(f);
-        FileUtil.SHARED = new FileUtil(bc) {
+        FileDataStore.SHARED = new FileDataStore(bc) {
 
             @Override
-            public File createNewDataFile(final String hint) {
+            public File createNewDataFile(InputStream stream, String url,
+                    String digest, String hint) throws IOException {
+                this.copyToLocalStorage(stream, localFile);
                 return localFile;
             }
 
@@ -161,7 +163,7 @@ public class RegisteredResourceTest {
     }
 
     private RegisteredResource create(final InstallableResource is) throws IOException {
-        new FileUtil(new MockBundleContext());
+        new FileDataStore(new MockBundleContext());
         final InternalResource internal = InternalResource.create("test", is);
         final RegisteredResourceImpl rr = RegisteredResourceImpl.create(internal);
         final TransformationResult tr = new DefaultTransformer().transform(rr);

Modified: sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/TaskOrderingTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/TaskOrderingTest.java?rev=1058067&r1=1058066&r2=1058067&view=diff
==============================================================================
--- sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/TaskOrderingTest.java (original)
+++ sling/trunk/installer/core/src/test/java/org/apache/sling/installer/core/impl/TaskOrderingTest.java Wed Jan 12 11:00:27 2011
@@ -50,7 +50,7 @@ public class TaskOrderingTest {
 	}
 
 	private static EntityResourceList getRegisteredResource(String url) throws IOException {
-        new FileUtil(new MockBundleContext());
+        new FileDataStore(new MockBundleContext());
         final InternalResource internal = InternalResource.create("test",
                 new InstallableResource(url, null, new Hashtable<String, Object>(), null, null, null));
         final RegisteredResourceImpl rr = RegisteredResourceImpl.create(internal);