incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r695873 - in /incubator/sling/trunk/extensions/jcrinstall/src: main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/
Date Tue, 16 Sep 2008 13:28:41 GMT
Author: bdelacretaz
Date: Tue Sep 16 06:28:40 2008
New Revision: 695873

URL: http://svn.apache.org/viewvc?rev=695873&view=rev
Log:
SLING-658 - Resources were not uninstalled when their folder is deleted

Modified:
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
    incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java
    incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java?rev=695873&r1=695872&r2=695873&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
Tue Sep 16 06:28:40 2008
@@ -18,9 +18,16 @@
  */
 package org.apache.sling.jcr.jcrinstall.jcr.impl;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Properties;
 import java.util.Set;
 
 import javax.jcr.Node;
@@ -30,6 +37,7 @@
 import javax.jcr.observation.Event;
 
 import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.jcrinstall.osgi.JcrInstallException;
 import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
@@ -78,6 +86,9 @@
     /** ComponentContext property that overrides the folder name regepx */
     public static final String FOLDER_NAME_REGEXP_PROPERTY = "sling.jcrinstall.folder.name.regexp";
     
+    public static final String DATA_FILE = "service.properties";
+    public static final String DATA_LAST_FOLDER_REGEXP = "folder.regexp";
+    
     /** Scan delay for watched folders */
     protected long scanDelayMsec = 1000L;
     
@@ -92,14 +103,35 @@
     	final String [] roots = DEFAULT_ROOTS; 
     	filenameFilter = new RegexpFilter(DEFAULT_FILENAME_REGEXP);
     	
-    	String regexp = getPropertyValue(context, FOLDER_NAME_REGEXP_PROPERTY);
-    	if(regexp != null) {
-    	    log.info("Using folder name regexp '{}' from context property '{}'", regexp, FOLDER_NAME_REGEXP_PROPERTY);
-    	    folderNameFilter = new RegexpFilter(regexp);
-    	} else {
+    	String folderNameRegexp = getPropertyValue(context, FOLDER_NAME_REGEXP_PROPERTY);
+    	if(folderNameRegexp == null) {
+    	    folderNameRegexp = DEFAULT_FOLDER_NAME_REGEXP;
             log.info("Using default folder name regexp '{}'", DEFAULT_FOLDER_NAME_REGEXP);
-	        folderNameFilter = new RegexpFilter(DEFAULT_FOLDER_NAME_REGEXP);
+    	} else {
+            log.info("Using folder name regexp '{}' from context property '{}'", folderNameRegexp,
FOLDER_NAME_REGEXP_PROPERTY);
     	}
+        folderNameFilter = new RegexpFilter(folderNameRegexp);
+        
+        // If regexp has changed, uninstall everything - it's a bit hard
+        // to know what might have changed otherwise
+        // (null context happens during testing only)
+        if(context != null) { 
+            final File f = context.getBundleContext().getDataFile(DATA_FILE);
+            final Properties props = loadProperties(f);
+            final String oldRegexp = props.getProperty(DATA_LAST_FOLDER_REGEXP);
+            if(oldRegexp != null && !oldRegexp.equals(folderNameRegexp)) {
+                log.info("Folder name regexp has changed, uninstalling all resources ({}
-> {}", oldRegexp, folderNameRegexp);
+                for(String uri : osgiController.getInstalledUris()) {
+                    try {
+                        osgiController.uninstall(uri);
+                    } catch (JcrInstallException e) {
+                        log.warn("Exception during 'uninstall all'", e);
+                    }
+                }
+            }
+            props.setProperty(DATA_LAST_FOLDER_REGEXP, folderNameRegexp);
+            saveProperties(props, f);
+        }
         
         // Listen for any new WatchedFolders created after activation
         session = repository.loginAdministrative(repository.getDefaultWorkspace());
@@ -112,23 +144,24 @@
             session.getWorkspace().getObservationManager().addEventListener(w, eventTypes,
path,
                     isDeep, null, null, noLocal);
         }
+        
+        // Check if any deletions happened while this
+        // service was inactive: create a fake WatchFolder 
+        // on / and use it to check for any deletions, even 
+        // if the corresponding WatchFolders are gone
+        try {
+            final WatchedFolder rootWf = new WatchedFolder(repository, "/", osgiController,
filenameFilter, 0L);
+            rootWf.checkDeletions(osgiController.getInstalledUris());
+        } catch(Exception e) {
+            log.warn("Exception in root WatchFolder.checkDeletions call", e);
+        }
 
+        // Find folders to watch
         folders = new HashSet<WatchedFolder>();
-        
         for(String root : roots) {
             folders.addAll(findWatchedFolders(root));
         }
         
-        // Check if any deletions happened while this
-        // service was inactive
-        for(WatchedFolder wf : folders) {
-            try {
-                wf.checkDeletions(osgiController.getInstalledUris());
-            } catch(Exception e) {
-                log.warn("Exception in activate() / checkDeletions", e);
-            }
-        }
-        
         // start queue processing
         running = true;
         final Thread t = new Thread(this, getClass().getSimpleName() + "_" + System.currentTimeMillis());
@@ -266,4 +299,44 @@
     		wf.scanIfNeeded();
     	}
     }
