incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r693853 - in /incubator/sling/trunk/extensions/jcrinstall: ./ src/main/java/org/apache/sling/jcr/jcrinstall/ src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ src/test/java/org/...
Date Wed, 10 Sep 2008 14:31:31 GMT
Author: bdelacretaz
Date: Wed Sep 10 07:31:30 2008
New Revision: 693853

URL: http://svn.apache.org/viewvc?rev=693853&view=rev
Log:
SLING-646 - integration + old jcrbundles code removed

Added:
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java
  (with props)
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java
  (with props)
    incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java
  (with props)
Removed:
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/AbstractNodeProcessor.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/BundleNodeProcessor.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/BundlesFolder.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/BundlesFolderCreationListener.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/ConfigNodeProcessor.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrBundlesConstants.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/JcrBundlesManager.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/NodeProcessor.java
Modified:
    incubator/sling/trunk/extensions/jcrinstall/pom.xml
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
    incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/Storage.java
    incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/StorageTest.java

Modified: incubator/sling/trunk/extensions/jcrinstall/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/pom.xml?rev=693853&r1=693852&r2=693853&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/pom.xml (original)
+++ incubator/sling/trunk/extensions/jcrinstall/pom.xml Wed Sep 10 07:31:30 2008
@@ -55,7 +55,7 @@
         <extensions>true</extensions>
         <configuration>
           <instructions>
-            <Private-Package> org.apache.sling.jcr.jcrinstall </Private-Package>
+            <Private-Package>org.apache.sling.jcr.jcrinstall.*</Private-Package>
           </instructions>
         </configuration>
       </plugin>

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=693853&r1=693852&r2=693853&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
Wed Sep 10 07:31:30 2008
@@ -39,13 +39,24 @@
  *  detect added or updated resources that might be of
  *  interest to the OsgiController.
  *  
- *   Calls the OsgiController to install/remove resources.
+ *  Calls the OsgiController to install/remove resources.
+ *   
+ *  @scr.component 
+ *      immediate="true"
+ *      metatype="no"
+ *  @scr.property 
+ *      name="service.description" 
+ *      value="Sling jcrinstall OsgiController Service"
+ *  @scr.property 
+ *      name="service.vendor" 
+ *      value="The Apache Software Foundation"
  */
-public class RepositoryObserver {
+public class RepositoryObserver implements Runnable {
 
     private Set<WatchedFolder> folders;
     private RegexpFilter folderNameFilter;
     private RegexpFilter filenameFilter;
+    private boolean running;
     
     /** @scr.reference */
     private OsgiController osgiController;
@@ -101,15 +112,23 @@
         // service was inactive
         for(WatchedFolder wf : folders) {
             try {
-                wf.checkDeletions();
+                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());
+        t.setDaemon(true);
+        t.start();
     }
     
     protected void deactivate(ComponentContext oldContext) {
     	
+        running = false;
+        
     	for(WatchedFolder f : folders) {
     		f.cleanup();
     	}
@@ -192,10 +211,39 @@
         return path;
     }
     
+    /**
+     * Scan WatchFolders once their timer expires
+     */
+    public void run() {
+        log.info("{} thread {} starts", getClass().getSimpleName(), Thread.currentThread().getName());
+
+        // We could use the scheduler service but that makes things harder to test
+        while (running) {
+            try {
+                runOneCycle();
+            } catch (IllegalArgumentException ie) {
+                log.warn("IllegalArgumentException  in " + getClass().getSimpleName(), ie);
+            } catch (RepositoryException re) {
+                log.warn("RepositoryException in " + getClass().getSimpleName(), re);
+            } catch (Throwable t) {
+                log.error("Unhandled Throwable in runOneCycle() - "
+                        + getClass().getSimpleName() + " thread will be stopped", t);
+            } finally {
+                try {
+                    Thread.sleep(1000L);
+                } catch (InterruptedException ignore) {
+                    // ignore
+                }
+            }
+        }
+
+        log.info("{} thread {} ends", getClass().getSimpleName(), Thread.currentThread().getName());
+    }
+    
     /** Let our WatchedFolders run their scanning cycles */ 
     void runOneCycle() throws Exception {
     	for(WatchedFolder wf : folders) {
     		wf.scanIfNeeded();
     	}
     }
-}
+}
\ No newline at end of file

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java?rev=693853&r1=693852&r2=693853&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
Wed Sep 10 07:31:30 2008
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Set;
 
 import javax.jcr.Item;
 import javax.jcr.Node;
