Add node mapper abstraction
authorMathieu Baudier <mbaudier@argeo.org>
Mon, 22 Mar 2010 14:48:23 +0000 (14:48 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Mon, 22 Mar 2010 14:48:23 +0000 (14:48 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@3437 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/BeanNodeMapper.java
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapper.java [new file with mode: 0644]
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapperProvider.java [new file with mode: 0644]

index d05af407f33e3996e696c871bf0d146746868588..f066ce8f931a46ee099a4d03354da7a818e050ca 100644 (file)
@@ -28,7 +28,7 @@ import org.argeo.ArgeoException;
 import org.springframework.beans.BeanWrapper;
 import org.springframework.beans.BeanWrapperImpl;
 
-public class BeanNodeMapper {
+public class BeanNodeMapper implements NodeMapper, NodeMapperProvider {
        private final static Log log = LogFactory.getLog(BeanNodeMapper.class);
 
        private final static String NODE_VALUE = "value";
@@ -43,6 +43,17 @@ public class BeanNodeMapper {
 
        private ClassLoader classLoader = getClass().getClassLoader();
 
+       private NodeMapperProvider nodeMapperProvider;
+
+       public void update(Node node, Object obj) {
+               try {
+                       beanToNode(createBeanWrapper(obj), node);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot update node " + node + " with "
+                                       + obj, e);
+               }
+       }
+
        public String storagePath(Object obj) {
                String clss = obj.getClass().getName();
                StringBuffer buf = new StringBuffer("/objects/");
@@ -57,16 +68,6 @@ public class BeanNodeMapper {
        public Node save(Session session, Object obj) {
                return save(session, storagePath(obj), obj);
        }
-
-       public void update(Node node, Object obj) {
-               try {
-                       beanToNode(createBeanWrapper(obj), node);
-               } catch (RepositoryException e) {
-                       throw new ArgeoException("Cannot update node " + node + " with "
-                                       + obj, e);
-               }
-       }
-
        public Node save(Session session, String path, Object obj) {
                try {
                        BeanWrapper beanWrapper = createBeanWrapper(obj);
@@ -96,8 +97,23 @@ public class BeanNodeMapper {
                }
        }
 
+       public Object load(Node node) {
+               try {
+                       return nodeToBean(node);
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot load object from node " + node, e);
+               }
+       }
+
        @SuppressWarnings("unchecked")
+       /** Transforms an object into a node*/
        public Object nodeToBean(Node node) throws RepositoryException {
+               if (nodeMapperProvider != null) {
+                       NodeMapper nodeMapper = nodeMapperProvider.findNodeMapper(node);
+                       if (nodeMapper != null) {
+                               return nodeMapper.load(node);
+                       }
+               }
 
                String clssName = node.getProperty(classProperty).getValue()
                                .getString();
@@ -118,7 +134,7 @@ public class BeanNodeMapper {
                                        .getName());
                        Class propClass = pd.getPropertyType();
 
-                       // list
+                       // primitive list
                        if (propClass != null && List.class.isAssignableFrom(propClass)) {
                                List<Object> lst = new ArrayList<Object>();
                                Class<?> valuesClass = classFromProperty(prop);
@@ -145,6 +161,7 @@ public class BeanNodeMapper {
                        PropertyDescriptor pd = beanWrapper.getPropertyDescriptor(name);
                        Class propClass = pd.getPropertyType();
 
+                       // objects list
                        if (propClass != null && List.class.isAssignableFrom(propClass)) {
                                String lstClass = childNode.getProperty(classProperty)
                                                .getString();
@@ -166,6 +183,7 @@ public class BeanNodeMapper {
                                continue nodes;
                        }
 
+                       // objects map
                        if (propClass != null && Map.class.isAssignableFrom(propClass)) {
                                String mapClass = childNode.getProperty(classProperty)
                                                .getString();
@@ -219,6 +237,15 @@ public class BeanNodeMapper {
 
        protected void beanToNode(BeanWrapper beanWrapper, Node node)
                        throws RepositoryException {
+
+               if (nodeMapperProvider != null) {
+                       NodeMapper nodeMapper = nodeMapperProvider.findNodeMapper(node);
+                       if (nodeMapper != null) {
+                               nodeMapper.update(node, beanWrapper.getWrappedInstance());
+                               return;
+                       }
+               }
+
                if (log.isTraceEnabled())
                        log.debug("Map bean to node " + node.getPath());
 
@@ -473,7 +500,7 @@ public class BeanNodeMapper {
        }
 
        protected Class<?> loadClass(String name) {
-               //log.debug("Class loader: " + classLoader);
+               // log.debug("Class loader: " + classLoader);
                try {
                        return classLoader.loadClass(name);
                } catch (ClassNotFoundException e) {
@@ -481,6 +508,11 @@ public class BeanNodeMapper {
                }
        }
 
+       /** Returns itself. */
+       public NodeMapper findNodeMapper(Node node) {
+               return this;
+       }
+
        protected String propertyName(String name) {
                return name;
        }
@@ -509,4 +541,8 @@ public class BeanNodeMapper {
                this.classLoader = classLoader;
        }
 
+       public void setNodeMapperProvider(NodeMapperProvider nodeMapperProvider) {
+               this.nodeMapperProvider = nodeMapperProvider;
+       }
+
 }
index 91ca780b132b6d2eccaeb784e41f3340b2be4020..ddbb7c71f006c5f4d60fd5572fde53aef4a75340 100644 (file)
@@ -74,7 +74,7 @@ public class JcrUtils {
                if (path.charAt(path.length() - 1) == '/')
                        throw new ArgeoException("Path " + path + " cannot end with '/'");
                int index = path.lastIndexOf('/');
-               if (index <= 0)
+               if (index < 0)
                        throw new ArgeoException("Cannot find last path element for "
                                        + path);
                return path.substring(index + 1);
diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapper.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapper.java
new file mode 100644 (file)
index 0000000..df0ff3f
--- /dev/null
@@ -0,0 +1,12 @@
+package org.argeo.jcr;
+
+import javax.jcr.Node;
+import javax.jcr.Session;
+
+public interface NodeMapper {
+       public Object load(Node node);
+
+       public void update(Node node, Object obj);
+
+       public Node save(Session session, String path, Object obj);
+}
diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapperProvider.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapperProvider.java
new file mode 100644 (file)
index 0000000..1d3c11b
--- /dev/null
@@ -0,0 +1,9 @@
+package org.argeo.jcr;
+
+import javax.jcr.Node;
+
+/** Provides a node mapper relevant for this node. */
+public interface NodeMapperProvider {
+       /** @return the node mapper or null if no relvant node mapper cna be found. */
+       public NodeMapper findNodeMapper(Node node);
+}