+    
+    Properties loadProperties(File f) {
+        final Properties props = new Properties();
+        if(f.exists()) {
+            InputStream is = null;
+            try {
+                is = new FileInputStream(f);
+                props.load(is);
+            } catch(IOException ioe) {
+                log.warn("Error reading " + f.getName(), ioe);
+            } finally {
+                if(is!=null) {
+                    try {
+                        is.close();
+                    } catch(IOException ignore) {
+                        
+                    }
+                }
+            }
+        }
+        return props;
+    }
+    
+    void saveProperties(Properties props, File f) {
+        OutputStream os = null;
+        try {
+            os = new FileOutputStream(f);
+            props.store(os, getClass().getSimpleName());
+        } catch(IOException ioe) {
+            log.warn("Error saving " + f.getName(), ioe);
+        } finally {
+            if(os!=null) {
+                try {
+                    os.close();
+                } catch(IOException ignore) {
+                    
+                }
+            }
+        }
+    }
 }
\ No newline at end of file

Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java?rev=695873&r1=695872&r2=695873&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MockRepositoryObserver.java
Tue Sep 16 06:28:40 2008
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.jcr.jcrinstall.jcr.impl;
 
+import java.util.Properties;
 import java.util.Set;
 
 import org.apache.sling.jcr.api.SlingRepository;
@@ -28,6 +29,8 @@
  *  used for testing.
  */
 public class MockRepositoryObserver extends RepositoryObserver {
+    private Properties props;
+    
     MockRepositoryObserver(SlingRepository repo, final OsgiController c) {
         repository = repo;
         osgiController = c;
@@ -53,7 +56,11 @@
         return result;
     }
     
+    public void setProperties(Properties p) {
+        props = p;
+    }
+    
     protected String getPropertyValue(ComponentContext ctx, String name) {
-        return null;
+        return (props == null ? null : props.getProperty(name));
     }
 }

Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java?rev=695873&r1=695872&r2=695873&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
Tue Sep 16 06:28:40 2008
@@ -19,8 +19,10 @@
 package org.apache.sling.jcr.jcrinstall.jcr.impl;
 
 import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.InputStream;
 import java.util.HashSet;
+import java.util.Properties;
 import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
