You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by un...@apache.org on 2012/06/23 16:54:31 UTC

svn commit: r1353133 - in /rave/sandbox/content-services: ./ rave-jcr-config/ rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/ rave-jcr-config/src/test/java/org/apache/rave/j...

Author: unico
Date: Sat Jun 23 14:54:29 2012
New Revision: 1353133

URL: http://svn.apache.org/viewvc?rev=1353133&view=rev
Log:
RAVE-603 fine grained reload control on individual items; add jcr utils module; simplify module registration; module-wide workspace default; 

Added:
    rave/sandbox/content-services/rave-jcr-utils/   (with props)
    rave/sandbox/content-services/rave-jcr-utils/pom.xml
    rave/sandbox/content-services/rave-jcr-utils/src/
    rave/sandbox/content-services/rave-jcr-utils/src/main/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/utils/
    rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/utils/JcrUtils.java
Modified:
    rave/sandbox/content-services/pom.xml
    rave/sandbox/content-services/rave-jcr-config/pom.xml
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Module.java
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleImporter.java
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleRegistry.java
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleScanner.java
    rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/RaveRepositoryImpl.java
    rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleRegistryTest.java
    rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleScannerTest.java
    rave/sandbox/content-services/rave-jcr-config/src/test/resources/META-INF/rave/module.json

Modified: rave/sandbox/content-services/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/pom.xml?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/pom.xml (original)
+++ rave/sandbox/content-services/pom.xml Sat Jun 23 14:54:29 2012
@@ -169,6 +169,7 @@
     <module>rave-jcr</module>
     <module>demo-portal</module>
     <module>rave-jcr-integration</module>
+    <module>rave-jcr-utils</module>
   </modules>
 
   <build>

