Author: bdelacretaz
Date: Tue Jul 29 06:50:43 2008
New Revision: 680696

URL: http://svn.apache.org/viewvc?rev=680696&view=rev
Log:
SLING-587 - adding and updating configs works (but no removing yet)

Modified:
    
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundlesFolder.java
    
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java
    
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesManager.java
    
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/NodeProcessor.java

Modified: 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundlesFolder.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundlesFolder.java?rev=680696&r1=680695&r2=680696&view=diff
==============================================================================
--- 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundlesFolder.java
 (original)
+++ 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundlesFolder.java
 Tue Jul 29 06:50:43 2008
@@ -163,7 +163,7 @@
     
     /** If our timer allows it, recursively call processNode 
      *  on our Node and its children */
-    void scanIfNeeded(Map<String, Boolean> flags) throws RepositoryException {
+    void scanIfNeeded(Map<String, Boolean> flags) throws Exception {
         if(nextScan != -1 && System.currentTimeMillis() > nextScan) {
             nextScan = -1;
             log.debug("Timer expired, scanning {}", path);
@@ -179,7 +179,7 @@
     
     /** Let the first NodeProcessor that accepts n process it, and
      *         recurse into n's children to do the same */
-    protected void processNode(Node n, Map<String, Boolean> flags) throws 
RepositoryException {
+    protected void processNode(Node n, Map<String, Boolean> flags) throws 
Exception {
         
         boolean accepted = false;
         

Modified: 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java?rev=680696&r1=680695&r2=680696&view=diff
==============================================================================
--- 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java
 (original)
+++ 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java
 Tue Jul 29 06:50:43 2008
@@ -18,17 +18,147 @@
  */
 package org.apache.sling.jcr.jcrbundles;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
 import java.util.Map;
+import java.util.Properties;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
 /** Process nodes that look like configs, based on their node name */
 class ConfigNodeProcessor extends AbstractNodeProcessor {
-       public ConfigNodeProcessor() {
+    private static final String ALIAS_KEY = "_alias_factory_pid";
+    
+       private final ConfigurationAdmin cadmin;
+
+       /** Configration PIDs are built out of filenames, examples:
+        *              o.a.s.foo.bar.cfg -> pid = o.a.s.foo.bar
+        *              o.a.s.foo.bar-a.cfg -> pid = .a.s.foo.bar, factory pid 
= a 
+        */
+       static class ConfigPid {
+               final String configPid;
+               final String factoryPid;
+
+               ConfigPid(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 "ConfigPid: configPid=" + configPid + ", 
factoryPid=" + factoryPid;
+               }
+       };
+       
+       public ConfigNodeProcessor(ConfigurationAdmin ca) {
                super("[a-zA-Z0-9].*\\.cfg$");
+               cadmin = ca;
        }
        
-       public void process(Node n, Map<String, Boolean> flags) throws 
RepositoryException {
+       public void process(Node n, Map<String, Boolean> flags) throws 
RepositoryException, IOException, InvalidSyntaxException {
+               
+               // For now we support only file-based configs
+               final InputStream is = getInputStream(n);
+               if(is == null) {
+                       log.warn("Cannot get InputStream for node {}, Node will 
be ignored", n.getPath());
+                       return;
+               }
+               
+        // Do nothing if config didn't change
+        final Node status = getStatusNode(n, true);
+               final Calendar lastModified = getLastModified(n);
+               Calendar savedLastModified = null;
+               if(status.hasProperty(JCR_LAST_MODIFIED)) {
+                       savedLastModified = 
status.getProperty(JCR_LAST_MODIFIED).getDate();
+               }
+               
+               boolean changed = 
+                       savedLastModified == null 
+                       || lastModified == null 
+                       || !(lastModified.equals(savedLastModified))
+               ;
+               
+               if(!changed) {
+               log.debug("Config {} unchanged, no update needed", n.getPath());
+               return;
+               }
+               if(lastModified != null) {
+                       status.setProperty(JCR_LAST_MODIFIED, lastModified);
+               }
+               n.getSession().save();
+
+               // Load configuration properties
+        final Properties p = new Properties();
+        try {
+               p.load(is);
+        } finally {
+               is.close();
+        }
+        
+        // Get pids from node name
+        final ConfigPid pid = new ConfigPid(n.getPath());
+        log.debug("{} created for node {}", pid, n.getPath());
+
+        // prepare configuration data
+        Hashtable<Object, Object> ht = new Hashtable<Object, Object>();
+        ht.putAll(p);
+        if(pid.factoryPid != null) {
+            ht.put(ALIAS_KEY, pid.factoryPid);
+        }
+
+        // get or create configuration
+        Configuration config = getConfiguration(pid);
+        if (config.getBundleLocation() != null) {
+            config.setBundleLocation(null);
+        }
+        config.update(ht);
+        log.info("Config {} created or updated", config.getPid());
        }
+       
+    Configuration getConfiguration(ConfigPid cp) throws IOException, 
InvalidSyntaxException {
+       Configuration result = null;
+       
+        if (cp.factoryPid == null) {
+               result = cadmin.getConfiguration(cp.configPid, null);
+        } else {
+            Configuration configs[] = cadmin.listConfigurations("(|(" + 
ALIAS_KEY
+                + "=" + cp.factoryPid + ")(.alias_factory_pid=" + cp.factoryPid
+                + "))");
+            
+            if (configs == null || configs.length == 0) {
+                result = cadmin.createFactoryConfiguration(cp.configPid, null);
+            } else {
+               result = configs[0];
+            }
+        }
+        
+        return result;
+    }
 }

Modified: 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesManager.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesManager.java?rev=680696&r1=680695&r2=680696&view=diff
==============================================================================
--- 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesManager.java
 (original)
+++ 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesManager.java
 Tue Jul 29 06:50:43 2008
@@ -30,6 +30,7 @@
 import javax.jcr.Session;
 
 import org.apache.sling.jcr.api.SlingRepository;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
@@ -70,6 +71,9 @@
     
     /** @scr.reference */
     private PackageAdmin padmin;
+    
+    /** @scr.reference */
+    private ConfigurationAdmin cadmin;
 
     protected final Logger log = LoggerFactory.getLogger(this.getClass());
     private boolean running;
@@ -82,7 +86,7 @@
         // setup our processors
         processors = new LinkedList<NodeProcessor>();
         processors.add(new BundleNodeProcessor(context, padmin));
-        processors.add(new ConfigNodeProcessor());
+        processors.add(new ConfigNodeProcessor(cadmin));
         processors.add(new NodeProcessor() {
             public boolean accepts(Node n) throws RepositoryException {
                 return true;
@@ -158,7 +162,7 @@
     }
     
     /** Run one cycle of processing our scanTimes queue */
-    void runOneCycle(Session s) throws RepositoryException {
+    void runOneCycle(Session s) throws Exception {
        boolean refreshPackages = false;
        final Map<String, Boolean> flags = new HashMap<String, Boolean>();
        

Modified: 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/NodeProcessor.java
URL: 
http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/NodeProcessor.java?rev=680696&r1=680695&r2=680696&view=diff
==============================================================================
--- 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/NodeProcessor.java
 (original)
+++ 
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/NodeProcessor.java
 Tue Jul 29 06:50:43 2008
@@ -27,5 +27,5 @@
 
 interface NodeProcessor {
     boolean accepts(Node n) throws RepositoryException;
-    void process(Node n, Map<String, Boolean> flags) throws 
RepositoryException;
+    void process(Node n, Map<String, Boolean> flags) throws Exception;
 }


Reply via email to