@@ -34,6 +36,8 @@
 import org.jmock.Expectations;
 import org.jmock.Mockery;
 import org.jmock.Sequence;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
 
 /** Test that added/updated/removed resources are
  * 	correctly translated to OsgiController calls.
@@ -220,6 +224,7 @@
         final Set<String> installedUri = new HashSet<String>();
         installedUri.add("/libs/foo/bar/install/dummy.jar");
         installedUri.add("/libs/foo/bar/install/dummy.cfg");
+        installedUri.add("/libs/watchfolder-is-gone/install/gone.cfg");
         
         final OsgiController c = mockery.mock(OsgiController.class);
         final RepositoryObserver ro = new MockRepositoryObserver(repo, c);
@@ -229,6 +234,7 @@
             allowing(c).getLastModified(with(any(String.class))); will(returnValue(-1L));

             one(c).uninstall("/libs/foo/bar/install/dummy.jar");
             one(c).uninstall("/libs/foo/bar/install/dummy.cfg");
+            one(c).uninstall("/libs/watchfolder-is-gone/install/gone.cfg");
         }});
         
         // Activating with installed resources that are not in
@@ -301,4 +307,71 @@
         
         mockery.assertIsSatisfied();
     }
+    
+    /** Verify that resources are correctly uninstalled if the folder name regexp changes
*/
+    public void testFolderRegexpChange() throws Exception {
+        contentHelper.setupContent();
+        
+       final String [] resources = {
+                "/libs/foo/bar/install/dummy.jar",
+                "/libs/foo/wii/install/dummy.cfg",
+                "/libs/foo/bar/install/dummy.dp",
+                "/libs/foo/wii/install/more.cfg",
+        };
+        
+        final InputStream data = new ByteArrayInputStream("hello".getBytes());
+        final long lastModifiedA = System.currentTimeMillis();
+
+        for(String file : resources) {
+            contentHelper.createOrUpdateFile(file, data, lastModifiedA);
+        }
+        
+        final Set<String> installedUri = new HashSet<String>();
+        final OsgiController c = mockery.mock(OsgiController.class);
+        final Properties props = new Properties();
+        final ComponentContext ctx = mockery.mock(ComponentContext.class);
+        final BundleContext bc = mockery.mock(BundleContext.class);
+        final File f = File.createTempFile(getClass().getSimpleName(), "properties");
+        f.deleteOnExit();
+        
+        // Test with first regexp
+        mockery.checking(new Expectations() {{
+            allowing(ctx).getBundleContext(); will(returnValue(bc));
+            allowing(bc).getDataFile("service.properties"); will(returnValue(f));
+            allowing(c).getInstalledUris(); will(returnValue(installedUri));
+            allowing(c).getLastModified(with(any(String.class))); will(returnValue(-1L));

+            one(c).installOrUpdate(with(equal(resources[0])), with(equal(lastModifiedA)),
with(any(InputStream.class)));
+            one(c).installOrUpdate(with(equal(resources[2])), with(equal(lastModifiedA)),
with(any(InputStream.class)));
+        }});
+        
+        final MockRepositoryObserver ro = new MockRepositoryObserver(repo, c);
+        ro.setProperties(props);
+        props.setProperty(RepositoryObserver.FOLDER_NAME_REGEXP_PROPERTY, ".*foo/bar/install$");
+        ro.activate(ctx);
+        for(String file : resources) {
+            contentHelper.createOrUpdateFile(file, data, lastModifiedA);
+        }
+        eventHelper.waitForEvents(5000L);
+        ro.runOneCycle();
+        mockery.assertIsSatisfied();
+        
+        // Test with a different regexp, install.A resources must be uninstalled
+        mockery.checking(new Expectations() {{
+            allowing(ctx).getBundleContext(); will(returnValue(bc));
+            allowing(bc).getDataFile("service.properties"); will(returnValue(f));
+            allowing(c).getInstalledUris(); will(returnValue(installedUri));
+            allowing(c).getLastModified(with(any(String.class))); will(returnValue(-1L));

+            one(c).installOrUpdate(with(equal(resources[1])), with(equal(lastModifiedA)),
with(any(InputStream.class)));
+            one(c).installOrUpdate(with(equal(resources[3])), with(equal(lastModifiedA)),
with(any(InputStream.class)));
+        }});
+        
+        props.setProperty(RepositoryObserver.FOLDER_NAME_REGEXP_PROPERTY, ".*foo/wii/install$");
+        ro.activate(ctx);
+        for(String file : resources) {
+            contentHelper.createOrUpdateFile(file, data, lastModifiedA);
+        }
+        eventHelper.waitForEvents(5000L);
+        ro.runOneCycle();
+        mockery.assertIsSatisfied();
+    }
 }
\ No newline at end of file



Mime
View raw message