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 18:22:19 UTC
svn commit: r680753 -
/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/
Author: bdelacretaz
Date: Tue Jul 29 09:22:17 2008
New Revision: 680753
URL: http://svn.apache.org/viewvc?rev=680753&view=rev
Log:
SLING-587 - bundles and configs are now uninstalled from the OSGi framework when deleted from the Sling repository
Modified:
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java
incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java
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/JcrBundlesConstants.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/AbstractNodeProcessor.java
URL: http://svn.apache.org/viewvc/incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java?rev=680753&r1=680752&r2=680753&view=diff
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java (original)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/AbstractNodeProcessor.java Tue Jul 29 09:22:17 2008
@@ -18,7 +18,7 @@
*/
package org.apache.sling.jcr.jcrbundles;
-import static org.apache.sling.jcr.jcrbundles.JcrBundlesConstants.STATUS_NODES_BASE_PATH;
+import static org.apache.sling.jcr.jcrbundles.JcrBundlesConstants.STATUS_BASE_PATH;
import java.io.InputStream;
import java.util.Calendar;
@@ -66,7 +66,7 @@
/** 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 String path = STATUS_BASE_PATH + fileNode.getPath();
final Session s = fileNode.getSession();
Node result = null;
@@ -85,6 +85,24 @@
return result;
}
+ /** Find the path of the node in the main tree that corresponds to the given status node path */
+ protected String getMainNodePath(String statusNodePath) {
+ return statusNodePath.substring(STATUS_BASE_PATH.length());
+ }
+
+ /** Find the node in the main tree that corresponds to the given status node */
+ protected Node getMainNode(Node statusNode) throws RepositoryException {
+ final String path = getMainNodePath(statusNode.getPath());
+ final Session s = statusNode.getSession();
+ Node result = null;
+
+ if(s.itemExists(path)) {
+ result = (Node)s.getItem(path);
+ }
+
+ return result;
+ }
+
protected Calendar getLastModified(Node fileNode) throws RepositoryException {
if(fileNode.hasProperty(JCR_CONTENT_LAST_MODIFIED)) {
return fileNode.getProperty(JCR_CONTENT_LAST_MODIFIED).getDate();
Modified: 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=680753&r1=680752&r2=680753&view=diff
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java (original)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/BundleNodeProcessor.java Tue Jul 29 09:22:17 2008
@@ -57,7 +57,7 @@
// 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();
+ final String location = getBundleLocation(n.getPath());
try {
final Node status = getStatusNode(n, true);
final Bundle oldBundle = getBundleByLocation(location);
@@ -118,7 +118,33 @@
}
}
}
-
+
+ /** Check if the given statusNode still has an equivalent in the main tree, and if not
+ * uninstall the corresponding bundle, if found. Do the same thing for statusNodes' children */
+ public void checkDeletions(Node statusNode, Map<String, Boolean> flags) throws Exception {
+ final Node mainNode = getMainNode(statusNode);
+ if(mainNode == null) {
+ final String mainPath = getMainNodePath(statusNode.getPath());
+ final String location = getBundleLocation(mainPath);
+ final Bundle b = getBundleByLocation(location);
+ if(b == null) {
+ log.info("Node {} has been deleted, but corresponding bundle {} not found - deleting status node only",
+ mainPath, location);
+ } else {
+ try {
+ b.uninstall();
+ flags.put("refresh.packages", Boolean.TRUE);
+ log.info("Node {} has been deleted, bundle {} uninstalled", mainPath, location);
+ } catch(Exception e) {
+ log.error("Exception while trying to uninstall bundle " + location, e);
+ }
+ }
+
+ statusNode.remove();
+ statusNode.getSession().save();
+ }
+ }
+
private boolean isFragment(Bundle bundle) {
return padmin.getBundleType(bundle) == PackageAdmin.BUNDLE_TYPE_FRAGMENT;
}
@@ -136,4 +162,8 @@
}
return null;
}
+
+ protected String getBundleLocation(String bundleNodePath) {
+ return JCRBUNDLES_NAME_PREFIX + bundleNodePath;
+ }
}
\ No newline at end of file
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=680753&r1=680752&r2=680753&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 09:22:17 2008
@@ -18,6 +18,7 @@
*/
package org.apache.sling.jcr.jcrbundles;
+import static org.apache.sling.jcr.jcrbundles.JcrBundlesConstants.STATUS_BASE_PATH;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -167,26 +168,51 @@
if(nextScan != -1 && System.currentTimeMillis() > nextScan) {
nextScan = -1;
log.debug("Timer expired, scanning {}", path);
-
- 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);
- }
+ checkDeletions(flags);
+ checkUpdatesAndDeletes(flags);
}
}
- /** 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 Exception {
+ /** Let our processors handle all nodes under the main tree */
+ void checkUpdatesAndDeletes(Map<String, Boolean> flags) throws Exception {
+ if(session.getRootNode().hasNode(relPath(path))) {
+ final Node n = session.getRootNode().getNode(relPath(path));
+ processNode(n, flags, false);
+ } else {
+ log.info("Bundles folder {} does not exist anymore", path);
+ }
+ }
+
+ /** Check for nodes in the status tree that have disappeared from their main
+ * locations, and let the processors handle these deletes.
+ */
+ void checkDeletions(Map<String, Boolean> flags) throws Exception {
+ final String statusPath = STATUS_BASE_PATH + path;
+ if(session.getRootNode().hasNode(relPath(statusPath))) {
+ final Node n = session.getRootNode().getNode(relPath(statusPath));
+ processNode(n, flags, true);
+ } else {
+ log.info("Status folder {} does not exist, checkDeletions does nothing");
+ }
+ }
+
+ /** Let the first NodeProcessor that accepts n process it (for normal processing
+ * or deletions), and recurse into n's children to do the same
+ */
+ protected void processNode(Node n, Map<String, Boolean> flags, boolean checkDeletions) throws Exception {
boolean accepted = false;
+ final String path = n.getPath();
+ final Session s = n.getSession();
for(NodeProcessor p : processors) {
if(p.accepts(n)) {
accepted = true;
- p.process(n, flags);
+ if(checkDeletions) {
+ p.checkDeletions(n, flags);
+ } else {
+ p.process(n, flags);
+ }
break;
}
}
@@ -195,9 +221,12 @@
log.debug("No NodeProcessor found for node {}, ignored", n.getPath());
}
- final NodeIterator it = n.getNodes();
- while(it.hasNext()) {
- processNode(it.nextNode(), flags);
+ // n might have been deleted above, if it's a status done
+ if(s.itemExists(path)) {
+ final NodeIterator it = n.getNodes();
+ while(it.hasNext()) {
+ processNode(it.nextNode(), flags, checkDeletions);
+ }
}
}
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=680753&r1=680752&r2=680753&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 09:22:17 2008
@@ -73,7 +73,7 @@
@Override
public String toString() {
- return "ConfigPid: configPid=" + configPid + ", factoryPid=" + factoryPid;
+ return "Configuration (configPid=" + configPid + ", factoryPid=" + factoryPid + ")";
}
};
@@ -134,15 +134,35 @@
}
// get or create configuration
- Configuration config = getConfiguration(pid);
+ Configuration config = getConfiguration(pid, true);
if (config.getBundleLocation() != null) {
config.setBundleLocation(null);
}
config.update(ht);
- log.info("Config {} created or updated", config.getPid());
+ log.info("Configuration {} created or updated", config.getPid());
}
- Configuration getConfiguration(ConfigPid cp) throws IOException, InvalidSyntaxException {
+ public void checkDeletions(Node statusNode, Map<String, Boolean> flags) throws Exception {
+ final Node mainNode = getMainNode(statusNode);
+ if(mainNode == null) {
+ final String mainPath = getMainNodePath(statusNode.getPath());
+ final ConfigPid pid = new ConfigPid(mainPath);
+ final Configuration config = getConfiguration(pid, false);
+ if(config == null) {
+ log.info("Node {} has been deleted, but {} not found - deleting status node only",
+ mainPath, pid);
+ } else {
+ config.delete();
+ log.info("Node {} has been deleted: {} deleted",
+ mainPath, pid);
+ }
+
+ statusNode.remove();
+ statusNode.getSession().save();
+ }
+ }
+
+ Configuration getConfiguration(ConfigPid cp, boolean createIfNeeded) throws IOException, InvalidSyntaxException {
Configuration result = null;
if (cp.factoryPid == null) {
@@ -153,7 +173,9 @@
+ "))");
if (configs == null || configs.length == 0) {
- result = cadmin.createFactoryConfiguration(cp.configPid, null);
+ if(createIfNeeded) {
+ result = cadmin.createFactoryConfiguration(cp.configPid, null);
+ }
} else {
result = configs[0];
}
Modified: 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=680753&r1=680752&r2=680753&view=diff
==============================================================================
--- incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java (original)
+++ incubator/sling/whiteboard/jcrbundles/src/main/java/org/apache/sling/jcr/jcrbundles/JcrBundlesConstants.java Tue Jul 29 09:22:17 2008
@@ -20,6 +20,6 @@
/** Constants for this module */
public class JcrBundlesConstants {
- public static final String STATUS_NODES_BASE_PATH = "/system/sling/jcrbundles/status";
+ public static final String STATUS_BASE_PATH = "/system/sling/jcrbundles/status";
public static final String JCRBUNDLES_NAME_PREFIX = "jcrbundles:";
}
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=680753&r1=680752&r2=680753&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 09:22:17 2008
@@ -18,6 +18,7 @@
*/
package org.apache.sling.jcr.jcrbundles;
+import static org.apache.sling.jcr.jcrbundles.JcrBundlesConstants.STATUS_BASE_PATH;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -93,7 +94,11 @@
}
public void process(Node n, Map<String, Boolean> flags) throws RepositoryException {
- log.debug("Node {} ignored, no NodeProcessor accepts it", n.getPath());
+ log.debug("Node {} ignored in process() call, no NodeProcessor accepts it", n.getPath());
+ }
+
+ public void checkDeletions(Node statusNode, Map<String, Boolean> flags) throws Exception {
+ log.debug("Node {} ignored in checkDeletions() call, no NodeProcessor accepts it", statusNode.getPath());
}
});
@@ -133,6 +138,25 @@
log.info("{} thread {} starts", getClass().getSimpleName(), Thread.currentThread().getName());
Session s = null;
+ // First check for deletions, using the status folder root path
+ BundlesFolder statusFolder = null;
+ try {
+ statusFolder = new BundlesFolder(repository, STATUS_BASE_PATH, processors);
+ final Map<String, Boolean> flags = new HashMap<String, Boolean>();
+ statusFolder.checkDeletions(flags);
+ refreshPackagesIfNeeded(flags);
+ } catch(Exception e) {
+ log.error("Exception during initial scanning of " + STATUS_BASE_PATH, e);
+ } finally {
+ if(statusFolder != null) {
+ try {
+ statusFolder.cleanup();
+ } catch(Exception e) {
+ log.error("Exception during BundlesFolder cleanup of " + STATUS_BASE_PATH, e);
+ }
+ }
+ }
+
// We could use the scheduler service but that makes things harder to test
while(running) {
try {
@@ -163,7 +187,6 @@
/** Run one cycle of processing our scanTimes queue */
void runOneCycle(Session s) throws Exception {
- boolean refreshPackages = false;
final Map<String, Boolean> flags = new HashMap<String, Boolean>();
for(BundlesFolder bf : folders) {
@@ -171,12 +194,14 @@
break;
}
bf.scanIfNeeded(flags);
- refreshPackages |= Boolean.TRUE.equals(flags.get("refresh.packages"));
}
-
- if(refreshPackages) {
- log.info("Refreshing PackageAdmin packages");
+ refreshPackagesIfNeeded(flags);
+ }
+
+ void refreshPackagesIfNeeded(Map<String, Boolean> flags) {
+ if(Boolean.TRUE.equals(flags.get("refresh.packages"))) {
+ log.info("Refreshing 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=680753&r1=680752&r2=680753&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 09:22:17 2008
@@ -28,4 +28,5 @@
interface NodeProcessor {
boolean accepts(Node n) throws RepositoryException;
void process(Node n, Map<String, Boolean> flags) throws Exception;
+ void checkDeletions(Node statusNode, Map<String, Boolean> flags) throws Exception;
}