@@ -120,15 +121,15 @@
     void scanIfNeeded() throws Exception {
         if (nextScan != -1 && System.currentTimeMillis() > nextScan) {
             nextScan = -1;
+            scan();
         }
-        scan();
     }
     
     /** Scan our folder and inform OsgiController of any changes */
     protected void scan() throws Exception {
         log.debug("Scanning {}", path);
         
-        checkDeletions();
+        checkDeletions(controller.getInstalledUris());
         
         Node folder = null;
         if(session.itemExists(path)) {
@@ -161,12 +162,12 @@
     }
     
     /** Check for deleted resources and uninstall them */
-    void checkDeletions() throws Exception {
+    void checkDeletions(Set<String> installedUri) throws Exception {
         // Check deletions
-        for(String uri : controller.getInstalledUris()) {
+        for(String uri : installedUri) {
             if(uri.startsWith(path)) {
                 if(!session.itemExists(uri)) {
-                    log.debug("Resource {} has been deleted, uninstalling");
+                    log.info("Resource {} has been deleted, uninstalling", uri);
                     controller.uninstall(uri);
                 }
             }

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java?rev=693853&r1=693852&r2=693853&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/BundleResourceProcessor.java
Wed Sep 10 07:31:30 2008
@@ -25,11 +25,13 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
+import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,11 +44,13 @@
     public static final String KEY_BUNDLE_ID = "bundle.id";
     
     private final BundleContext ctx;
+    private final PackageAdmin packageAdmin;
     private final Map<Long, Bundle> pendingBundles;
     private final Logger log = LoggerFactory.getLogger(this.getClass());
     
-    BundleResourceProcessor(BundleContext ctx) {
+    BundleResourceProcessor(BundleContext ctx, PackageAdmin packageAdmin) {
         this.ctx = ctx;
+        this.packageAdmin = packageAdmin;
         pendingBundles = new HashMap<Long, Bundle>();
     }
 
@@ -54,6 +58,7 @@
         // Update if we already have a bundle id, else install
         Bundle b = null;
         boolean updated = false;
+        boolean refresh = false;
         final Long longId = (Long)attributes.get(KEY_BUNDLE_ID);
         
         if(longId != null) {
@@ -63,14 +68,21 @@
             } else {
                 b.update(data);
                 updated = true;
+                refresh = true;
             }
         }
         
         if(!updated) {
             b = ctx.installBundle(OsgiControllerImpl.getResourceLocation(uri), data);
+            refresh = true;
             attributes.put(KEY_BUNDLE_ID, new Long(b.getBundleId()));
         }
         
+        if(refresh) {
+            packageAdmin.resolveBundles(null);
+            packageAdmin.refreshPackages(null);
+        }
+        
         pendingBundles.put(new Long(b.getBundleId()), b);
         
         return updated ? UPDATED : INSTALLED; 
@@ -105,6 +117,11 @@
         while(iter.hasNext()) {
             final Long id = iter.next();
             final Bundle bundle = ctx.getBundle(id.longValue());
+            if(bundle == null) {
+                log.debug("Bundle id {} disappeared (bundle removed from framework?), removed
from pending bundles queue");
+                iter.remove();
+                continue;
+            }
             final int state = bundle.getState();
             
             if(bundle == null) {
@@ -128,9 +145,11 @@
             } else if ((state & Bundle.RESOLVED) > 0) {
                 log.info("Bundle {} is resolved, trying to start it.", bundle.getLocation());
                 bundle.start();
+                packageAdmin.resolveBundles(null);
+                packageAdmin.refreshPackages(null);
                 
             } else if ((state & Bundle.INSTALLED) > 0) {
-                log.info("Bundle {} is installed but not resolved.", bundle.getLocation());
+                log.debug("Bundle {} is installed but not resolved.", bundle.getLocation());
             }
         }
     }

Added: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java?rev=693853&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java
(added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java
Wed Sep 10 07:31:30 2008
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.jcrinstall.osgi.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.INSTALLED;
+import static org.apache.sling.jcr.jcrinstall.osgi.InstallResultCode.UPDATED;
+
+/** Process OSGi Configuration resources */
+public class ConfigResourceProcessor implements OsgiResourceProcessor {
+
+    private static final String ALIAS_KEY = "_alias_factory_pid";
+    public static final String CONFIG_EXTENSION = ".cfg";
+    private final ConfigurationAdmin configurationAdmin;
+    private final Logger log = LoggerFactory.getLogger(this.getClass());
+    
+    ConfigResourceProcessor(ConfigurationAdmin ca) {
+        configurationAdmin = ca;
+    }
+    
+    public boolean canProcess(String uri) {
+        return uri.endsWith(CONFIG_EXTENSION);
+    }
+
+    public int installOrUpdate(String uri, Map<String, Object> attributes, InputStream
data) throws Exception {
+        
+        // Load configuration properties
+        final Properties p = new Properties();
+        try {
+            p.load(data);
+        } finally {
+            data.close();
+        }
+
+        // Get pids from node name
+        final ConfigurationPid pid = new ConfigurationPid(uri);
+        log.debug("{} created for uri {}", pid, uri);
+
+        // prepare configuration data
+        Hashtable<Object, Object> ht = new Hashtable<Object, Object>();
+        ht.putAll(p);
+        if(pid.getFactoryPid() != null) {
+            ht.put(ALIAS_KEY, pid.getFactoryPid());
+        }
+
+        // get or create configuration
+        int result = UPDATED;
+        Configuration config = getConfiguration(pid, false);
+        if(config == null) {
+            result = INSTALLED;
+            config = getConfiguration(pid, true);
+        }
+        if (config.getBundleLocation() != null) {
+            config.setBundleLocation(null);
+        }
+        config.update(ht);
+        log.info("Configuration {} {}", config.getPid(), (result == UPDATED ? "updated" :
"created"));
+        return result;
+    }
+
+    public void processResourceQueue() throws Exception {
+        // TODO might need to retry installing configs, as
+        // we do for bundles
+    }
+
+    public void uninstall(String uri, Map<String, Object> attributes) throws Exception
{
+        final ConfigurationPid pid = new ConfigurationPid(uri);
+        final Configuration cfg = getConfiguration(pid, false);
+        if(cfg == null) {
+            log.debug("Config {} deleted but {} not found, ignoring", uri, pid);
+        } else {
+            log.info("Deleting config {} (uri = {})", pid, uri);
+            cfg.delete();
+        }
+    }
+
+    /** Get or create configuration */
+    Configuration getConfiguration(ConfigurationPid cp, boolean createIfNeeded) throws IOException,
InvalidSyntaxException {
+        Configuration result = null;
+        
+        if (cp.getFactoryPid() == null) {
+            result = configurationAdmin.getConfiguration(cp.getConfigPid(), null);
+        } else {
+            Configuration configs[] = configurationAdmin.listConfigurations(
+                "(|(" + ALIAS_KEY
+                + "=" + cp.getFactoryPid() + ")(.alias_factory_pid=" + cp.getFactoryPid()
+                + "))");
+            
+            if (configs == null || configs.length == 0) {
+                if(createIfNeeded) {
+                    result = configurationAdmin.createFactoryConfiguration(cp.getConfigPid(),
null);
+                }
+            } else {
+                result = configs[0];
+            }
+        }
+        
+        return result;
+    }
+
+}

Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigResourceProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java?rev=693853&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java
(added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java
Wed Sep 10 07:31:30 2008
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.jcrinstall.osgi.impl;
+
+/** Builds configration PIDs out of filenames, examples:
+ *      o.a.s.foo.bar.cfg -> pid = o.a.s.foo.bar
+ *      o.a.s.foo.bar-a.cfg -> pid = o.a.s.foo.bar, factory pid = a 
+ */
+class ConfigurationPid {
+    private final String configPid;
+    private final String factoryPid;
+
+    public ConfigurationPid(String path) {
+        // cut off path and extension
+        String pid = path;
+        final int lastSlash = path.lastIndexOf('/');
+        if(lastSlash >= 0) {
+            pid = path.substring(lastSlash + 1);
+        }
+        final int lastDot = pid.lastIndexOf('.');
+        if(lastDot >= 0) {
+            pid = pid.substring(0, lastDot);
+        }
+
+        // split pid and factory pid alias
+        int n = pid.indexOf('-');
+        if (n > 0) {
+            factoryPid = pid.substring(n + 1);
+            configPid = pid.substring(0, n);
+        } else {
+            factoryPid = null;
+            configPid = pid;
+        }
+    }
+    
+    @Override
+    public String toString() {
+        return "Configuration (configPid=" + configPid + ", factoryPid=" + factoryPid + ")";
+    }
+
+    public String getConfigPid() {
+        return configPid;
+    }
+
+    public String getFactoryPid() {
+        return factoryPid;
+    }
+}

Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPid.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java?rev=693853&r1=693852&r2=693853&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/OsgiControllerImpl.java
Wed Sep 10 07:31:30 2008
@@ -22,6 +22,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -29,14 +30,42 @@
 import org.apache.sling.jcr.jcrinstall.osgi.JcrInstallException;
 import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
 import org.apache.sling.jcr.jcrinstall.osgi.OsgiResourceProcessor;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class OsgiControllerImpl implements OsgiController {
+/** OsgiController service
+ *  
+ *  @scr.service
+ *  @scr.component 
+ *      immediate="true"
+ *      metatype="no"
+ *  @scr.property 
+ *      name="service.description" 
+ *      value="Sling jcrinstall OsgiController Service"
+ *  @scr.property 
+ *      name="service.vendor" 
+ *      value="The Apache Software Foundation"
+*/
+public class OsgiControllerImpl implements OsgiController, Runnable, SynchronousBundleListener
{
 
     private Storage storage;
     private List<OsgiResourceProcessor> processors;
     private final Logger log = LoggerFactory.getLogger(this.getClass());
+    private boolean running;
+    private long loopDelay;
+    
+    public static final String STORAGE_FILENAME = "controller.storage";
+    
+    /** @scr.reference */
+    private ConfigurationAdmin configAdmin;
+    
+    /** @scr.reference */
+    private PackageAdmin packageAdmin;
     
     /** Storage key: last modified as a Long */
     public static final String KEY_LAST_MODIFIED = "last.modified";
@@ -44,6 +73,34 @@
     /** Default value for getLastModified() */
     public static final long LAST_MODIFIED_NOT_FOUND = -1;
     
+    protected void activate(ComponentContext context) throws IOException {
+        processors = new LinkedList<OsgiResourceProcessor>();
+        processors.add(new BundleResourceProcessor(context.getBundleContext(), packageAdmin));
+        processors.add(new ConfigResourceProcessor(configAdmin));
+        
+        storage = new Storage(context.getBundleContext().getDataFile(STORAGE_FILENAME));
+        
+        // start queue processing
+        running = true;
+        final Thread t = new Thread(this, getClass().getSimpleName() + "_" + System.currentTimeMillis());
+        t.setDaemon(true);
+        t.start();
+    }
+    
+    protected void deactivate(ComponentContext oldContext) {
+        running = false;
+        
+        if(storage != null) {
+            try {
+                storage.saveToFile();
+            } catch(IOException ioe) {
+                log.warn("IOException in Storage.saveToFile()", ioe);
+            }
+        }
+        storage = null;
+        processors = null;
+    }
+    
     public int installOrUpdate(String uri, long lastModified, InputStream data) throws IOException,
JcrInstallException {
         int result = IGNORED;
         final OsgiResourceProcessor p = getProcessor(uri);
@@ -122,4 +179,37 @@
         
         return result;
     }
+    
+    /** Schedule our next scan sooner if anything happens to bundles */
+    public void bundleChanged(BundleEvent e) {
+        loopDelay = 0;
+    }
+
+    /** Process our resource queues at regular intervals, more often if
+     *  we received bundle events since the last processing
+     */
+    public void run() {
+        log.info("{} thread {} starts", getClass().getSimpleName(), Thread.currentThread().getName());
+
+        // We could use the scheduler service but that makes things harder to test
+        while (running) {
+            loopDelay = 1000;
+            try {
+                for(OsgiResourceProcessor p : processors) {
+                    p.processResourceQueue();
+                }
+                
+            } catch (Exception e) {
+                log.warn("Exception in run()", e);
+            } finally {
+                try {
+                    Thread.sleep(loopDelay);
+                } catch (InterruptedException ignore) {
+                    // ignore
+                }
+            }
+        }
+
+        log.info("{} thread {} ends", getClass().getSimpleName(), Thread.currentThread().getName());
+    }
 }
\ No newline at end of file

Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/Storage.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/Storage.java?rev=693853&r1=693852&r2=693853&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/Storage.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/osgi/impl/Storage.java
Wed Sep 10 07:31:30 2008
@@ -26,6 +26,7 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -51,8 +52,12 @@
         Throwable loadException = null;
         
         try {
-            ois = new ObjectInputStream(new FileInputStream(dataFile));
-            loadedData = (Map<String, Map<String, Object>>)ois.readObject();
+            if(dataFile.exists()) {
+                ois = new ObjectInputStream(new FileInputStream(dataFile));
+                loadedData = (Map<String, Map<String, Object>>)ois.readObject();
+            } else {
+                log.debug("Data file does not exist, will use empty data");
+            }
         } catch(EOFException eof) {
             loadException = eof;
         } catch(ClassNotFoundException cnfe) {
@@ -65,6 +70,8 @@
         
         if(loadException != null) {
             log.debug("Unable to retrieve data from data file, will use empty data", loadException);
+        }
+        if(loadedData == null) {
             loadedData = new HashMap<String, Map<String, Object>>();
         }
         
@@ -114,8 +121,12 @@
         }
     }
     
-    /** Get the Set of of keys in our data map */
+    /** Get a copy of the Set of keys in our data map */
     Set<String> getKeys() {
-        return data.keySet();
+        synchronized(data) {
+            final Set<String> result = new HashSet<String>();
+            result.addAll(data.keySet());
+            return result;
+        }
     }
 }

Added: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java?rev=693853&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java
(added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java
Wed Sep 10 07:31:30 2008
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.jcr.jcrinstall.osgi.impl;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConfigurationPidTest {
+
+    private void assertPid(String path, String expectedPid, String expectedFactoryPid) {
+        final ConfigurationPid pid = new ConfigurationPid(path);
+        assertEquals("For path " + path + ", pid matches", expectedPid, pid.getConfigPid());
+        assertEquals("For path " + path + ", factory pid matches", expectedFactoryPid, pid.getFactoryPid());
+    }
+    
+    @org.junit.Test public void testNonFactory() {
+        assertPid("o.a.s.foo.bar.cfg", "o.a.s.foo.bar", null);
+        assertPid("/somepath/o.a.s.foo.bar.cfg", "o.a.s.foo.bar", null);
+    }
+
+    @org.junit.Test public void testFactory() {
+        assertPid("o.a.s.foo.bar-a.cfg", "o.a.s.foo.bar", "a");
+        assertPid("/somepath/o.a.s.foo.bar-a.cfg", "o.a.s.foo.bar", "a");
+    }
+}

Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/ConfigurationPidTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/StorageTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/StorageTest.java?rev=693853&r1=693852&r2=693853&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/StorageTest.java
(original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/osgi/impl/StorageTest.java
Wed Sep 10 07:31:30 2008
@@ -31,6 +31,25 @@
         assertEquals("Storage is initially empty", 0, s.getKeys().size());
     }
     
+    @org.junit.Test public void testFileCreation() throws Exception {
+
+        // Get a temp file and delete it so that Storage must
+        // create it (i.e. we use just the filename)
+        final File f = Utilities.getTestFile();
+        f.delete();
+        
+        {
+            final Storage s = new Storage(f);
+            s.getMap("one").put("two", "twodata");
+            s.saveToFile();
+        }
+        
+        {
+            final Storage s = new Storage(f);
+            assertTrue("Retrieved Map contains 'two'", s.getMap("one").containsKey("two"));
+        }
+    }
+    
     @org.junit.Test public void testStoreAndRetrieve() throws Exception {
 
         final File f = Utilities.getTestFile();



Mime
View raw message