From f0e8b8dc680eb131d11e53180c3912ece49f37fc Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Mon, 22 Mar 2010 14:48:23 +0000 Subject: [PATCH] Add node mapper abstraction git-svn-id: https://svn.argeo.org/commons/trunk@3437 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../java/org/argeo/jcr/BeanNodeMapper.java | 62 +++++++++++++++---- .../src/main/java/org/argeo/jcr/JcrUtils.java | 2 +- .../main/java/org/argeo/jcr/NodeMapper.java | 12 ++++ .../org/argeo/jcr/NodeMapperProvider.java | 9 +++ 4 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapper.java create mode 100644 server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapperProvider.java diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/BeanNodeMapper.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/BeanNodeMapper.java index d05af407f..f066ce8f9 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/BeanNodeMapper.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/BeanNodeMapper.java @@ -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 lst = new ArrayList(); 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; + } + } diff --git a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/JcrUtils.java b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/JcrUtils.java index 91ca780b1..ddbb7c71f 100644 --- a/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/JcrUtils.java +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/JcrUtils.java @@ -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 index 000000000..df0ff3f3f --- /dev/null +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapper.java @@ -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 index 000000000..1d3c11b20 --- /dev/null +++ b/server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jcr/NodeMapperProvider.java @@ -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); +} -- 2.30.2