r1030 - in lutinjaxx/trunk: . jaxx-core jaxx-core/src/main/java/jaxx/runtime/swing/navigation jaxx-core/src/test/java/jaxx/runtime/swing/navigation
Author: chemit Date: 2008-11-24 15:33:42 +0000 (Mon, 24 Nov 2008) New Revision: 1030 Modified: lutinjaxx/trunk/jaxx-core/pom.xml lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java lutinjaxx/trunk/pom.xml Log: use JXPath to compute bean value in a NavigationTreeModel Modified: lutinjaxx/trunk/jaxx-core/pom.xml =================================================================== --- lutinjaxx/trunk/jaxx-core/pom.xml 2008-11-24 15:33:01 UTC (rev 1029) +++ lutinjaxx/trunk/jaxx-core/pom.xml 2008-11-24 15:33:42 UTC (rev 1030) @@ -46,6 +46,11 @@ <artifactId>jxlayer</artifactId> </dependency> + <dependency> + <groupId>commons-jxpath</groupId> + <artifactId>commons-jxpath</artifactId> + </dependency> + </dependencies> <!-- ************************************************************* --> Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java 2008-11-24 15:33:01 UTC (rev 1029) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java 2008-11-24 15:33:42 UTC (rev 1030) @@ -5,8 +5,8 @@ import jaxx.runtime.JAXXContext; import jaxx.runtime.JAXXContextEntryDef; import jaxx.runtime.JAXXObject; -import org.apache.commons.beanutils.BeanUtilsBean; -import org.apache.commons.beanutils.PropertyUtilsBean; +import jaxx.runtime.swing.navigation.NavigationUtil.NodeRenderer; +import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -14,7 +14,6 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import java.lang.reflect.InvocationTargetException; -import java.util.List; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -50,28 +49,61 @@ /** the definition of the JAXXContext entry associated to this node, if null will seek in parent */ protected JAXXContextEntryDef jaxxContextEntryDef; - public NavigationTreeNode(String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass, JAXXContextEntryDef jaxxContextEntryDef) { + protected String jaxxContextEntryPath; + + protected NodeRenderer renderer; + + public NavigationTreeNode(Object renderer, Object jaxxContextEntryDef, String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass) { + super(renderer); + if (renderer instanceof NodeRenderer) { + // the renderer must keep a reference of the node + ((NodeRenderer) renderer).setNode(this); + } else if (renderer instanceof String) { + // nothing special to be done + } else { + if (renderer != null) { + // wrong renderer type + throw new IllegalArgumentException("to define a renderer, must be a String (simple libelle) or a " + NodeRenderer.class + ", but was " + renderer); + } + } this.context = context; this.jaxxClass = jaxxClass; this.jaxxActionClass = jaxxActionClass; - this.jaxxContextEntryDef = jaxxContextEntryDef; + + if (jaxxContextEntryDef instanceof JAXXContextEntryDef) { + this.jaxxContextEntryDef = ((JAXXContextEntryDef) jaxxContextEntryDef); + } else if (jaxxContextEntryDef instanceof String) { + this.jaxxContextEntryPath = (String) jaxxContextEntryDef; + } else { + if (jaxxContextEntryDef != null) { + // wront context definition type + throw new IllegalArgumentException("to define a context link, must be a String (jxpath) or a " + JAXXContextEntryDef.class + ", but was " + jaxxContextEntryDef); + } + } } - public NavigationTreeNode(Object userObject, String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass, JAXXContextEntryDef jaxxContextEntryDef) { + /*public NavigationTreeNode(String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass, JAXXContextEntryDef jaxxContextEntryDef) { + this.context = context; + this.jaxxClass = jaxxClass; + this.jaxxActionClass = jaxxActionClass; + this.jaxxContextEntryDef = jaxxContextEntryDef; + }*/ + + /*public NavigationTreeNode(Object userObject, String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass, JAXXContextEntryDef jaxxContextEntryDef) { super(userObject); this.context = context; this.jaxxClass = jaxxClass; this.jaxxActionClass = jaxxActionClass; this.jaxxContextEntryDef = jaxxContextEntryDef; - } + }*/ - public NavigationTreeNode(Object userObject, boolean allowsChildren, String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass, JAXXContextEntryDef jaxxContextEntryDef) { + /*public NavigationTreeNode(Object userObject, boolean allowsChildren, String context, Class<? extends JAXXObject> jaxxClass, Class<? extends JAXXAction> jaxxActionClass, JAXXContextEntryDef jaxxContextEntryDef) { super(userObject, allowsChildren); this.context = context; this.jaxxClass = jaxxClass; this.jaxxActionClass = jaxxActionClass; this.jaxxContextEntryDef = jaxxContextEntryDef; - } + }*/ public String getContext() { return context; @@ -169,6 +201,127 @@ return son == null ? null : son.findNode(stack); } + /** + * Obtain the associated bean value from context corresponding to node + * + * @param context the context to seek + * @return the value associated in context with the given context path + * @throws InvocationTargetException todo + * @throws NoSuchMethodException todo + * @throws IllegalAccessException todo + */ + public Object getJAXXContextValue(JAXXContext context) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + Object result; + + if (getJaxxContextEntryDef() != null) { + // the node maps directly a value in context + result = getJaxxContextEntryDef().getContextValue(context); + return result; + } + // find the first ancestor node with a context def + NavigationTreeNode parentNode = getFirstAncestorWithDef(); + if (parentNode == null) { + log.warn("could not find a ancestor node with a definition of a context entry from node (" + this + ")"); + // todo must be an error + // no parent found + return null; + } + + Object parentBean = parentNode.getJaxxContextEntryDef().getContextValue(context); + //Object parentBean = parentNode.getJAXXContextValue(context); + + if (parentBean == null) { + // must be an error no bean found + log.warn("culd not find a bean attached in context from context entry definition " + parentNode.getJaxxContextEntryDef()); + return null; + } + + if (this == parentNode) { + // current node is the node matching the context entry value + return parentBean; + } + + if (jaxxContextEntryPath == null) { + // todo must be an error + log.warn("must find a jaxxContextEntryPath on node (" + this + ")"); + return null; + } + + String jxpathExpression = computeJXPath(jaxxContextEntryPath, parentNode); + + if (jxpathExpression == null) { + /// todo must be an error + log.warn("could not build jxpath from node " + parentNode + " to " + this); + // could not retreave the jxpath... + return null; + } + if (jxpathExpression.startsWith("[")) { + // special case when we want to access a collection + jxpathExpression = '.'+jxpathExpression; + } + log.info("jxpath : " + jxpathExpression); + + JXPathContext jxcontext = JXPathContext.newContext(parentBean); + + result = jxcontext.getValue(jxpathExpression); + + return result; + } + + protected String computeJXPath(String expr, NavigationTreeNode parentNode) { + if (parentNode == this) { + // reach the parent limit node, return the expr computed + return expr; + } + int firstIndex = expr.indexOf(".."); + int lastIndex = expr.lastIndexOf(".."); + + if (firstIndex == -1) { + // this is a error, since current node is not parent limit node, + // we must find somewhere a way to go up in nodes + throw new IllegalArgumentException(expr + " should contains at least one \"..\""); + } + + if (firstIndex != 0) { + // this is a error, the ../ must be at the beginning of the expression + throw new IllegalArgumentException("\"..\" must be at the beginning but was : " + expr); + } + + NavigationTreeNode ancestor = getParent(); + + if (firstIndex == lastIndex) { + // found only one go up, so must be substitute by the parent node context + + String newExpr = expr.substring(2); + //String newExpr = expr.substring(expr.startsWith("../") ? 3 : 2); + + if (getParent().equals(parentNode)) { + + // parent node is the final parent node, so no substitution needed + return newExpr; + //return parentNode.computeJXPath(newExpr, parentNode); + } + + // ancestor must have a jaxxContextEntryPath + if (ancestor.jaxxContextEntryPath == null) { + throw new IllegalArgumentException("with the expression " + expr + ", the ancestor node (" + ancestor + ") must have a jaxxContextEntryPath definition, but was not "); + } + + newExpr = ancestor.jaxxContextEntryPath + newExpr; + + return ancestor.computeJXPath(newExpr, parentNode); + } + + // have more than one go up, so the ancestor node can not have a jaxxContextEntryPath + if (ancestor.jaxxContextEntryPath != null) { + throw new IllegalArgumentException("with the expression " + expr + ", the ancestor node can not have a jaxxContextEntryPath definition"); + } + + // substitute the last ..[/] and delegate to ancestor + String newExpr = expr.substring(0, lastIndex - 1) + expr.substring(lastIndex + (expr.charAt(lastIndex + 3) == '/' ? 3 : 2)); + + return ancestor.computeJXPath(newExpr, parentNode); + } } @Override @@ -323,63 +476,10 @@ * @throws IllegalAccessException todo */ public Object getJAXXContextValue(JAXXContext context, NavigationTreeNode node) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { - Object result; + //Object result; if (node == null) { return null; } - if (node.getJaxxContextEntryDef() != null) { - // the node maps directly a value in context - result = node.getJaxxContextEntryDef().getContextValue(context); - return result; - } - // find the first ancestor node with a context def - NavigationTreeNode parentNode = node.getFirstAncestorWithDef(); - if (parentNode == null) { - // no parent found - return null; - } - - Object parentBean = getJAXXContextValue(context, parentNode); - if (parentBean == null) { - return null; - } - result = parentBean; - // descend from parentNode to node (says descending into parentBean following node contexts) - TreeNode[] path = node.getPath(); - PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance().getPropertyUtils(); - - int level = parentNode.getLevel() + 1; - - if (List.class.isAssignableFrom(parentBean.getClass())) { - // parent bean is a list, returnindexed node - NavigationTreeNode sonNode = (NavigationTreeNode) path[level]; - //TODO Finish it... - int index = parentNode.getIndex(sonNode); - result = ((List) parentBean).get(index); - level++; - } - - for (int i = level, length = path.length; i < length; i++) { - NavigationTreeNode treeNode = (NavigationTreeNode) path[i]; - - String propertyName = treeNode.getContext(); - Object sonBean = propertyUtils.getProperty(result, propertyName); - if (sonBean == null) { - // can be null (for example a leaf list) - result = null; - break; - } - if (!(List.class.isAssignableFrom(sonBean.getClass())) || treeNode.isLeaf() || i == length - 1) { - // simple property and last node - result = sonBean; - continue; - } - // indexed node - NavigationTreeNode sonNode = (NavigationTreeNode) path[++i]; - int index = treeNode.getIndex(sonNode); - result = propertyUtils.getIndexedProperty(result, propertyName, index); - } - return result; + return node.getJAXXContextValue(context); } - } Modified: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java 2008-11-24 15:33:01 UTC (rev 1029) +++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java 2008-11-24 15:33:42 UTC (rev 1030) @@ -28,16 +28,16 @@ @Test public void testFindNode() throws Exception { - NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); + NavigationTreeNode rootNode = new NavigationTreeNode(null, null, ROOT_CONTEXT, null, null); for (int i = 0; i < 4; i++) { - NavigationTreeNode sonNode = new NavigationTreeNode(getNodeContext(i), null, null, null); + NavigationTreeNode sonNode = new NavigationTreeNode(null, null, getNodeContext(i), null, null); rootNode.insert(sonNode, i); for (int j = 0; j < 4; j++) { - NavigationTreeNode sonSonNode = new NavigationTreeNode(getNodeContext(i, j), null, null, null); + NavigationTreeNode sonSonNode = new NavigationTreeNode(null, null, getNodeContext(i, j), null, null); sonNode.insert(sonSonNode, j); for (int k = 0; k < 4; k++) { - sonSonNode.insert(new NavigationTreeNode(getNodeContext(i, j, k), null, null, null), k); + sonSonNode.insert(new NavigationTreeNode(null, null, getNodeContext(i, j, k), null, null), k); } } } @@ -128,49 +128,50 @@ @Test public void testGetJAXXContextValue() throws Exception { - NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); + NavigationTreeNode rootNode = new NavigationTreeNode(null, null, ROOT_CONTEXT, null, null); NavigationTreeNode sonNode; NavigationTreeNode sonSonNode; NavigationTreeNode sonSonSonNode; - sonNode = new NavigationTreeNode("name", null, null, JAXXContextEntryDef.newDef("name", String.class)); + sonNode = new NavigationTreeNode(null, JAXXContextEntryDef.newDef("name", String.class), "name", null, null); rootNode.insert(sonNode, 0); - sonNode = new NavigationTreeNode("name2", null, null, JAXXContextEntryDef.newDef("name2", String.class)); + sonNode = new NavigationTreeNode(null, JAXXContextEntryDef.newDef("name2", String.class), "name2", null, null); rootNode.insert(sonNode, 1); - sonNode = new NavigationTreeNode("model", null, null, JAXXContextEntryDef.newDef(Model.class)); + sonNode = new NavigationTreeNode(null, JAXXContextEntryDef.newDef(Model.class), "model", null, null); rootNode.insert(sonNode, 2); - sonSonNode = new NavigationTreeNode("name", null, null, null); + sonSonNode = new NavigationTreeNode(null, "../name", "name", null, null); sonNode.insert(sonSonNode, 0); - sonSonNode = new NavigationTreeNode("integerValue", null, null, null); + sonSonNode = new NavigationTreeNode(null, "../integerValue", "integerValue", null, null); sonNode.insert(sonSonNode, 1); - sonSonNode = new NavigationTreeNode("sons", null, null, null); + sonSonNode = new NavigationTreeNode(null, "../sons", "sons", null, null); sonNode.insert(sonSonNode, 2); - sonSonSonNode = new NavigationTreeNode(0 + "", null, null, null); + sonSonSonNode = new NavigationTreeNode(null, "..[1]", 0 + "", null, null); sonSonNode.insert(sonSonSonNode, 0); - sonSonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - sonSonSonNode.insert(new NavigationTreeNode("integerValue", null, null, null), 1); - sonSonSonNode.insert(new NavigationTreeNode("sons", null, null, null), 2); + sonSonSonNode.insert(new NavigationTreeNode(null, "../name", "name", null, null), 0); + sonSonSonNode.insert(new NavigationTreeNode(null, "../integerValue", "integerValue", null, null), 1); + sonSonSonNode.insert(new NavigationTreeNode(null, "../sons", "sons", null, null), 2); - sonSonSonNode = new NavigationTreeNode(1 + "", null, null, null); + sonSonSonNode = new NavigationTreeNode(null, "..[2]", 1 + "", null, null); sonSonNode.insert(sonSonSonNode, 1); - sonSonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - sonSonSonNode.insert(new NavigationTreeNode("integerValue", null, null, null), 1); - sonSonSonNode.insert(new NavigationTreeNode("sons", null, null, null), 2); + sonSonSonNode.insert(new NavigationTreeNode(null, "../name", "name", null, null), 0); + sonSonSonNode.insert(new NavigationTreeNode(null, "../integerValue", "integerValue", null, null), 1); + sonSonSonNode.insert(new NavigationTreeNode(null, "../sons", "sons", null, null), 2); - sonSonSonNode = new NavigationTreeNode(2 + "", null, null, null); + sonSonSonNode = new NavigationTreeNode(null, null, 2 + "", null, null); + //sonSonSonNode = new NavigationTreeNode(null, "..[3]", 2 + "", null, null); sonSonNode.insert(sonSonSonNode, 2); - sonSonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - sonSonSonNode.insert(new NavigationTreeNode("integerValue", null, null, null), 1); - sonSonSonNode.insert(new NavigationTreeNode("sons", null, null, null), 2); + sonSonSonNode.insert(new NavigationTreeNode(null, "../..[3]/name", "name", null, null), 0); + sonSonSonNode.insert(new NavigationTreeNode(null, "../..[3]/integerValue", "integerValue", null, null), 1); + sonSonSonNode.insert(new NavigationTreeNode(null, "../..[3]/sons", "sons", null, null), 2); NavigationTreeModel model = new NavigationTreeModel(rootNode); @@ -251,39 +252,39 @@ @Test public void testGetJAXXContextValueFromList() throws Exception { - NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); + NavigationTreeNode rootNode = new NavigationTreeNode(null, null, ROOT_CONTEXT, null, null); NavigationTreeNode sonNode; NavigationTreeNode sonSonNode; NavigationTreeNode sonSonSonNode; // first son is a list of models - sonNode = new NavigationTreeNode("models", null, null, JAXXContextEntryDef.newListDef("models")); + sonNode = new NavigationTreeNode(null, JAXXContextEntryDef.newListDef("models"), "models", null, null); rootNode.insert(sonNode, 0); // first son son is a model - sonSonNode = new NavigationTreeNode("0", null, null, null); + sonSonNode = new NavigationTreeNode(null, "..[1]", "0", null, null); sonNode.insert(sonSonNode, 0); - sonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - sonSonNode.insert(new NavigationTreeNode("integerValue", null, null, null), 1); - sonSonNode.insert(sonSonSonNode = new NavigationTreeNode("sons", null, null, null), 2); + sonSonNode.insert(new NavigationTreeNode(null, "../name", "name", null, null), 0); + sonSonNode.insert(new NavigationTreeNode(null, "../integerValue", "integerValue", null, null), 1); + sonSonNode.insert(sonSonSonNode = new NavigationTreeNode(null, "../sons", "sons", null, null), 2); - sonSonSonNode.insert(sonSonSonNode = new NavigationTreeNode("0", null, null, null), 0); - sonSonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); + sonSonSonNode.insert(sonSonSonNode = new NavigationTreeNode(null, "..[1]", "0", null, null), 0); + sonSonSonNode.insert(new NavigationTreeNode(null, "../name", "name", null, null), 0); // second son son is a model - sonSonNode = new NavigationTreeNode("1", null, null, null); + sonSonNode = new NavigationTreeNode(null, "..[2]", "1", null, null); sonNode.insert(sonSonNode, 1); - sonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - sonSonNode.insert(new NavigationTreeNode("integerValue", null, null, null), 1); - sonSonNode.insert(new NavigationTreeNode("sons", null, null, null), 2); + sonSonNode.insert(new NavigationTreeNode(null, "../name", "name", null, null), 0); + sonSonNode.insert(new NavigationTreeNode(null, "../integerValue", "integerValue", null, null), 1); + sonSonNode.insert(new NavigationTreeNode(null, "../sons", "sons", null, null), 2); // third son son is a model - sonSonNode = new NavigationTreeNode("2", null, null, null); + sonSonNode = new NavigationTreeNode(null, "..[3]", "2", null, null); sonNode.insert(sonSonNode, 2); - sonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - sonSonNode.insert(new NavigationTreeNode("integerValue", null, null, null), 1); - sonSonNode.insert(new NavigationTreeNode("sons", null, null, null), 2); + sonSonNode.insert(new NavigationTreeNode(null, "../name", "name", null, null), 0); + sonSonNode.insert(new NavigationTreeNode(null, "../integerValue", "integerValue", null, null), 1); + sonSonNode.insert(new NavigationTreeNode(null, "../sons", "sons", null, null), 2); NavigationTreeModel model = new NavigationTreeModel(rootNode); Modified: lutinjaxx/trunk/pom.xml =================================================================== --- lutinjaxx/trunk/pom.xml 2008-11-24 15:33:01 UTC (rev 1029) +++ lutinjaxx/trunk/pom.xml 2008-11-24 15:33:42 UTC (rev 1030) @@ -1,4 +1,5 @@ -<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"> +<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> @@ -186,6 +187,12 @@ <version>3.0.1</version> </dependency> + <dependency> + <groupId>commons-jxpath</groupId> + <artifactId>commons-jxpath</artifactId> + <version>1.3</version> + </dependency> + </dependencies> </dependencyManagement>
participants (1)
-
chemit@users.labs.libre-entreprise.org