You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/07/29 14:35:25 UTC

svn commit: r680684 - /incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/

Author: bdelacretaz
Date: Tue Jul 29 05:35:23 2008
New Revision: 680684

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

Added:
    incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java   (with props)
    incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java   (with props)
    incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java   (with props)
    incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java   (with props)
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/JcrBundlesManager.java
    incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/NodeProcessor.java

Added: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java?rev=680684&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java (added)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java Tue Jul 29 05:35:23 2008
@@ -0,0 +1,111 @@
+/*
+ * 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.jcrbundles;
+
+import static org.apache.sling.jcr.jcrbundles.JcrBundlesConstants.STATUS_NODES_BASE_PATH;
+
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.regex.Pattern;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** NodeProcessor that accepts nodes based on a regexp on
+ * 	their name, but does nothing with them */ 
+abstract class AbstractNodeProcessor implements NodeProcessor {
+	
+    /** The relative path of the data and last modified date of an nt:file node */
+	public static final String JCR_CONTENT = "jcr:content";
+    public static final String JCR_CONTENT_DATA = JCR_CONTENT + "/jcr:data";
+    public static final String JCR_LAST_MODIFIED = "jcr:lastModified";
+    public static final String JCR_CONTENT_LAST_MODIFIED = JCR_CONTENT + "/" + JCR_LAST_MODIFIED;
+
+    protected final Logger log = LoggerFactory.getLogger(this.getClass());
+	private final Pattern pattern;
+	
+	AbstractNodeProcessor(String regexp) {
+		pattern = Pattern.compile(regexp);
+	}
+
+	public boolean accepts(Node n) throws RepositoryException {
+		boolean result = pattern.matcher(n.getName()).matches();
+		if(result) {
+			log.debug("Node {} accepted by {}", n.getPath(), getClass().getName());
+		}
+		return result;
+	}
+	
+	static InputStream getInputStream(Node fileNode) throws RepositoryException 
+    {
+    	Property prop = fileNode.getProperty(JCR_CONTENT_DATA);
+    	return prop.getStream();
+    }
+	
+	/** Return the Node to use to store status of given fileNode.
+	 * 	Session is not saved if status node is created */
+	protected Node getStatusNode(Node fileNode, boolean createIfNotFound) throws RepositoryException {
+		final String path = STATUS_NODES_BASE_PATH + fileNode.getPath();
+		final Session s = fileNode.getSession();
+		Node result = null;
+		
+		if(s.itemExists(path)) {
+			result = (Node)s.getItem(path);
+		} else if(createIfNotFound) {
+			result = deepCreate(s, path);
+		}
+		
+		if(result != null) {
+			log.debug("Status node for {} is at {}", fileNode.getPath(), result.getPath());
+		} else {
+			log.debug("No status node found for {}", fileNode.getPath());
+		}
+		
+		return result;
+	}
+	
+	protected Calendar getLastModified(Node fileNode) throws RepositoryException {
+		if(fileNode.hasProperty(JCR_CONTENT_LAST_MODIFIED)) {
+			return fileNode.getProperty(JCR_CONTENT_LAST_MODIFIED).getDate();
+		}
+		return null;
+	}
+	
+	protected Node deepCreate(Session s, String path) throws RepositoryException {
+		if(path.startsWith("/")) {
+			path = path.substring(1);
+		}
+		final String [] names = path.split("/");
+		String currentPath = "";
+		
+		for(int i=0; i < names.length; i++) {
+			currentPath += "/" + names[i];
+			if(!s.itemExists(currentPath)) {
+				s.getRootNode().addNode(currentPath.substring(1));
+			}
+		}
+
+		return (Node)s.getItem("/" + path);
+	}
+}

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java?rev=680684&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java (added)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java Tue Jul 29 05:35:23 2008
@@ -0,0 +1,139 @@
+/*
+ * 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.jcrbundles;
+
+import static org.apache.sling.jcr.jcrbundles.JcrBundlesConstants.JCRBUNDLES_NAME_PREFIX;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Calendar;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/** Process nodes that look like bundles, based on their node name */
+class BundleNodeProcessor extends AbstractNodeProcessor {
+    private final ComponentContext context;
+    private final PackageAdmin padmin; 
+	
+	public BundleNodeProcessor(ComponentContext ctx, PackageAdmin pa) {
+		super("[a-zA-Z0-9].*\\.jar$");
+		context = ctx;
+		padmin = pa;
+	}
+	
+	public void process(Node n, Map<String, Boolean> flags) throws RepositoryException {
+		
+		// Do we have file data?
+		InputStream is = null;
+		try {
+			is = getInputStream(n);
+		} catch(Exception e) {
+			log.info("Unable to get InputStream on Node {}, will be ignored ({})", n.getPath(), e);
+			return;
+		}
+
+		// We have data - install, update or do nothing with bundle
+		// TODO handle deletes (store a list of bundles that were installed)
+        final String location = JCRBUNDLES_NAME_PREFIX + n.getPath();
+		try {
+	        final Node status = getStatusNode(n, true);
+			final Bundle oldBundle = getBundleByLocation(location);
+			final Calendar lastModified = getLastModified(n);
+			Bundle newBundle = null;
+			boolean changed = false;
+			
+			if(oldBundle == null) {
+				// Bundle not installed yet, install it
+				changed = true;
+				newBundle = getBundleContext().installBundle(location, is);
+		        if (!isFragment(newBundle)) {
+		        	newBundle.start();
+			        log.info("Bundle {} successfully installed and started", location);
+		        } else {
+			        log.info("Fragment bundle {} successfully installed", location);
+		        }
+		        status.setProperty("status", "installed");
+		        
+			} else {
+				// Bundle already installed, did it change?
+				Calendar savedLastModified = null;
+				if(status.hasProperty(JCR_LAST_MODIFIED)) {
+					savedLastModified = status.getProperty(JCR_LAST_MODIFIED).getDate();
+				}
+				
+				changed = 
+					savedLastModified == null 
+					|| lastModified == null 
+					|| !(lastModified.equals(savedLastModified))
+				;
+				
+				if(changed) {
+					oldBundle.update(is);
+			        log.info("Bundle {} successfully updated", location);
+			        status.setProperty("status", "updated");
+				} else {
+			        log.debug("Bundle {} unchanged, no update needed", location);
+				}
+			}
+			
+			if(changed) {
+		        flags.put("refresh.packages", Boolean.TRUE);
+		        if(lastModified != null) {
+		        	status.setProperty(JCR_LAST_MODIFIED, lastModified);
+		        }
+		        n.getSession().save();
+			}
+	        
+		} catch(Exception e) {
+			log.warn("Exception while processing bundle {}", e);
+			
+		} finally {
+			try {
+				is.close();
+			} catch(IOException ioe) {
+				log.error("IOException on closing InputStream", ioe);
+			}
+		}
+	}
+	
+    private boolean isFragment(Bundle bundle) {
+        return padmin.getBundleType(bundle) == PackageAdmin.BUNDLE_TYPE_FRAGMENT;
+    }
+
+    private BundleContext getBundleContext() {
+        return context.getBundleContext();
+    }
+
+    protected Bundle getBundleByLocation(String location) {
+        Bundle bundles[] = getBundleContext().getBundles();
+        for(Bundle b : bundles) {
+        	if(location.equals(b.getLocation())) {
+        		return b;
+        	}
+        }
+        return null;
+    }
+}
\ No newline at end of file

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

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=680684&r1=680683&r2=680684&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 05:35:23 2008
@@ -20,6 +20,7 @@
 
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.jcr.Node;
@@ -162,27 +163,30 @@
     
     /** If our timer allows it, recursively call processNode 
      *  on our Node and its children */