Modified: rave/sandbox/content-services/rave-jcr-config/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/pom.xml?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/pom.xml (original)
+++ rave/sandbox/content-services/rave-jcr-config/pom.xml Sat Jun 23 14:54:29 2012
@@ -66,6 +66,11 @@
       <artifactId>jackrabbit-core</artifactId>
       <version>${apache.jackrabbit.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.apache.rave.sandbox.jcr</groupId>
+      <artifactId>rave-jcr-utils</artifactId>
+      <version>${project.version}</version>
+    </dependency>
 
     <!-- Test -->
     <dependency>

Modified: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Module.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Module.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Module.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/Module.java Sat Jun 23 14:54:29 2012
@@ -47,6 +47,7 @@ import org.apache.rave.jcr.importing.Imp
  * {
  *     "name" : "rave-ocm-demo",
  *     "version" : 3,
+ *     "workspace" : "default",
  *     "dependencies" : [ "rave-ocm-core" ],
  *     "namespaces" : {
  *       "ocmdemo" : "http://rave.apache.org/jcr/ocmdemo"
@@ -61,6 +62,7 @@ import org.apache.rave.jcr.importing.Imp
  *       "ocmdemo" : {
  *         "file" : "ocmdemo.json"
  *         "parent" : "/",
+ *         "workspace" : "myws",
  *         "importBehavior" : "replace"
  *       }
  *     },
@@ -83,14 +85,13 @@ import org.apache.rave.jcr.importing.Imp
 public final class Module {
 
     enum Status {
-        EXISTING, NEW, REMOVED, GRADED, FAILED
+        DONE, PENDING, RELOAD, FAILED
     }
 
     private final String name;
     private final String baseUrl;
     private final String version;
-
-    private Status status;
+    private final String workspace;
 
     private List<String> dependencies;
     private List<Namespace> namespaces;
@@ -98,10 +99,11 @@ public final class Module {
     private List<Content> contents;
     private List<Resource> resources;
 
-    public Module(final String name, final String baseUrl, final String version) {
+    public Module(final String name, final String baseUrl, final String version, final String workspace) {
         this.name = name;
         this.baseUrl = baseUrl;
         this.version = version;
+        this.workspace = workspace;
     }
 
     public String getName() {
@@ -112,16 +114,12 @@ public final class Module {
         return version;
     }
 
-    String getBaseUrl() {
-        return baseUrl;
-    }
-
-    public Status getStatus() {
-        return status;
+    public String getWorkspace() {
+        return workspace;
     }
 
-    void setStatus(Status status) {
-        this.status = status;
+    String getBaseUrl() {
+        return baseUrl;
     }
 
     public List<String> getDependencies() {
@@ -159,11 +157,11 @@ public final class Module {
         return cnds;
     }
 
-    void addCnd(String name, String file, boolean reload, Status status) {
+    void addCnd(String name, String file, boolean reload, Status status, String version) {
         if (cnds == null) {
             cnds = new ArrayList<Cnd>();
         }
-        cnds.add(new Cnd(name, file, reload, status));
+        cnds.add(new Cnd(name, file, reload, status, version));
     }
 
     public List<Content> getContents() {
@@ -173,11 +171,11 @@ public final class Module {
         return contents;
     }
 
-    void addContent(String name, String file, String parent, boolean reload, String workspace, ImportBehavior importBehavior, Status status) {
+    void addContent(String name, String file, String parent, boolean reload, String workspace, ImportBehavior importBehavior, Status status, String version) {
         if (contents == null) {
             contents = new ArrayList<Content>();
         }
-        contents.add(new Content(name, file, parent, reload, workspace, importBehavior, status));
+        contents.add(new Content(name, file, parent, reload, workspace, importBehavior, status, version));
     }
 
     public List<Resource> getResources() {
@@ -195,65 +193,12 @@ public final class Module {
     }
 
     @Override
-    public boolean equals(final Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null) {
-            return false;
-        }
-        if (getClass() != o.getClass()) {
-            return false;
-        }
-
-        final Module module = (Module) o;
-
-        if (!name.equals(module.name)) {
-            return false;
-        }
-        if (!baseUrl.equals(module.baseUrl)) {
-            return false;
-        }
-        if (version != module.version) {
-            return false;
-        }
-        if (cnds != null ? !cnds.equals(module.cnds) : module.cnds != null) {
-            return false;
-        }
-        if (contents != null ? !contents.equals(module.contents) : module.contents != null) {
-            return false;
-        }
-        if (dependencies != null ? !dependencies.equals(module.dependencies) : module.dependencies != null) {
-            return false;
-        }
-        if (namespaces != null ? !namespaces.equals(module.namespaces) : module.namespaces != null) {
-            return false;
-        }
-        if (resources != null ? !resources.equals(module.resources) : module.resources != null) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int result = name.hashCode();
-        result = 31 * result + baseUrl.hashCode();
-        result = 31 * result + version.hashCode();
-        result = 31 * result + (dependencies != null ? dependencies.hashCode() : 0);
-        result = 31 * result + (namespaces != null ? namespaces.hashCode() : 0);
-        result = 31 * result + (cnds != null ? cnds.hashCode() : 0);
-        result = 31 * result + (contents != null ? contents.hashCode() : 0);
-        return result;
-    }
-
-    @Override
     public String toString() {
         return "Module{" +
-                "name='" + name + '\'' +
-                ", baseUrl='" + baseUrl + '\'' +
+                "name=" + name +
+                ", baseUrl=" + baseUrl +
                 ", version=" + version +
+                ", workspace=" + workspace +
                 ", dependencies=" + dependencies +
                 ", namespaces=" + namespaces +
                 ", cnds=" + cnds +
@@ -283,33 +228,31 @@ public final class Module {
             this.status = status;
         }
 
-        public boolean isReload() {
-            return false;
-        }
-
         Module getModule() {
             return Module.this;
         }
 
-        @Override
-        public boolean equals(final Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
+    }
 
-            final Item item = (Item) o;
+    public abstract class ReloadableItem extends Item {
 
-            return name.equals(item.name) && getModule().getName().equals(item.getModule().getName());
+        private final boolean reload;
+        private final String version;
 
+        private ReloadableItem(String name, Status status, boolean reload, String version) {
+            super(name, status);
+            this.reload = reload;
+            this.version = version;
         }
 
-        @Override
-        public int hashCode() {
-            return name.hashCode();
+        public boolean isReload() {
+            return reload;
+        }
+
+        public String getVersion() {
+            return version;
         }
+
     }
 
     public final class Namespace extends Item {
@@ -351,99 +294,57 @@ public final class Module {
         }
 
         @Override
-        public int hashCode() {
-            int result = getName().hashCode();
-            result = 31 * result + uri.hashCode();
-            return result;
-        }
-
-        @Override
         public String toString() {
             return "Namespace{" +
                     "name='" + getName() + '\'' +
-                    "prefix='" + getPrefix() + '\'' +
-                    "status='" + getStatus() + '\'' +
+                    ", prefix='" + getPrefix() + '\'' +
+                    ", status='" + getStatus() + '\'' +
                     ", uri='" + uri + '\'' +
                     '}';
         }
     }
 
-    public final class Cnd extends Item {
+    public final class Cnd extends ReloadableItem {
 
         private final String file;
-        private final boolean reload;
 
-        private Cnd(String name, String file, boolean reload, Status status) {
-            super(name, status);
+        private Cnd(String name, String file, boolean reload, Status status, String version) {
+            super(name, status, reload, version);
             this.file = file;
-            this.reload = reload;
         }
 
         public String getFile() {
             return file;
         }
 
-        public boolean isReload() {
-            return reload;
-        }
-
         URL getURL() throws MalformedURLException {
             return new URL((baseUrl.endsWith("/") ? baseUrl : baseUrl + "/") + file);
         }
 
         @Override
-        public boolean equals(final Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null) {
-                return false;
-            }
-            if (getClass() != o.getClass()) {
-                return false;
-            }
-            if (!super.equals(o)) {
-                return false;
-            }
-
-            final Cnd cnd = (Cnd) o;
-
-            return reload == cnd.reload && file.equals(cnd.file);
-
-        }
-
-        @Override
-        public int hashCode() {
-            int result = getName().hashCode();
-            result = 31 * result + file.hashCode();
-            result = 31 * result + (reload ? 1 : 0);
-            return result;
-        }
-
-        @Override
         public String toString() {
             return "Cnd{" +
                     "name='" + getName() + '\'' +
-                    "status='" + getStatus() + '\'' +
-                    "file='" + file + '\'' +
-                    ", reload=" + reload +
+                    ", status='" + getStatus() + '\'' +
+                    ", file='" + file + '\'' +
+                    ", reload=" + isReload() +
+                    ", version=" + getVersion() +
+                    ", workspace=" + workspace +
                     '}';
         }
     }
 
-    public final class Content extends Item {
+    public final class Content extends ReloadableItem {
 
         private final String file;
         private final String parent;
-        private final boolean reload;
         private final String workspace;
         private ImportBehavior importBehavior;
 
-        private Content(String name, String file, String parent, boolean reload, String workspace, ImportBehavior importBehavior, Status status) {
-            super(name, status);
+        private Content(String name, String file, String parent, boolean reload, String workspace, ImportBehavior importBehavior, Status status, String version) {
+            super(name, status, reload, version);
             this.file = file;
             this.parent = parent;
-            this.reload = reload;
             this.workspace = workspace;
             this.importBehavior = importBehavior;
         }
@@ -460,10 +361,6 @@ public final class Module {
             return parent + "/" + getName();
         }
 
-        public boolean isReload() {
-            return reload;
-        }
-
         public String getWorkspace() {
             return workspace;
         }
@@ -481,57 +378,14 @@ public final class Module {
         }
 
         @Override
-        public boolean equals(final Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null) {
-                return false;
-            }
-            if (getClass() != o.getClass()) {
-                return false;
-            }
-            if (!super.equals(o)) {
-                return false;
-            }
-
-            final Content content = (Content) o;
-
-            if (reload != content.reload) {
-                return false;
-            }
-            if (!file.equals(content.file)) {
-                return false;
-            }
-            if (workspace != null ? !workspace.equals(content.workspace) : content.workspace != null) {
-                return false;
-            }
-            if (importBehavior != null ? !importBehavior.equals(content.importBehavior) : content.importBehavior != null) {
-                return false;
-            }
-            return parent.equals(content.parent);
-
-        }
-
-        @Override
-        public int hashCode() {
-            int result = getName().hashCode();
-            result = 31 * result + file.hashCode();
-            result = 31 * result + parent.hashCode();
-            result = 31 * result + (reload ? 1 : 0);
-            result = 31 * result + workspace.hashCode();
-            result = importBehavior == null ? result : 31 * result + importBehavior.hashCode();
-            return result;
-        }
-
-        @Override
         public String toString() {
             return "Content{" +
                     "name='" + getName() + '\'' +
-                    "status='" + getStatus() + '\'' +
-                    "file='" + file + '\'' +
+                    ", status='" + getStatus() + '\'' +
+                    ", file='" + file + '\'' +
                     ", parent='" + parent + '\'' +
-                    ", reload=" + reload +
+                    ", reload=" + isReload() +
+                    ", version=" + getVersion() +
                     ", workspace='" + workspace + '\'' +
                     ", importBehavior=" + importBehavior +
                     '}';
@@ -569,10 +423,6 @@ public final class Module {
             return importBehavior;
         }
 
-        void setImportBehavior(ImportBehavior importBehavior) {
-            this.importBehavior = importBehavior;
-        }
-
         URL getJarURL() throws MalformedURLException {
             if (baseUrl.startsWith("jar:")) {
                 return new URL(baseUrl.substring(4, baseUrl.length()-2));
@@ -581,39 +431,13 @@ public final class Module {
         }
 
         @Override
-        public boolean equals(final Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null) {
-                return false;
-            }
-            if (getClass() != o.getClass()) {
-                return false;
-            }
-            if (!super.equals(o)) {
-                return false;
-            }
-
-            final Resource resource = (Resource) o;
-
-            if (!parent.equals(resource.parent)) {
-                return false;
-            }
-            if (importBehavior != null ? !importBehavior.equals(resource.importBehavior) : resource.importBehavior != null) {
-                return false;
-            }
-            return path.equals(resource.path);
-
-        }
-
-        @Override
-        public int hashCode() {
-            int result = super.hashCode();
-            result = 31 * result + (path != null ? path.hashCode() : 0);
-            result = 31 * result + parent.hashCode();
-            result = importBehavior == null ? result : 31 * result + importBehavior.hashCode();
-            return result;
+        public String toString() {
+            return "Resource{" +
+                    "path='" + path + '\'' +
+                    ", parent='" + parent + '\'' +
+                    ", workspace='" + workspace + '\'' +
+                    ", importBehavior=" + importBehavior +
+                    '}';
         }
     }
 

Modified: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleImporter.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleImporter.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleImporter.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleImporter.java Sat Jun 23 14:54:29 2012
@@ -85,46 +85,41 @@ public final class ModuleImporter {
         log.info("Preparing for import");
 
         final Collection<Module.Content> reloadContents = new ArrayList<Module.Content>();
-        final Collection<Module.Resource> reloadResources = new ArrayList<Module.Resource>();
         for (final Module module : modules) {
             for (final Module.Namespace namespace : module.getNamespaces()) {
-                if (namespace.getStatus() == Module.Status.NEW) {
+                if (namespace.getStatus() == Module.Status.PENDING) {
                     namespaces.add(namespace);
                 }
             }
             for (final Module.Cnd cnd : module.getCnds()) {
-                if (cnd.getStatus() == Module.Status.NEW || cnd.getStatus() == Module.Status.FAILED) {
+                if (cnd.getStatus() == Module.Status.PENDING || cnd.getStatus() == Module.Status.RELOAD) {
                     cnds.add(cnd);
-                } else if (cnd.getModule().getStatus() == Module.Status.GRADED) {
-                    if (cnd.isReload() && cnd.getStatus() != Module.Status.REMOVED) {
-                        cnds.add(cnd);
-                    }
                 }
             }
             for (final Module.Content content : module.getContents()) {
-                if (content.getStatus() == Module.Status.NEW || content.getStatus() == Module.Status.FAILED) {
+                if (content.getStatus() == Module.Status.PENDING) {
                     contents.add(content);
-                } else if (content.getModule().getStatus() == Module.Status.GRADED) {
-                    if (content.isReload() && content.getStatus() != Module.Status.REMOVED) {
-                        if (content.getImportBehavior() == ImportBehavior.MERGE) {
-                            // there is currently no reload support for the case where the content item is expected
-                            // to merge with existing content
-                            // adding that would probably require a reload of all upstream items and by extension their downstream
-                            // counterparts, and that would be the whole content tree
-                            log.info("Reloading content that is expected to merge with existing content is not supported");
-                        } else if (content.getImportBehavior() == ImportBehavior.SKIP) {
-                            // can't tell if content was previously imported or skipped, can't reload either
-                            log.info("Reloading content that might have been skipped is not supported");
-                        } else {
-                            contents.add(content);
-                            reloadContents.add(content);
-                            content.setImportBehavior(ImportBehavior.REPLACE);
-                        }
+                } else if (content.getStatus() == Module.Status.RELOAD) {
+                    if (content.getImportBehavior() == ImportBehavior.MERGE) {
+                        // there is currently no reload support for the case where the content item is expected
+                        // to merge with existing content
+                        // adding that would probably require a reload of all upstream items and by extension their downstream
+                        // counterparts, and that would be the whole content tree
+                        log.warn("Reloading content that is expected to merge with existing content is not supported." +
+                                "Module: " + module.getName() + ", content: " + content.getName());
+                    } else if (content.getImportBehavior() == ImportBehavior.SKIP) {
+                        // can't tell if content was previously imported or skipped, can't reload either
+                        log.warn("Reloading content that might have been skipped is not supported. " +
+                                "Module: " + module.getName() + ", content: " + content.getName());
+                    } else {
+                        contents.add(content);
+                        reloadContents.add(content);
+                        content.setImportBehavior(ImportBehavior.REPLACE);
                     }
                 }
             }
             for (Module.Resource resource : module.getResources()) {
-                if (resource.getStatus() == Module.Status.NEW || resource.getStatus() == Module.Status.FAILED) {
+                if (resource.getStatus() == Module.Status.PENDING) {
                     resources.add(resource);
                 }
             }
@@ -199,12 +194,12 @@ public final class ModuleImporter {
                 if (!existingUri.equals(namespace.getUri())) {
                     updateItemStatus(namespace, Module.Status.FAILED);
                 } else {
-                    updateItemStatus(namespace, Module.Status.EXISTING);
+                    updateItemStatus(namespace, Module.Status.DONE);
                 }
             } catch (NamespaceException expected) {
                 try {
                     namespaceRegistry.registerNamespace(namespace.getPrefix(), namespace.getUri());
-                    updateItemStatus(namespace, Module.Status.EXISTING);
+                    updateItemStatus(namespace, Module.Status.DONE);
                 } catch (NamespaceException e) {
                     log.error("Failed to register namespace " + namespace.getPrefix() + "=" + namespace.getUri(), e);
                     updateItemStatus(namespace, Module.Status.FAILED);
@@ -227,11 +222,11 @@ public final class ModuleImporter {
         final Session session = sessionProvider.getSession(null);
         for (Module.Cnd cnd : cnds) {
             final Module module = cnd.getModule();
-            final boolean reregister = cnd.getStatus() != Module.Status.NEW;
+            final boolean reregister = cnd.getStatus() != Module.Status.PENDING;
             log.info((reregister ? "Rer" : "R") + "egistering node types from " + cnd.getFile() + " in module " + module.getName());
             try {
                 CndImporter.registerNodeTypes(new InputStreamReader(cnd.getURL().openStream()), session, reregister);
-                updateItemStatus(cnd, Module.Status.EXISTING);
+                updateItemStatus(cnd, Module.Status.DONE);
             } catch (ParseException e) {
                 log.error("Failed to parse cnd " + cnd.getFile() + " in module " + module.getName(), e);
                 updateItemStatus(cnd, Module.Status.FAILED);
@@ -251,9 +246,10 @@ public final class ModuleImporter {
             return;
         }
         for (Module.Content content : contents) {
-            final Session session = getSession(content.getWorkspace());
-            final ContentImporter contentImporter = new ContentImporter(session);
             final Module module = content.getModule();
+            final String workspace = content.getWorkspace() == null ? module.getWorkspace() : content.getWorkspace();
+            final Session session = getSession(workspace);
+            final ContentImporter contentImporter = new ContentImporter(session);
             if (!session.nodeExists(content.getParent())) {
                 log.error("Cannot import content from " + content.getFile() + " in module " + module.getName()
                         + ": parent " + content.getParent() + " does not exist");
@@ -266,7 +262,7 @@ public final class ModuleImporter {
                 log.info("Importing content from " + content.getFile() + " in module " + module.getName());
                 contentImporter.importContent(content.getParent(), content.getName(), is, content.getImportBehavior());
                 session.save();
-                updateItemStatus(content, Module.Status.EXISTING);
+                updateItemStatus(content, Module.Status.DONE);
             } catch (IOException e) {
                 log.error("Failed to read content " + content.getFile() + " in module " + module.getName(), e);
                 updateItemStatus(content, Module.Status.FAILED);
@@ -290,9 +286,10 @@ public final class ModuleImporter {
             return;
         }
         for (Module.Resource resource : resources) {
-            final Session session = getSession(resource.getWorkspace());
-            final ResourceImporter resourceImporter = new ResourceImporter(session, mimeTypeResolver);
             final Module module = resource.getModule();
+            final String workspace = resource.getWorkspace() == null ? module.getWorkspace() : resource.getWorkspace();
+            final Session session = getSession(workspace);
+            final ResourceImporter resourceImporter = new ResourceImporter(session, mimeTypeResolver);
             if (!session.nodeExists(resource.getParent())) {
                 log.error("Cannot import resources " + resource.getName() + " in module " + module.getName() +
                         ": parent " + resource.getParent() + " does not exist");
@@ -310,7 +307,7 @@ public final class ModuleImporter {
                 log.info("Importing resources " + resource.getName() + " in module " + module.getName());
                 resourceImporter.importResource(resource.getParent(), resource.getPath(), is, resource.getImportBehavior());
                 session.save();
-                updateItemStatus(resource, Module.Status.EXISTING);
+                updateItemStatus(resource, Module.Status.DONE);
             } catch (IOException e) {
                 log.error("Failed to read resources in module " + module.getName(), e);
             } catch (ImportException e) {

Modified: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleRegistry.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleRegistry.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleRegistry.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleRegistry.java Sat Jun 23 14:54:29 2012
@@ -31,6 +31,7 @@ import javax.jcr.Value;
 import javax.jcr.ValueFactory;
 
 import org.apache.rave.jcr.importing.ImportBehavior;
+import org.apache.rave.jcr.utils.JcrUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,100 +103,83 @@ public final class ModuleRegistry {
 
         try {
             if (current.getVersion() != null ? !current.getVersion().equals(previous.getVersion()) : previous.getVersion() != null) {
-                if (current.getVersion() == null) {
-//                    assert node.hasProperty(VERSION);
-                    node.getProperty(VERSION).remove();
-                } else {
-                    node.setProperty(VERSION, current.getVersion());
-                    setStatusProperty(node, Module.Status.GRADED);
-                    current.setStatus(Module.Status.GRADED);
-                }
+                node.setProperty(VERSION, current.getVersion());
             }
 
             if (!current.getBaseUrl().equals(previous.getBaseUrl())) {
                 node.setProperty(BASEURL, current.getBaseUrl());
             }
 
+            if (current.getWorkspace() != null ? !current.getWorkspace().equals(previous.getWorkspace()) : previous.getWorkspace() != null) {
+                node.setProperty(WORKSPACE, current.getWorkspace());
+            }
+
             if (!current.getDependencies().equals(previous.getDependencies())) {
-                if (current.getDependencies().isEmpty()) {
-                    node.getProperty(DEPENDENCIES).remove();
-                } else {
-                    setDependencies(node, current);
-                }
+                setDependencies(node, current);
             }
 
-            if (!current.getNamespaces().equals(previous.getNamespaces())) {
-                final Node namespacesNode = getOrCreateNode(node, NAMESPACES);
-                for (Module.Namespace namespace : getRemoved(current.getNamespaces(), previous.getNamespaces())) {
-                    setStatusProperty(namespacesNode.getNode(namespace.getName()), Module.Status.REMOVED);
-                    namespace.setStatus(Module.Status.REMOVED);
-                }
-                for (Module.Namespace namespace : getModified(current.getNamespaces(), previous.getNamespaces())) {
-                    final Node namespaceNode = namespacesNode.getNode(namespace.getName());
-                    setNamespaceProperties(namespaceNode, namespace);
-                }
-                for (Module.Namespace namespace : getAdded(current.getNamespaces(), previous.getNamespaces())) {
+            final Collection<Module.Namespace> addedNamespaces = getAdded(current.getNamespaces(), previous.getNamespaces());
+            if (!addedNamespaces.isEmpty()) {
+                final Node namespacesNode = JcrUtils.getOrCreateNode(node, NAMESPACES);
+                for (Module.Namespace namespace : addedNamespaces) {
                     final Node namespaceNode = namespacesNode.addNode(namespace.getName());
                     setNamespaceProperties(namespaceNode, namespace);
-                    setStatusProperty(namespaceNode, Module.Status.NEW);
-                    namespace.setStatus(Module.Status.NEW);
+                    setStatusProperty(namespaceNode, Module.Status.PENDING);
+                    namespace.setStatus(Module.Status.PENDING);
                 }
             }
 
-            if (!current.getCnds().equals(previous.getCnds())) {
-                final Node cndsNode = getOrCreateNode(node, CNDS);
-                for (Module.Cnd cnd : getRemoved(current.getCnds(), previous.getCnds())) {
-                    setStatusProperty(cndsNode.getNode(cnd.getName()), Module.Status.REMOVED);
-                    cnd.setStatus(Module.Status.REMOVED);
-                }
-                for (Module.Cnd cnd : getModified(current.getCnds(), previous.getCnds())) {
-                    final Node cndNode = cndsNode.getNode(cnd.getName());
-                    setCndProperties(cndNode, cnd);
-                }
-                for (Module.Cnd cnd : getAdded(current.getCnds(), previous.getCnds())) {
+            final Collection<Module.Cnd> addedCnds = getAdded(current.getCnds(), previous.getCnds());
+            if (!addedCnds.isEmpty()) {
+                final Node cndsNode = JcrUtils.getOrCreateNode(node, CNDS);
+                for (Module.Cnd cnd : addedCnds) {
                     final Node cndNode = cndsNode.addNode(cnd.getName());
                     setCndProperties(cndNode, cnd);
-                    setStatusProperty(cndNode, Module.Status.NEW);
-                    cnd.setStatus(Module.Status.NEW);
+                    setStatusProperty(cndNode, Module.Status.PENDING);
+                    cnd.setStatus(Module.Status.PENDING);
                 }
             }
-
-            if (!current.getContents().equals(previous.getContents())) {
-                final Node contentsNode = getOrCreateNode(node, CONTENTS);
-                for (Module.Content content : getRemoved(current.getContents(), previous.getContents())) {
-                    setStatusProperty(contentsNode.getNode(content.getName()), Module.Status.REMOVED);
-                    content.setStatus(Module.Status.REMOVED);
+            final Collection<Module.Cnd> reloadCnds = getReloadItems(current.getCnds(), previous.getCnds());
+            if (!reloadCnds.isEmpty()) {
+                final Node cndsNode = node.getNode(CNDS);
+                for (Module.Cnd cnd : reloadCnds) {
+                    final Node cndNode = cndsNode.getNode(cnd.getName());
+                    setStatusProperty(cndNode, Module.Status.RELOAD);
+                    cnd.setStatus(Module.Status.RELOAD);
                 }
-                for (Module.Content content : getModified(current.getContents(), previous.getContents())) {
-                    final Node contentNode = contentsNode.getNode(content.getName());
+            }
+
+            final Collection<Module.Content> addedContents = getAdded(current.getContents(), previous.getContents());
+            if (!addedContents.isEmpty()) {
+                final Node contentsNode = JcrUtils.getOrCreateNode(node, CONTENTS);
+                for (Module.Content content : addedContents) {
+                    final Node contentNode = contentsNode.addNode(content.getName());
                     setContentProperties(contentNode, content);
+                    setStatusProperty(contentNode, Module.Status.PENDING);
+                    content.setStatus(Module.Status.PENDING);
                 }
-                for (Module.Content content : getAdded(current.getContents(), previous.getContents())) {
+            }
+            final Collection<Module.Content> reloadContents = getReloadItems(current.getContents(), previous.getContents());
+            if (!reloadContents.isEmpty()) {
+                final Node contentsNode = node.getNode(CONTENTS);
+                for (Module.Content content : reloadContents) {
                     final Node contentNode = contentsNode.getNode(content.getName());
-                    setContentProperties(contentNode, content);
-                    setStatusProperty(contentNode, Module.Status.NEW);
-                    content.setStatus(Module.Status.NEW);
+                    setStatusProperty(contentNode, Module.Status.RELOAD);
+                    content.setStatus(Module.Status.RELOAD);
                 }
             }
 
-            if (!current.getResources().equals(previous.getResources())) {
-                final Node resourcesNode = getOrCreateNode(node, RESOURCES);
-                for (Module.Resource resource : getRemoved(current.getResources(), previous.getResources())) {
-                    setStatusProperty(resourcesNode.getNode(resource.getName()), Module.Status.REMOVED);
-                    resource.setStatus(Module.Status.REMOVED);
-                }
-                for (Module.Resource resource : getModified(current.getResources(), previous.getResources())) {
-                    final Node resourceNode = resourcesNode.getNode(resource.getName());
-                    setResourceProperties(resourceNode, resource);
-                }
-                for (Module.Resource resource : getAdded(current.getResources(), previous.getResources())) {
-                    final Node resourceNode = resourcesNode.getNode(resource.getName());
+            final Collection<Module.Resource> addedResources = getAdded(current.getResources(), previous.getResources());
+            if (!addedResources.isEmpty()) {
+                final Node resourcesNode = JcrUtils.getOrCreateNode(node, RESOURCES);
+                for (Module.Resource resource : addedResources) {
+                    final Node resourceNode = resourcesNode.addNode(resource.getName());
                     setResourceProperties(resourceNode, resource);
-                    setStatusProperty(resourceNode, Module.Status.NEW);
-                    resource.setStatus(Module.Status.NEW);
+                    setStatusProperty(resourceNode, Module.Status.PENDING);
+                    resource.setStatus(Module.Status.PENDING);
                 }
-            }
 
+            }
             session.save();
         } finally {
             session.refresh(false);
@@ -210,58 +194,61 @@ public final class ModuleRegistry {
         log.info("Registering new module '" + module.getName() + "'");
 
         final Node modulesNode = session.getNode(modulesPath);
-        final Node moduleNode = getOrCreateNode(modulesNode, module.getName());
+        final Node moduleNode = JcrUtils.getOrCreateNode(modulesNode, module.getName());
 
         try {
             if (module.getVersion() != null) {
                 moduleNode.setProperty(VERSION, module.getVersion());
             }
             moduleNode.setProperty(BASEURL, module.getBaseUrl());
-            moduleNode.setProperty(STATUS, Module.Status.NEW.toString());
+            if (module.getWorkspace() != null) {
+                moduleNode.setProperty(WORKSPACE, module.getWorkspace());
+            }
+            moduleNode.setProperty(STATUS, Module.Status.PENDING.toString());
 
             if (!module.getDependencies().isEmpty()) {
                 setDependencies(moduleNode, module);
             }
 
             if (!module.getNamespaces().isEmpty()) {
-                final Node namespacesNode = getOrCreateNode(moduleNode, NAMESPACES);
+                final Node namespacesNode = JcrUtils.getOrCreateNode(moduleNode, NAMESPACES);
                 for (Module.Namespace namespace : module.getNamespaces()) {
                     if (!namespacesNode.hasNode(namespace.getName())) {
                         final Node namespaceNode = namespacesNode.addNode(namespace.getName());
                         setNamespaceProperties(namespaceNode, namespace);
-                        setStatusProperty(namespaceNode, Module.Status.NEW);
-                        namespace.setStatus(Module.Status.NEW);
+                        setStatusProperty(namespaceNode, Module.Status.PENDING);
+                        namespace.setStatus(Module.Status.PENDING);
                     }
                 }
             }
 
             if (!module.getCnds().isEmpty()) {
-                final Node cndsNode = getOrCreateNode(moduleNode, CNDS);
+                final Node cndsNode = JcrUtils.getOrCreateNode(moduleNode, CNDS);
                 for (Module.Cnd cnd : module.getCnds()) {
-                    Node cndNode = getOrCreateNode(cndsNode, cnd.getName());
+                    Node cndNode = JcrUtils.getOrCreateNode(cndsNode, cnd.getName());
                     setCndProperties(cndNode, cnd);
-                    setStatusProperty(cndNode, Module.Status.NEW);
-                    cnd.setStatus(Module.Status.NEW);
+                    setStatusProperty(cndNode, Module.Status.PENDING);
+                    cnd.setStatus(Module.Status.PENDING);
                 }
             }
 
             if (!module.getContents().isEmpty()) {
-                final Node contentsNode = getOrCreateNode(moduleNode, CONTENTS);
+                final Node contentsNode = JcrUtils.getOrCreateNode(moduleNode, CONTENTS);
                 for (Module.Content content : module.getContents()) {
-                    final Node contentNode = getOrCreateNode(contentsNode, content.getName());
+                    final Node contentNode = JcrUtils.getOrCreateNode(contentsNode, content.getName());
                     setContentProperties(contentNode, content);
-                    setStatusProperty(contentNode, Module.Status.NEW);
-                    content.setStatus(Module.Status.NEW);
+                    setStatusProperty(contentNode, Module.Status.PENDING);
+                    content.setStatus(Module.Status.PENDING);
                 }
             }
 
             if (!module.getResources().isEmpty()) {
-                final Node resourcesNode = getOrCreateNode(moduleNode, RESOURCES);
+                final Node resourcesNode = JcrUtils.getOrCreateNode(moduleNode, RESOURCES);
                 for (Module.Resource resource : module.getResources()) {
-                    final Node resourceNode = getOrCreateNode(resourcesNode, resource.getName());
+                    final Node resourceNode = JcrUtils.getOrCreateNode(resourcesNode, resource.getName());
                     setResourceProperties(resourceNode, resource);
-                    setStatusProperty(resourceNode, Module.Status.NEW);
-                    resource.setStatus(Module.Status.NEW);
+                    setStatusProperty(resourceNode, Module.Status.PENDING);
+                    resource.setStatus(Module.Status.PENDING);
                 }
             }
 
@@ -314,12 +301,10 @@ public final class ModuleRegistry {
     private Module readModule(Node node) throws RepositoryException {
         final String name = node.getName();
         final String baseUrl = node.getProperty(BASEURL).getString();
-        final String version = node.hasProperty(VERSION) ? node.getProperty(VERSION).getString() : null;
-
-        final Module module = new Module(name, baseUrl, version);
+        final String moduleVersion = JcrUtils.getStringProperty(node, VERSION, null);
+        final String defaultWorkspace = JcrUtils.getStringProperty(node, WORKSPACE, null);
 
-        Module.Status status = Module.Status.valueOf(node.getProperty(STATUS).getString());
-        module.setStatus(status);
+        final Module module = new Module(name, baseUrl, moduleVersion, defaultWorkspace);
 
         if (node.hasProperty(DEPENDENCIES)) {
             for (Value value : node.getProperty(DEPENDENCIES).getValues()) {
@@ -333,7 +318,7 @@ public final class ModuleRegistry {
                 final Node item = iter.nextNode();
                 final String prefix = item.getName();
                 final String uri = item.getProperty(URI).getString();
-                status = Module.Status.valueOf(item.getProperty(STATUS).getString());
+                final Module.Status status = readStatus(item);
                 module.addNamespace(prefix, uri, status);
             }
         }
@@ -343,9 +328,10 @@ public final class ModuleRegistry {
             while (iter.hasNext()) {
                 final Node item = iter.nextNode();
                 final String file = item.getProperty(FILE).getString();
-                final boolean reload = !item.hasProperty(RELOAD) || item.getProperty(RELOAD).getBoolean();
-                status = Module.Status.valueOf(item.getProperty(STATUS).getString());
-                module.addCnd(item.getName(), file, reload, status);
+                final boolean reload = JcrUtils.getBooleanProperty(item, RELOAD, false);
+                final Module.Status status = readStatus(item);
+                final String version = JcrUtils.getStringProperty(item, VERSION, null);
+                module.addCnd(item.getName(), file, reload, status, version);
             }
         }
 
@@ -355,14 +341,12 @@ public final class ModuleRegistry {
                 final Node item = iter.nextNode();
                 final String file = item.getProperty(FILE).getString();
                 final String parent = item.getProperty(PARENT).getString();
-                final boolean reload = item.hasProperty(RELOAD) && item.getProperty(RELOAD).getBoolean();
-                final String workspace = !item.hasProperty(WORKSPACE) ? null : item.getProperty(WORKSPACE).getString();
-                ImportBehavior importBehavior = null;
-                if (item.hasProperty(IMPORTBEHAVIOR)) {
-                    importBehavior = ImportBehavior.valueOf(item.getProperty(IMPORTBEHAVIOR).getString().toUpperCase());
-                }
-                status = Module.Status.valueOf(item.getProperty(STATUS).getString());
-                module.addContent(item.getName(), file, parent, reload, workspace, importBehavior, status);
+                final boolean reload = JcrUtils.getBooleanProperty(item, RELOAD, false);
+                final String workspace = JcrUtils.getStringProperty(item, WORKSPACE, null);
+                final ImportBehavior importBehavior = readImportBehavior(item);
+                final Module.Status status = readStatus(item);
+                final String version = JcrUtils.getStringProperty(item, VERSION, null);
+                module.addContent(item.getName(), file, parent, reload, workspace, importBehavior, status, version);
             }
         }
 
@@ -372,12 +356,9 @@ public final class ModuleRegistry {
                 final Node item = iter.nextNode();
                 final String path = item.getProperty(PATH).getString();
                 final String parent = item.getProperty(PARENT).getString();
-                final String workspace = !item.hasProperty(WORKSPACE) ? null : item.getProperty(WORKSPACE).getString();
-                ImportBehavior importBehavior = null;
-                if (item.hasProperty(IMPORTBEHAVIOR)) {
-                    importBehavior = ImportBehavior.valueOf(item.getProperty(IMPORTBEHAVIOR).getString().toUpperCase());
-                }
-                status = Module.Status.valueOf(item.getProperty(STATUS).getString());
+                final String workspace = JcrUtils.getStringProperty(item, WORKSPACE, null);
+                final ImportBehavior importBehavior = readImportBehavior(item);
+                final Module.Status status = readStatus(item);
                 module.addResource(item.getName(), path, parent, workspace, importBehavior, status);
             }
         }
@@ -385,11 +366,28 @@ public final class ModuleRegistry {
         return module;
     }
 
-    private Node getOrCreateNode(Node parent, String name) throws RepositoryException {
-        if (parent.hasNode(name)) {
-            return parent.getNode(name);
+    private Module.Status readStatus(Node item) throws RepositoryException {
+        String value = JcrUtils.getStringProperty(item, STATUS, null);
+        if (value != null) {
+            try {
+                return Module.Status.valueOf(value);
+            } catch (IllegalArgumentException e) {
+                log.error("Unrecognized value for " + STATUS + " property at " + item.getPath());
+            }
+        }
+        return null;
+    }
+
+    private ImportBehavior readImportBehavior(final Node item) throws RepositoryException {
+        String value = JcrUtils.getStringProperty(item, IMPORTBEHAVIOR, null);
+        if (value != null) {
+            try {
+                return ImportBehavior.valueOf(value.toUpperCase());
+            } catch (IllegalArgumentException e) {
+                log.error("Unrecognized value for " + IMPORTBEHAVIOR + " property at " + item.getPath());
+            }
         }
-        return parent.addNode(name);
+        return null;
     }
 
     private void setStatusProperty(Node node, Module.Status status) throws RepositoryException {
@@ -403,6 +401,9 @@ public final class ModuleRegistry {
     private void setCndProperties(Node cndNode, Module.Cnd cnd) throws RepositoryException {
         cndNode.setProperty(FILE, cnd.getFile());
         cndNode.setProperty(RELOAD, cnd.isReload());
+        if (cnd.getVersion() != null) {
+            cndNode.setProperty(VERSION, cnd.getVersion());
+        }
     }
 
     private void setContentProperties(Node contentNode, Module.Content content) throws RepositoryException {
@@ -415,12 +416,14 @@ public final class ModuleRegistry {
         if (content.getImportBehavior() != null) {
             contentNode.setProperty(IMPORTBEHAVIOR, content.getImportBehavior().toString());
         }
+        if (content.getVersion() != null) {
+            contentNode.setProperty(VERSION, content.getVersion());
+        }
     }
 
     private void setResourceProperties(final Node resourceNode, final Module.Resource resource) throws RepositoryException {
         resourceNode.setProperty(PATH, resource.getPath());
         resourceNode.setProperty(PARENT, resource.getParent());
-        resourceNode.setProperty(RELOAD, resource.isReload());
         if (resource.getWorkspace() != null) {
             resourceNode.setProperty(WORKSPACE, resource.getWorkspace());
         }
@@ -429,7 +432,6 @@ public final class ModuleRegistry {
         }
     }
 
-
     private void setDependencies(Node node, Module module) throws RepositoryException {
         ValueFactory valueFactory = session.getValueFactory();
         Collection<Value> values = new ArrayList<Value>(module.getDependencies().size());
@@ -439,25 +441,21 @@ public final class ModuleRegistry {
         node.setProperty(DEPENDENCIES, values.toArray(new Value[values.size()]));
     }
 
-    private <T extends Module.Item> Collection<T> getModified(Collection<T> current, Collection<T> previous) {
-        Collection<T> modified = new ArrayList<T>(current.size());
+    private <T extends Module.ReloadableItem> Collection<T> getReloadItems(Collection<T> current, Collection<T> previous) {
+        Collection<T> reload = new ArrayList<T>(current.size());
         for (T currentItem : current) {
-            T previousItem = getItem(currentItem.getName(), previous);
-            if (previousItem != null && !currentItem.equals(previousItem)) {
-                modified.add(currentItem);
-            }
-        }
-        return modified;
-    }
-
-    private <T extends Module.Item> Collection<T> getRemoved(Collection<T> current, Collection<T> previous) {
-        Collection<T> removed = new ArrayList<T>(previous.size());
-        for (T previousItem : previous) {
-            if (getItem(previousItem.getName(), current) == null) {
-                removed.add(previousItem);
+            if (currentItem.isReload()) {
+                T previousItem = getItem(currentItem.getName(), previous);
+                if (previousItem != null) {
+                    String currentVersion = currentItem.getVersion() != null ? currentItem.getVersion() : currentItem.getModule().getVersion();
+                    String previousVersion = previousItem.getVersion() != null ? previousItem.getVersion() : previousItem.getModule().getVersion();
+                    if (currentVersion != null ? currentVersion.equals(previousVersion) : previousVersion != null) {
+                        reload.add(currentItem);
+                    }
+                }
             }
         }
-        return removed;
+        return reload;
     }
 
     private <T extends Module.Item> Collection<T> getAdded(Collection<T> current, Collection<T> previous) {

Modified: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleScanner.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleScanner.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleScanner.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/bootstrapping/ModuleScanner.java Sat Jun 23 14:54:29 2012
@@ -101,8 +101,9 @@ public final class ModuleScanner {
 
         final String moduleName = object.get(NAME).textValue();
         final String newVersion = object.has(VERSION) ? object.get(VERSION).textValue() : null;
+        final String defaultWorkspace = object.has(WORKSPACE) ? object.get(WORKSPACE).textValue() : null;
 
-        final Module module = new Module(moduleName, baseUrl, newVersion);
+        final Module module = new Module(moduleName, baseUrl, newVersion, defaultWorkspace);
 
         final JsonNode dependencies = object.get(DEPENDENCIES);
         if (dependencies != null && dependencies.isArray()) {
@@ -128,12 +129,13 @@ public final class ModuleScanner {
             while (iter.hasNext()) {
                 final String name = iter.next();
                 final JsonNode cnd = cnds.get(name);
-                if (!cnd.has("file")) {
+                if (!cnd.has(FILE)) {
                     throw new BootstrapException("cnd definition must specify a file field");
                 }
                 final String file = cnd.get(FILE).textValue();
-                final boolean reload = !cnd.has(RELOAD) || cnd.get(RELOAD).booleanValue();
-                module.addCnd(name, file, reload, null);
+                final boolean reload = cnd.has(RELOAD) && cnd.get(RELOAD).booleanValue();
+                final String version = cnd.has(VERSION) ? cnd.get(VERSION).textValue() : null;
+                module.addCnd(name, file, reload, null, version);
             }
         }
 
@@ -150,11 +152,9 @@ public final class ModuleScanner {
                 final String parent = content.get(PARENT).textValue();
                 final boolean reload = content.has(RELOAD) && content.get(RELOAD).booleanValue();
                 final String workspace = !content.has(WORKSPACE) ? null : content.get(WORKSPACE).textValue();
-                ImportBehavior importBehavior = null;
-                if (content.has(IMPORTBEHAVIOR)) {
-                    importBehavior = ImportBehavior.valueOf(content.get(IMPORTBEHAVIOR).textValue().toUpperCase());
-                }
-                module.addContent(name, file, parent, reload, workspace, importBehavior, null);
+                final ImportBehavior importBehavior = parseImportBehavior(content);
+                final String version = content.has(VERSION) ? content.get(VERSION).textValue() : null;
+                module.addContent(name, file, parent, reload, workspace, importBehavior, null, version);
             }
         }
 
@@ -170,10 +170,7 @@ public final class ModuleScanner {
                 final String path = resource.has(PATH) ? resource.get(PATH).textValue() : "";
                 final String parent = resource.get(PARENT).textValue();
                 final String workspace = !resource.has(WORKSPACE) ? null : resource.get(WORKSPACE).textValue();;
-                ImportBehavior importBehavior = null;
-                if (resource.has(IMPORTBEHAVIOR)) {
-                    importBehavior = ImportBehavior.valueOf(resource.get(IMPORTBEHAVIOR).textValue().toUpperCase());
-                }
+                final ImportBehavior importBehavior = parseImportBehavior(resource);
                 module.addResource(name, path, parent, workspace, importBehavior, null);
             }
         }
@@ -181,9 +178,20 @@ public final class ModuleScanner {
         return module;
     }
 
+    private ImportBehavior parseImportBehavior(final JsonNode node) throws BootstrapException {
+        if (!node.has(IMPORTBEHAVIOR)) {
+            return null;
+        }
+        final String value = node.get(IMPORTBEHAVIOR).textValue();
+        try {
+            return ImportBehavior.valueOf(value.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            throw new BootstrapException("Unrecognized value for " + IMPORTBEHAVIOR + " field: " + value);
+        }
+    }
 
     private String getBaseURL(URL moduleDescriptor) {
-        String s = moduleDescriptor.toString();
+        final String s = moduleDescriptor.toString();
         if (!s.endsWith(moduleDescriptorPath)) {
             throw new IllegalArgumentException("Expected module descriptor to be at " + moduleDescriptorPath);
         }

Modified: rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/RaveRepositoryImpl.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/RaveRepositoryImpl.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/RaveRepositoryImpl.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/main/java/org/apache/rave/jcr/jackrabbit/RaveRepositoryImpl.java Sat Jun 23 14:54:29 2012
@@ -20,7 +20,6 @@ package org.apache.rave.jcr.jackrabbit;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedHashMap;
 import java.util.Map;
 
 import javax.jcr.NamespaceException;
@@ -89,9 +88,10 @@ public class RaveRepositoryImpl extends 
                 moduleRegistry.writeModule(module);
             }
 
-            final Map<Module, Module> modified = getModifiedModules(current, previous);
-            for (Map.Entry<Module, Module> entry : modified.entrySet()) {
-                moduleRegistry.updateModule(entry.getKey(), entry.getValue());
+            for (Map.Entry<String, Module> entry : previous.entrySet()) {
+                if (current.containsKey(entry.getKey())) {
+                    moduleRegistry.updateModule(current.get(entry.getKey()), entry.getValue());
+                }
             }
         } finally {
             session.refresh(false);
@@ -156,16 +156,4 @@ public class RaveRepositoryImpl extends 
         return added;
     }
 
-    private Map<Module, Module> getModifiedModules(Map<String, Module> current, Map<String, Module> previous) {
-        Map<Module, Module> modified = new LinkedHashMap<Module, Module>();
-        for (Map.Entry<String, Module> entry : current.entrySet()) {
-            final String moduleName = entry.getKey();
-            final Module currentModule = entry.getValue();
-            if (previous.containsKey(moduleName) && !currentModule.equals(previous.get(moduleName))) {
-                modified.put(currentModule, previous.get(moduleName));
-            }
-        }
-        return modified;
-    }
-
 }

Modified: rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleRegistryTest.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleRegistryTest.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleRegistryTest.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleRegistryTest.java Sat Jun 23 14:54:29 2012
@@ -19,11 +19,9 @@
 package org.apache.rave.jcr.bootstrapping;
 
 import java.net.URL;
-import java.util.Enumeration;
 
 import javax.jcr.NamespaceException;
 import javax.jcr.Node;
-import javax.jcr.NodeIterator;
 import javax.jcr.Session;
 
 import org.apache.jackrabbit.test.AbstractJCRTest;
@@ -76,6 +74,8 @@ public class ModuleRegistryTest extends 
         assertTrue(moduleNode.hasProperty("version"));
         assertEquals("v1", moduleNode.getProperty("version").getString());
         assertTrue(moduleNode.hasProperty("baseUrl"));
+        assertTrue(moduleNode.hasProperty("workspace"));
+        assertEquals("moduleWs", moduleNode.getProperty("workspace").getString());
 
         // namespaces
         assertTrue(moduleNode.hasNode("namespaces"));
@@ -110,6 +110,7 @@ public class ModuleRegistryTest extends 
         contentNode = moduleNode.getNode("contents/bar");
         assertTrue(contentNode.hasProperty("workspace"));
         assertEquals("myws", contentNode.getProperty("workspace").getString());
+        assertEquals("v2", contentNode.getProperty("version").getString());
 
         // resources
         assertTrue(moduleNode.hasNode("resources"));
@@ -129,12 +130,12 @@ public class ModuleRegistryTest extends 
         final ModuleScanner moduleScanner = new ModuleScanner("rave");
         final Module module = moduleScanner.parse(getClass().getResource("/META-INF/rave/module.json"));
         moduleRegistry.writeModule(module);
-        assertEquals(module, moduleRegistry.readModule(module.getName()));
+        assertEquals(module.toString(), moduleRegistry.readModule(module.getName()).toString());
     }
 
     public void testRemoveModule() throws Exception {
         final ModuleRegistry moduleRegistry = new ModuleRegistry(session, "/rave:system");
-        final Module module = new Module("foo", "foo", "");
+        final Module module = new Module("foo", "foo", null, null);
         moduleRegistry.writeModule(module);
         moduleRegistry.removeModule(module);
         assertFalse(session.nodeExists("/rave:system/modules/foo"));
@@ -146,7 +147,7 @@ public class ModuleRegistryTest extends 
         Module module = moduleScanner.parse(getClass().getResource("/META-INF/rave/module.json"));
         moduleRegistry.writeModule(module);
 
-        module.addNamespace("bar", "http://bar.com/1.0", Module.Status.NEW);
+        module.addNamespace("bar", "http://bar.com/1.0", Module.Status.PENDING);
         moduleRegistry.updateModule(module, moduleRegistry.readModule(module.getName()));
 
         module = moduleRegistry.readModule(module.getName());

Modified: rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleScannerTest.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleScannerTest.java?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleScannerTest.java (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/java/org/apache/rave/jcr/bootstrapping/ModuleScannerTest.java Sat Jun 23 14:54:29 2012
@@ -68,13 +68,14 @@ public class ModuleScannerTest {
         final Module.Content foo = iter.next();
         assertEquals("foo.json", foo.getFile());
         assertEquals("/testroot", foo.getParent());
-        assertTrue(foo.isReload());
+        assertFalse(foo.isReload());
         assertEquals(ImportBehavior.MERGE, foo.getImportBehavior());
 
         final Module.Content bar = iter.next();
         assertEquals("bar.json", bar.getFile());
         assertEquals("/testroot", bar.getParent());
-        assertFalse(bar.isReload());
+        assertTrue(bar.isReload());
+        assertEquals("v2", bar.getVersion());
         assertEquals("myws", bar.getWorkspace());
 
         assertEquals(1, module.getResources().size());

Modified: rave/sandbox/content-services/rave-jcr-config/src/test/resources/META-INF/rave/module.json
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-config/src/test/resources/META-INF/rave/module.json?rev=1353133&r1=1353132&r2=1353133&view=diff
==============================================================================
--- rave/sandbox/content-services/rave-jcr-config/src/test/resources/META-INF/rave/module.json (original)
+++ rave/sandbox/content-services/rave-jcr-config/src/test/resources/META-INF/rave/module.json Sat Jun 23 14:54:29 2012
@@ -1,6 +1,7 @@
 {
   "name" : "foo",
   "version" : "v1",
+  "workspace" : "moduleWs",
   "dependencies" : [ "bar", "quz" ],
   "namespaces" : {
       "foo" : "http://foo.com/1.0"
@@ -20,7 +21,8 @@
     "bar" : {
       "file" : "bar.json",
       "parent" : "/testroot",
-      "reload" : false,
+      "reload" : true,
+      "version" : "v2",
       "workspace" : "myws"
     }
   },

Propchange: rave/sandbox/content-services/rave-jcr-utils/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Sat Jun 23 14:54:29 2012
@@ -0,0 +1,2 @@
+rave-jcr-utils.iml
+target

Added: rave/sandbox/content-services/rave-jcr-utils/pom.xml
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-utils/pom.xml?rev=1353133&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-utils/pom.xml (added)
+++ rave/sandbox/content-services/rave-jcr-utils/pom.xml Sat Jun 23 14:54:29 2012
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+
+  $Id: pom.xml 1303795 2012-03-22 14:19:45Z ate $
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
+  >
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.rave.sandbox.jcr</groupId>
+    <artifactId>rave-content-services</artifactId>
+    <version>sandbox-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>rave-jcr-utils</artifactId>
+  <name>Apache Rave :: rave-jcr-utils</name>
+  <description>Apache Rave JCR Utilities Module</description>
+  <packaging>jar</packaging>
+
+</project>

Added: rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/utils/JcrUtils.java
URL: http://svn.apache.org/viewvc/rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/utils/JcrUtils.java?rev=1353133&view=auto
==============================================================================
--- rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/utils/JcrUtils.java (added)
+++ rave/sandbox/content-services/rave-jcr-utils/src/main/java/org/apache/rave/jcr/utils/JcrUtils.java Sat Jun 23 14:54:29 2012
@@ -0,0 +1,49 @@
+/*
+ * 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.rave.jcr.utils;
+
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+
+public class JcrUtils {
+
+    public static String getStringProperty(Node node, String propertyName, String defaultValue) throws RepositoryException {
+        try {
+            return node.getProperty(propertyName).getString();
+        } catch (PathNotFoundException e) {
+            return defaultValue;
+        }
+    }
+
+    public static boolean getBooleanProperty(final Node node, final String propertyName, final boolean defaultValue) throws RepositoryException {
+        try {
+            return node.getProperty(propertyName).getBoolean();
+        } catch (PathNotFoundException e) {
+            return defaultValue;
+        }
+    }
+
+    public static Node getOrCreateNode(Node parent, String name) throws RepositoryException {
+        if (parent.hasNode(name)) {
+            return parent.getNode(name);
+        }
+        return parent.addNode(name);
+    }
+}