-    void scanIfNeeded() throws RepositoryException {
+    void scanIfNeeded(Map<String, Boolean> flags) throws RepositoryException {
         if(nextScan != -1 && System.currentTimeMillis() > nextScan) {
             nextScan = -1;
             log.debug("Timer expired, scanning {}", path);
             
-            // TODO handle case where folder disappears
-            final Node n = session.getRootNode().getNode(relPath(path));
-            processNode(n);
+            if(session.getRootNode().hasNode(relPath(path))) {
+                final Node n = session.getRootNode().getNode(relPath(path));
+                processNode(n, flags);
+            } else {
+            	log.info("Bundles folder {} does not exist anymore", path);
+            }
         }
     }
     
-    /** Install/update/remove the bundle or config that Node n
-     *  represents, if any. */
-    protected void processNode(Node n) throws RepositoryException {
+    /** 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 {
         
         boolean accepted = false;
         
         for(NodeProcessor p : processors) {
             if(p.accepts(n)) {
                 accepted = true;
-                p.process(n);
+                p.process(n, flags);
                 break;
             }
         }
@@ -193,10 +197,11 @@
         
         final NodeIterator it = n.getNodes();
         while(it.hasNext()) {
-            processNode(it.nextNode());
+            processNode(it.nextNode(), flags);
         }
     }
     
+    /** Return the relative path for supplied path */
     static String relPath(String path) {
         if(path.startsWith("/")) {
             return path.substring(1);

Added: 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=680684&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java (added)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java Tue Jul 29 05:35:23 2008
@@ -0,0 +1,34 @@
+/*
+ * 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.jcrbundles;
+
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/** Process nodes that look like configs, based on their node name */
+class ConfigNodeProcessor extends AbstractNodeProcessor {
+	public ConfigNodeProcessor() {
+		super("[a-zA-Z0-9].*\\.cfg$");
+	}
+	
+	public void process(Node n, Map<String, Boolean> flags) throws RepositoryException {
+	}
+}

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/ConfigNodeProcessor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java?rev=680684&view=auto
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java (added)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java Tue Jul 29 05:35:23 2008
@@ -0,0 +1,25 @@
+/*
+ * 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.jcrbundles;
+
+/** Constants for this module */
+public class JcrBundlesConstants {
+	public static final String STATUS_NODES_BASE_PATH = "/system/sling/jcrbundles/status";
+	public static final String JCRBUNDLES_NAME_PREFIX = "jcrbundles:";
+}

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

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=680684&r1=680683&r2=680684&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 05:35:23 2008
@@ -18,9 +18,11 @@
  */
 package org.apache.sling.jcr.jcrbundles;
 
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.jcr.Node;
@@ -29,6 +31,7 @@
 
 import org.apache.sling.jcr.api.SlingRepository;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -65,8 +68,11 @@
     /** @scr.reference */
     private SlingRepository repository;
     
-    /** Default log. */
+    /** @scr.reference */
+    private PackageAdmin padmin;
+
     protected final Logger log = LoggerFactory.getLogger(this.getClass());
+    private boolean running;
     
     /** When activated, collect the list of bundle folders to scan
      *  and register as a listener for future updates.
@@ -75,13 +81,15 @@
 
         // setup our processors
         processors = new LinkedList<NodeProcessor>();
+        processors.add(new BundleNodeProcessor(context, padmin));
+        processors.add(new ConfigNodeProcessor());
         processors.add(new NodeProcessor() {
             public boolean accepts(Node n) throws RepositoryException {
                 return true;
             }
 
-            public void process(Node n) throws RepositoryException {
-                log.debug("Dummy NodeProcessor would process Node {}", n.getPath());
+            public void process(Node n, Map<String, Boolean> flags) throws RepositoryException {
+                log.debug("Node {} ignored, no NodeProcessor accepts it", n.getPath());
             }
             
         });
@@ -95,13 +103,16 @@
         // TODO: should listen for any new "bundles" folders created after activation
         
         // start queue processing
-        final Thread t = new Thread(this, getClass().getSimpleName());
+        final Thread t = new Thread(this, getClass().getSimpleName() + "_" + System.currentTimeMillis());
         t.setDaemon(true);
+        running = true;
         t.start();
     }
     
     /** Cleanup */
     protected void deactivate(ComponentContext oldContext) {
+    	running = false;
+    	
         for(BundlesFolder bf : folders) {
             try {
                 bf.cleanup();
@@ -115,18 +126,21 @@
     
     /** Scan paths once their timer expires */
     public void run() {
+        log.info("{} thread {} starts", getClass().getSimpleName(), Thread.currentThread().getName());
         Session s = null;
         
         // We could use the scheduler service but that makes things harder to test
-        while(true) {
+        while(running) {
             try {
-                s = repository.loginAdministrative(repository.getDefaultWorkspace());
-                runOneCycle(s);
+        		s = repository.loginAdministrative(repository.getDefaultWorkspace());
+        		runOneCycle(s);
             } 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 {
                 if(s!= null) {
                     s.logout();
@@ -140,12 +154,25 @@
             }
         }
         
+        log.info("{} thread {} ends", getClass().getSimpleName(), Thread.currentThread().getName());
     }
     
     /** Run one cycle of processing our scanTimes queue */
     void runOneCycle(Session s) throws RepositoryException {
+    	boolean refreshPackages = false;
+    	final Map<String, Boolean> flags = new HashMap<String, Boolean>();
+    	
         for(BundlesFolder bf : folders) {
-            bf.scanIfNeeded();
+        	if(!running) {
+        		break;
+        	}
+            bf.scanIfNeeded(flags);
+            refreshPackages |= Boolean.TRUE.equals(flags.get("refresh.packages"));
+        }
+        
+        if(refreshPackages) {
+        	log.info("Refreshing PackageAdmin packages");
+        	padmin.refreshPackages(null);
         }
     }
 }
\ No newline at end of file

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=680684&r1=680683&r2=680684&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 05:35:23 2008
@@ -1,5 +1,25 @@
+/*
+ * 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.jcrbundles;
 
+import java.util.Map;
+
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
@@ -7,5 +27,5 @@
 
 interface NodeProcessor {
     boolean accepts(Node n) throws RepositoryException;
-    void process(Node n) throws RepositoryException;
+    void process(Node n, Map<String, Boolean> flags) throws RepositoryException;
 }