[Buix-commits] r1019 - in lutinjaxx/trunk/jaxx-core/src: main/java/jaxx/runtime/swing main/java/jaxx/runtime/swing/navigation site/fr/rst test/java/jaxx/runtime/swing test/java/jaxx/runtime/swing/navigation
Author: chemit Date: 2008-11-17 11:55:31 +0000 (Mon, 17 Nov 2008) New Revision: 1019 Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationtreeSelectionAdapterWithCardLayout.java lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java Removed: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeModel.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeSelectionAdapter.java lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationtreeSelectionAdapterWithCardLayout.java lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/NavigationTreeModelTest.java Modified: lutinjaxx/trunk/jaxx-core/src/site/fr/rst/NavigationTreeModel.rst Log: introduce a package navigation to put all navigation model stuff Deleted: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeModel.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeModel.java 2008-11-16 21:19:26 UTC (rev 1018) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeModel.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -1,385 +0,0 @@ -package jaxx.runtime.swing; - - -import jaxx.runtime.JAXXAction; -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 org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.tree.DefaultMutableTreeNode; -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; - -/** - * Le modele utilisé pour un arbre de navigation. - * <p/> - * Il est composé de {@link NavigationTreeModel.NavigationTreeNode} - * - * @author chemit - */ -public class NavigationTreeModel extends DefaultTreeModel { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private final Log log = LogFactory.getLog(NavigationTreeModel.class); - - private static final long serialVersionUID = 1L; - - /** la représentation d'un noeud dans le model {@link NavigationTreeModel} */ - public static class NavigationTreeNode extends DefaultMutableTreeNode { - - private static final long serialVersionUID = 1L; - - /** pour representer le context du noeud. */ - protected String context; - - /** the JAXXObject class associated with this node */ - protected Class<? extends JAXXObject> jaxxClass; - - /** the JAXXAction class associated with this node and will be put in ui context */ - protected Class<? extends JAXXAction> jaxxActionClass; - - /** 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) { - 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) { - super(userObject, allowsChildren); - this.context = context; - this.jaxxClass = jaxxClass; - this.jaxxActionClass = jaxxActionClass; - this.jaxxContextEntryDef = jaxxContextEntryDef; - } - - public String getContext() { - return context; - } - - public void setContext(String context) { - this.context = context; - } - - public Class<? extends JAXXObject> getJaxxClass() { - return jaxxClass; - } - - public void setJaxxClass(Class<? extends JAXXObject> jaxxClass) { - this.jaxxClass = jaxxClass; - } - - public Class<? extends JAXXAction> getJaxxActionClass() { - return jaxxActionClass; - } - - public void setJaxxActionClass(Class<? extends JAXXAction> jaxxActionClass) { - this.jaxxActionClass = jaxxActionClass; - } - - public JAXXContextEntryDef getJaxxContextEntryDef() { - return jaxxContextEntryDef; - } - - public void setJaxxContextEntryDef(JAXXContextEntryDef jaxxContextEntryDef) { - this.jaxxContextEntryDef = jaxxContextEntryDef; - } - - /** @return the fully context pathof the node from the root node to this. */ - public String getContextPath() { - TreeNode[] path = getPath(); - StringBuilder sb = new StringBuilder(); - for (TreeNode treeNode : path) { - NavigationTreeNode myNode = (NavigationTreeNode) treeNode; - sb.append('.').append(myNode.getContext()); - } - return sb.substring(1); - } - - @Override - public NavigationTreeNode getChildAt(int index) { - return (NavigationTreeNode) super.getChildAt(index); - } - - @Override - public NavigationTreeNode getParent() { - return (NavigationTreeNode) super.getParent(); - } - - /** - * @param context the name of the {@link #context} to be matched in the cild of this node. - * @return the child of this node with given {@link #context} value. - */ - public NavigationTreeNode getChild(String context) { - for (int i = 0, max = getChildCount(); i < max; i++) { - NavigationTreeNode son = getChildAt(i); - if (context.equals(son.getContext())) { - return son; - } - } - return null; - } - - /** - * @return the first ancestor with a none null {@link #jaxxContextEntryDef} - * or <code>null</code> if none find.. - */ - protected NavigationTreeNode getFirstAncestorWithDef() { - if (jaxxContextEntryDef != null) { - return this; - } - return getParent() == null ? null : getParent().getFirstAncestorWithDef(); - } - - protected NavigationTreeNode findNode(Stack<String> stack) { - if (log.isDebugEnabled()) { - log.debug(context + " : enter with " + stack); - } - if (stack.isEmpty()) { - return this; - } - // nextcontext to search - String currentPath = stack.pop(); - if (getContext().equals(currentPath)) { - // this node matchs - return findNode(stack); - } - // find the next matching son - NavigationTreeNode son = getChild(currentPath); - return son == null ? null : son.findNode(stack); - } - - } - - @Override - public NavigationTreeNode getRoot() { - return (NavigationTreeNode) super.getRoot(); - } - - - public NavigationTreeModel(TreeNode root) { - super(root); - } - - public NavigationTreeModel(TreeNode root, boolean asksAllowsChildren) { - super(root, asksAllowsChildren); - } - - /** - * Search from the root node a node named by his fully path (concatenation of nodes - * {@link NavigationTreeNode#context} valued separated by dot. - * <p/> - * Example : - * <p/> - * <pre>$root.child1.leaf1</pre> - * - * @param path the fully path of the searched node. - * @return the node matching the fully context from the root node, or <code>null</code> if not find. - */ - public NavigationTreeNode findNode(String path) { - return findNode(getRoot(), path, (Pattern) null); - } - - /** - * Apply first the regex pattern to obtain the searched node. - * <p/> - * Search then from the root node a node named by his fully path (concatenation of nodes - * {@link NavigationTreeNode#context} valued separated by dot. - * <p/> - * <p/> - * Example : - * <p/> - * <pre>$root.child1.leaf1</pre> - * - * @param path the fully path of the searched node. - * @param regex a optional regex to apply to path before searching - * @return the node matching the fully context from the root node, or <code>null</code> if not find. - */ - public NavigationTreeNode findNode(String path, String regex) { - return findNode(getRoot(), path, regex); - } - - /** - * Apply first the regex pattern to obtain the searched node. - * <p/> - * Search then from the root node a node named by his fully path (concatenation of nodes - * {@link NavigationTreeNode#context} valued separated by dot. - * <p/> - * Example : - * <p/> - * <pre>$root.child1.leaf1</pre> - * - * @param path the fully path of the searched node. - * @param regex a optional regex to apply to path before searching - * @return the node matching the fully context from the root node, or <code>null</code> if not find. - */ - public NavigationTreeNode findNode(String path, Pattern regex) { - return findNode(getRoot(), path, regex); - } - - - /** - * Search from a given root node a node named by his fully path (concatenation of nodes - * {@link NavigationTreeNode#context} valued separated by dot. - * - * @param root root node to be used - * @param path the fully path of the searched node. - * @return the node matching the fully context from the given root node, or <code>null</code> if not find. - */ - public NavigationTreeNode findNode(NavigationTreeNode root, String path) { - return findNode(root, path, (Pattern) null); - } - - /** - * Apply first the regex pattern to obtain the searched node. - * <p/> - * Search then from a given root node a node named by his fully path (concatenation of nodes - * {@link NavigationTreeNode#context} valued separated by dot. - * - * @param root root node to be used - * @param path the fully path of the searched node. - * @param regex a previous regex to apply to path : must have a matches - * @return the node matching the fully context from the given root node, or <code>null</code> if not find. - */ - public NavigationTreeNode findNode(NavigationTreeNode root, String path, String regex) { - return findNode(root, path, regex == null ? null : Pattern.compile(regex)); - } - - /** - * Apply first the regex pattern to obtain the searched node. - * <p/> - * Search then from a given root node a node named by his fully path (concatenation of nodes - * {@link NavigationTreeNode#context} valued separated by dot. - * - * @param root root node to be used - * @param path the fully path of the searched node. - * @param regex a previous regex to apply to path : must have a matches - * @return the node matching the fully context from the given root node, or <code>null</code> if not find. - */ - public NavigationTreeNode findNode(NavigationTreeNode root, String path, Pattern regex) { - if (regex != null) { - Matcher matcher = regex.matcher(path); - if (!matcher.matches() || matcher.groupCount() < 1) { - log.warn("no matching regex " + regex + " to " + path); - return null; - } - path = matcher.group(1); - log.info("matching regex " + regex + " : " + path); - } - String[] paths = path.split("\\."); - Stack<String> stack = new Stack<String>(); - for (int i = paths.length - 1; i > -1; i--) { - stack.push(paths[i]); - } - return root.findNode(stack); - } - - - /** - * Obtain the associated bean value from context corresponding to node from given contextPath. - * - * @param context the context to seek - * @param contextPath the current context path of the node - * @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, String contextPath) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { - Object result; - NavigationTreeNode node = findNode(contextPath, (Pattern) null); - result = getJAXXContextValue(context, node); - return result; - } - - /** - * Obtain the associated bean value from context corresponding to node - * - * @param context the context to seek - * @param node the current node - * @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, NavigationTreeNode node) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { - 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; - } - -} Deleted: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeSelectionAdapter.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeSelectionAdapter.java 2008-11-16 21:19:26 UTC (rev 1018) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeSelectionAdapter.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -1,181 +0,0 @@ -package jaxx.runtime.swing; - -import jaxx.runtime.JAXXObject; -import jaxx.runtime.JAXXAction; -import jaxx.runtime.swing.NavigationTreeModel.NavigationTreeNode; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.JTree; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.TreePath; -import java.awt.Component; -import java.lang.reflect.InvocationTargetException; - -/** A {@link javax.swing.event.TreeSelectionListener} implementation@author chemit */ -public abstract class NavigationTreeSelectionAdapter implements TreeSelectionListener { - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private final Log log = LogFactory.getLog(NavigationTreeSelectionAdapter.class); - - static public final String NAVIGATION_CONTEXT_PATH = "navigation-context-path"; - - /** la classe d'ui par defaut, associé à un noeud de l'arbe */ - protected Class<? extends JAXXObject> defaultUIClass; - - protected Class<? extends JAXXAction> defaultUIHandlerClass; - - /** l'ui contenant l'arbre de navigation */ - protected JAXXObject context; - - protected NavigationTreeSelectionAdapter(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context) { - this.defaultUIClass = defaultUIClass; - this.defaultUIHandlerClass = defaultUIHandlerClass; - this.context = context; - } - - protected abstract NavigationTreeModel getNavigationTreeModel(); - - /** - * @return le composent actuellement visible associé au noeud courant ou au noeud précédent - * lors d'un changement de noeud. - */ - protected abstract Component getCurrentUI(); - - /** - * @param path le chemin du noeud selectionne dont on veut afficher l'ui associée - * @return l'ui associé au novueau noeud sélectionné - */ - protected abstract Component getNewUI(String path); - - /** - * @param event l'evenement de selection de noeud - * @param component le composent actuellement visible - * @return <code>true</code> si le composent a bien été fermé, <code>false</code> sinon - * @throws Exception if any - */ - protected abstract boolean closeUI(TreeSelectionEvent event, Component component) throws Exception; - - /** - * Instancie une nouvelle ui associé à un noeud de l'arbre de navigation - * - * @param node le noeud associé à l'ui à créer - * @return la nouvelle ui associée au noeud - * @throws Exception if any - */ - protected abstract Component createUI(NavigationTreeNode node) throws Exception; - - /** - * Ouvre l'ui associée au noeud sélectionné dans l'arbre de navigation. - * - * @param newUI l'ui associé au noeud sélectionné à ouvrir - * @param path le path dans le context de navigation - * @throws Exception if any - */ - protected abstract void openUI(Component newUI, NavigationTreeNode path) throws Exception; - - /** - * Retourne au noeud précdemment sélectionné dans l'arbre de navigation, avec la possibilité de notifier - * une erreure survenue. - * - * @param event l'évènement de changement de noeud sélectionné. - * @param e l'erreur recontrée (ou null si pas d"erreur) - */ - protected abstract void goBackToPreviousNode(TreeSelectionEvent event, Exception e); - - public void valueChanged(TreeSelectionEvent event) { - if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) { - // do not treate this if no path changed - return; - } - - try { - - NavigationTreeNode node = (NavigationTreeNode) event.getPath().getLastPathComponent(); - - if (node.getJaxxClass() == null) { - // no ui is associated with this node, display a empty content - node.setJaxxClass(defaultUIClass); - } - - if (node.getJaxxActionClass()==null) { - node.setJaxxActionClass(defaultUIHandlerClass); - } - - String path = node.getContextPath(); - - if (log.isDebugEnabled()) { - log.debug(path); - } - - Component newUI = getNewUI(path); - Component component = getCurrentUI(); - - if (newUI != null && newUI.equals(component)) { - // call back from goto back to previous node, do nothing - return; - } - - - if (!closeUI(event, component)) { - // previous ui was not closed, so reselect the previous node in navigation - goBackToPreviousNode(event, null); - // and quit - return; - } - - // now, we are free to open the ui associated with the selected node in navigation - - // before all, attach bean in context associated with the selected node in naivgation tree - attachBeanFromNodeToContext(node); - - - if (newUI == null) { - // instanciate a new ui associated with the selected node - newUI = createUI(node); - - } - - // save in context current node context path - context.setContextValue(node.getContextPath(), NAVIGATION_CONTEXT_PATH); - - // really open the ui associated with the selected node - openUI(newUI, node); - - } catch (Exception e) { - // if any error, go back to previvous node - goBackToPreviousNode(event, e); - } - - } - - protected void attachBeanFromNodeToContext(NavigationTreeNode node) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { - - String path = node.getContextPath(); - - NavigationTreeModel navigationModel = getNavigationTreeModel(); - - //if (navigationModel != null) { - - Object data = navigationModel.getJAXXContextValue(context, path); - if (data != null) { - if (log.isInfoEnabled()) { - log.info("find data for contextPath <" + path + "> : " + data.getClass()); - } - context.setContextValue(data); - } - //} - } - - protected void returnToPreviousNode(JTree tree, TreeSelectionEvent event) { - // go back to previous node - // put in context a tag to not come back again here - TreePath oldPath = event.getOldLeadSelectionPath(); - //NavigationTreeNode oldNode = (NavigationTreeNode) oldPath.getLastPathComponent(); - if (oldPath != null) { - tree.setSelectionPath(oldPath); - } - } - -} \ No newline at end of file Deleted: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationtreeSelectionAdapterWithCardLayout.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationtreeSelectionAdapterWithCardLayout.java 2008-11-16 21:19:26 UTC (rev 1018) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationtreeSelectionAdapterWithCardLayout.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -1,105 +0,0 @@ -package jaxx.runtime.swing; - -import jaxx.runtime.JAXXAction; -import jaxx.runtime.JAXXContext; -import jaxx.runtime.JAXXInitialContext; -import jaxx.runtime.JAXXObject; -import jaxx.runtime.swing.NavigationTreeModel.NavigationTreeNode; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.JPanel; -import javax.swing.event.TreeSelectionEvent; -import java.awt.Component; - -/** - * Simple {@link NavigationTreeSelectionAdapter} implementation with a {@link CardLayout2} to manage components to - * associated with tree's nodes. - * <p/> - * For each node, the ui associated has a constraints in a cardlayout which is the node context path. - * <p/> - * A single container managed by the cardlayout is used to display the components associated with tree's nodes. - * - * @author chemit - */ -public abstract class NavigationtreeSelectionAdapterWithCardLayout extends NavigationTreeSelectionAdapter { - - - /** to use log facility, just put in your code: log.info(\"...\"); */ - static private final Log log = LogFactory.getLog(NavigationtreeSelectionAdapterWithCardLayout.class); - - /** - * All components associated with a tree's node is displayed in a single container. - * - * @return the containter of components - */ - protected abstract JPanel getContentContainer(); - - /** - * the cardlayout managing components associated with tree node. The constraints - * of each component is the node contextPath. - * - * @return the layout used to display components associated with tree's nodes. - */ - protected abstract CardLayout2 getContentLayout(); - - public NavigationtreeSelectionAdapterWithCardLayout(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context) { - super(defaultUIClass, defaultUIHandlerClass, context); - - if (getContentContainer() == null) { - throw new IllegalArgumentException("could not have a null 'contentContainer' in ui " + context); - } - if (getContentLayout() == null) { - throw new IllegalArgumentException("could not have a null 'contentLayout' in ui " + context); - } - } - - protected Component getCurrentUI() { - CardLayout2 layout = getContentLayout(); - JPanel container = getContentContainer(); - return layout.getVisibleComponent(container); - } - - protected Component getNewUI(String path) { - CardLayout2 layout = getContentLayout(); - JPanel container = getContentContainer(); - return layout.contains(path) ? layout.getComponent(container, path) : null; - } - - protected void openUI(Component newUI, NavigationTreeNode node) throws Exception { - CardLayout2 layout = getContentLayout(); - JPanel container = getContentContainer(); - // switch layout - layout.show(container, node.getContextPath()); - } - - protected boolean closeUI(TreeSelectionEvent event, Component component) throws Exception { - // by default, we says that component was succesfull closed - return true; - } - - protected Component createUI(NavigationTreeNode node) throws Exception { - JAXXObject newUI; - - if (node.getJaxxActionClass() != null) { - JAXXAction action = node.getJaxxActionClass().newInstance(); - // init context with - JAXXInitialContext context = action.init(this.context); - // must instanciate the ui with an JAXXInitialContext - newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(context); - } else { - if (log.isWarnEnabled()) { - log.warn("no action associated with ui " + node.getJaxxClass()); - } - // no action associated, just - newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(this.context); - } - if (log.isDebugEnabled()) { - log.debug("instanciate new ui " + newUI); - } - - getContentContainer().add((Component) newUI, node.getContextPath()); - return (Component) newUI; - } -} - Copied: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java (from rev 1018, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeModel.java) =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -0,0 +1,385 @@ +package jaxx.runtime.swing.navigation; + + +import jaxx.runtime.JAXXAction; +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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.tree.DefaultMutableTreeNode; +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; + +/** + * Le modele utilisé pour un arbre de navigation. + * <p/> + * Il est composé de {@link NavigationTreeModel.NavigationTreeNode} + * + * @author chemit + */ +public class NavigationTreeModel extends DefaultTreeModel { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationTreeModel.class); + + private static final long serialVersionUID = 1L; + + /** la représentation d'un noeud dans le model {@link NavigationTreeModel} */ + public static class NavigationTreeNode extends DefaultMutableTreeNode { + + private static final long serialVersionUID = 1L; + + /** pour representer le context du noeud. */ + protected String context; + + /** the JAXXObject class associated with this node */ + protected Class<? extends JAXXObject> jaxxClass; + + /** the JAXXAction class associated with this node and will be put in ui context */ + protected Class<? extends JAXXAction> jaxxActionClass; + + /** 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) { + 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) { + super(userObject, allowsChildren); + this.context = context; + this.jaxxClass = jaxxClass; + this.jaxxActionClass = jaxxActionClass; + this.jaxxContextEntryDef = jaxxContextEntryDef; + } + + public String getContext() { + return context; + } + + public void setContext(String context) { + this.context = context; + } + + public Class<? extends JAXXObject> getJaxxClass() { + return jaxxClass; + } + + public void setJaxxClass(Class<? extends JAXXObject> jaxxClass) { + this.jaxxClass = jaxxClass; + } + + public Class<? extends JAXXAction> getJaxxActionClass() { + return jaxxActionClass; + } + + public void setJaxxActionClass(Class<? extends JAXXAction> jaxxActionClass) { + this.jaxxActionClass = jaxxActionClass; + } + + public JAXXContextEntryDef getJaxxContextEntryDef() { + return jaxxContextEntryDef; + } + + public void setJaxxContextEntryDef(JAXXContextEntryDef jaxxContextEntryDef) { + this.jaxxContextEntryDef = jaxxContextEntryDef; + } + + /** @return the fully context pathof the node from the root node to this. */ + public String getContextPath() { + TreeNode[] path = getPath(); + StringBuilder sb = new StringBuilder(); + for (TreeNode treeNode : path) { + NavigationTreeNode myNode = (NavigationTreeNode) treeNode; + sb.append('.').append(myNode.getContext()); + } + return sb.substring(1); + } + + @Override + public NavigationTreeNode getChildAt(int index) { + return (NavigationTreeNode) super.getChildAt(index); + } + + @Override + public NavigationTreeNode getParent() { + return (NavigationTreeNode) super.getParent(); + } + + /** + * @param context the name of the {@link #context} to be matched in the cild of this node. + * @return the child of this node with given {@link #context} value. + */ + public NavigationTreeNode getChild(String context) { + for (int i = 0, max = getChildCount(); i < max; i++) { + NavigationTreeNode son = getChildAt(i); + if (context.equals(son.getContext())) { + return son; + } + } + return null; + } + + /** + * @return the first ancestor with a none null {@link #jaxxContextEntryDef} + * or <code>null</code> if none find.. + */ + protected NavigationTreeNode getFirstAncestorWithDef() { + if (jaxxContextEntryDef != null) { + return this; + } + return getParent() == null ? null : getParent().getFirstAncestorWithDef(); + } + + protected NavigationTreeNode findNode(Stack<String> stack) { + if (log.isDebugEnabled()) { + log.debug(context + " : enter with " + stack); + } + if (stack.isEmpty()) { + return this; + } + // nextcontext to search + String currentPath = stack.pop(); + if (getContext().equals(currentPath)) { + // this node matchs + return findNode(stack); + } + // find the next matching son + NavigationTreeNode son = getChild(currentPath); + return son == null ? null : son.findNode(stack); + } + + } + + @Override + public NavigationTreeNode getRoot() { + return (NavigationTreeNode) super.getRoot(); + } + + + public NavigationTreeModel(TreeNode root) { + super(root); + } + + public NavigationTreeModel(TreeNode root, boolean asksAllowsChildren) { + super(root, asksAllowsChildren); + } + + /** + * Search from the root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#context} valued separated by dot. + * <p/> + * Example : + * <p/> + * <pre>$root.child1.leaf1</pre> + * + * @param path the fully path of the searched node. + * @return the node matching the fully context from the root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(String path) { + return findNode(getRoot(), path, (Pattern) null); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from the root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#context} valued separated by dot. + * <p/> + * <p/> + * Example : + * <p/> + * <pre>$root.child1.leaf1</pre> + * + * @param path the fully path of the searched node. + * @param regex a optional regex to apply to path before searching + * @return the node matching the fully context from the root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(String path, String regex) { + return findNode(getRoot(), path, regex); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from the root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#context} valued separated by dot. + * <p/> + * Example : + * <p/> + * <pre>$root.child1.leaf1</pre> + * + * @param path the fully path of the searched node. + * @param regex a optional regex to apply to path before searching + * @return the node matching the fully context from the root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(String path, Pattern regex) { + return findNode(getRoot(), path, regex); + } + + + /** + * Search from a given root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#context} valued separated by dot. + * + * @param root root node to be used + * @param path the fully path of the searched node. + * @return the node matching the fully context from the given root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(NavigationTreeNode root, String path) { + return findNode(root, path, (Pattern) null); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from a given root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#context} valued separated by dot. + * + * @param root root node to be used + * @param path the fully path of the searched node. + * @param regex a previous regex to apply to path : must have a matches + * @return the node matching the fully context from the given root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(NavigationTreeNode root, String path, String regex) { + return findNode(root, path, regex == null ? null : Pattern.compile(regex)); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from a given root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#context} valued separated by dot. + * + * @param root root node to be used + * @param path the fully path of the searched node. + * @param regex a previous regex to apply to path : must have a matches + * @return the node matching the fully context from the given root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(NavigationTreeNode root, String path, Pattern regex) { + if (regex != null) { + Matcher matcher = regex.matcher(path); + if (!matcher.matches() || matcher.groupCount() < 1) { + log.warn("no matching regex " + regex + " to " + path); + return null; + } + path = matcher.group(1); + log.info("matching regex " + regex + " : " + path); + } + String[] paths = path.split("\\."); + Stack<String> stack = new Stack<String>(); + for (int i = paths.length - 1; i > -1; i--) { + stack.push(paths[i]); + } + return root.findNode(stack); + } + + + /** + * Obtain the associated bean value from context corresponding to node from given contextPath. + * + * @param context the context to seek + * @param contextPath the current context path of the node + * @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, String contextPath) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + Object result; + NavigationTreeNode node = findNode(contextPath, (Pattern) null); + result = getJAXXContextValue(context, node); + return result; + } + + /** + * Obtain the associated bean value from context corresponding to node + * + * @param context the context to seek + * @param node the current node + * @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, NavigationTreeNode node) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + 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; + } + +} Copied: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java (from rev 1017, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationTreeSelectionAdapter.java) =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -0,0 +1,181 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXAction; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreePath; +import java.awt.Component; +import java.lang.reflect.InvocationTargetException; + +/** A {@link javax.swing.event.TreeSelectionListener} implementation@author chemit */ +public abstract class NavigationTreeSelectionAdapter implements TreeSelectionListener { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationTreeSelectionAdapter.class); + + static public final String NAVIGATION_CONTEXT_PATH = "navigation-context-path"; + + /** la classe d'ui par defaut, associé à un noeud de l'arbe */ + protected Class<? extends JAXXObject> defaultUIClass; + + protected Class<? extends JAXXAction> defaultUIHandlerClass; + + /** l'ui contenant l'arbre de navigation */ + protected JAXXObject context; + + protected NavigationTreeSelectionAdapter(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context) { + this.defaultUIClass = defaultUIClass; + this.defaultUIHandlerClass = defaultUIHandlerClass; + this.context = context; + } + + protected abstract NavigationTreeModel getNavigationTreeModel(); + + /** + * @return le composent actuellement visible associé au noeud courant ou au noeud précédent + * lors d'un changement de noeud. + */ + protected abstract Component getCurrentUI(); + + /** + * @param path le chemin du noeud selectionne dont on veut afficher l'ui associée + * @return l'ui associé au novueau noeud sélectionné + */ + protected abstract Component getNewUI(String path); + + /** + * @param event l'evenement de selection de noeud + * @param component le composent actuellement visible + * @return <code>true</code> si le composent a bien été fermé, <code>false</code> sinon + * @throws Exception if any + */ + protected abstract boolean closeUI(TreeSelectionEvent event, Component component) throws Exception; + + /** + * Instancie une nouvelle ui associé à un noeud de l'arbre de navigation + * + * @param node le noeud associé à l'ui à créer + * @return la nouvelle ui associée au noeud + * @throws Exception if any + */ + protected abstract Component createUI(NavigationTreeNode node) throws Exception; + + /** + * Ouvre l'ui associée au noeud sélectionné dans l'arbre de navigation. + * + * @param newUI l'ui associé au noeud sélectionné à ouvrir + * @param path le path dans le context de navigation + * @throws Exception if any + */ + protected abstract void openUI(Component newUI, NavigationTreeNode path) throws Exception; + + /** + * Retourne au noeud précdemment sélectionné dans l'arbre de navigation, avec la possibilité de notifier + * une erreure survenue. + * + * @param event l'évènement de changement de noeud sélectionné. + * @param e l'erreur recontrée (ou null si pas d"erreur) + */ + protected abstract void goBackToPreviousNode(TreeSelectionEvent event, Exception e); + + public void valueChanged(TreeSelectionEvent event) { + if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) { + // do not treate this if no path changed + return; + } + + try { + + NavigationTreeNode node = (NavigationTreeNode) event.getPath().getLastPathComponent(); + + if (node.getJaxxClass() == null) { + // no ui is associated with this node, display a empty content + node.setJaxxClass(defaultUIClass); + } + + if (node.getJaxxActionClass()==null) { + node.setJaxxActionClass(defaultUIHandlerClass); + } + + String path = node.getContextPath(); + + if (log.isDebugEnabled()) { + log.debug(path); + } + + Component newUI = getNewUI(path); + Component component = getCurrentUI(); + + if (newUI != null && newUI.equals(component)) { + // call back from goto back to previous node, do nothing + return; + } + + + if (!closeUI(event, component)) { + // previous ui was not closed, so reselect the previous node in navigation + goBackToPreviousNode(event, null); + // and quit + return; + } + + // now, we are free to open the ui associated with the selected node in navigation + + // before all, attach bean in context associated with the selected node in naivgation tree + attachBeanFromNodeToContext(node); + + + if (newUI == null) { + // instanciate a new ui associated with the selected node + newUI = createUI(node); + + } + + // save in context current node context path + context.setContextValue(node.getContextPath(), NAVIGATION_CONTEXT_PATH); + + // really open the ui associated with the selected node + openUI(newUI, node); + + } catch (Exception e) { + // if any error, go back to previvous node + goBackToPreviousNode(event, e); + } + + } + + protected void attachBeanFromNodeToContext(NavigationTreeNode node) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + + String path = node.getContextPath(); + + NavigationTreeModel navigationModel = getNavigationTreeModel(); + + //if (navigationModel != null) { + + Object data = navigationModel.getJAXXContextValue(context, path); + if (data != null) { + if (log.isInfoEnabled()) { + log.info("find data for contextPath <" + path + "> : " + data.getClass()); + } + context.setContextValue(data); + } + //} + } + + protected void returnToPreviousNode(JTree tree, TreeSelectionEvent event) { + // go back to previous node + // put in context a tag to not come back again here + TreePath oldPath = event.getOldLeadSelectionPath(); + //NavigationTreeNode oldNode = (NavigationTreeNode) oldPath.getLastPathComponent(); + if (oldPath != null) { + tree.setSelectionPath(oldPath); + } + } + +} \ No newline at end of file Copied: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationtreeSelectionAdapterWithCardLayout.java (from rev 1017, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/NavigationtreeSelectionAdapterWithCardLayout.java) =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationtreeSelectionAdapterWithCardLayout.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationtreeSelectionAdapterWithCardLayout.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -0,0 +1,106 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXInitialContext; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import jaxx.runtime.swing.CardLayout2; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JPanel; +import javax.swing.event.TreeSelectionEvent; +import java.awt.Component; + +/** + * Simple {@link NavigationTreeSelectionAdapter} implementation with a {@link jaxx.runtime.swing.CardLayout2} to manage components to + * associated with tree's nodes. + * <p/> + * For each node, the ui associated has a constraints in a cardlayout which is the node context path. + * <p/> + * A single container managed by the cardlayout is used to display the components associated with tree's nodes. + * + * @author chemit + */ +public abstract class NavigationtreeSelectionAdapterWithCardLayout extends NavigationTreeSelectionAdapter { + + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationtreeSelectionAdapterWithCardLayout.class); + + /** + * All components associated with a tree's node is displayed in a single container. + * + * @return the containter of components + */ + protected abstract JPanel getContentContainer(); + + /** + * the cardlayout managing components associated with tree node. The constraints + * of each component is the node contextPath. + * + * @return the layout used to display components associated with tree's nodes. + */ + protected abstract CardLayout2 getContentLayout(); + + public NavigationtreeSelectionAdapterWithCardLayout(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context) { + super(defaultUIClass, defaultUIHandlerClass, context); + + if (getContentContainer() == null) { + throw new IllegalArgumentException("could not have a null 'contentContainer' in ui " + context); + } + if (getContentLayout() == null) { + throw new IllegalArgumentException("could not have a null 'contentLayout' in ui " + context); + } + } + + protected Component getCurrentUI() { + CardLayout2 layout = getContentLayout(); + JPanel container = getContentContainer(); + return layout.getVisibleComponent(container); + } + + protected Component getNewUI(String path) { + CardLayout2 layout = getContentLayout(); + JPanel container = getContentContainer(); + return layout.contains(path) ? layout.getComponent(container, path) : null; + } + + protected void openUI(Component newUI, NavigationTreeNode node) throws Exception { + CardLayout2 layout = getContentLayout(); + JPanel container = getContentContainer(); + // switch layout + layout.show(container, node.getContextPath()); + } + + protected boolean closeUI(TreeSelectionEvent event, Component component) throws Exception { + // by default, we says that component was succesfull closed + return true; + } + + protected Component createUI(NavigationTreeNode node) throws Exception { + JAXXObject newUI; + + if (node.getJaxxActionClass() != null) { + JAXXAction action = node.getJaxxActionClass().newInstance(); + // init context with + JAXXInitialContext context = action.init(this.context); + // must instanciate the ui with an JAXXInitialContext + newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(context); + } else { + if (log.isWarnEnabled()) { + log.warn("no action associated with ui " + node.getJaxxClass()); + } + // no action associated, just + newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(this.context); + } + if (log.isDebugEnabled()) { + log.debug("instanciate new ui " + newUI); + } + + getContentContainer().add((Component) newUI, node.getContextPath()); + return (Component) newUI; + } +} + Modified: lutinjaxx/trunk/jaxx-core/src/site/fr/rst/NavigationTreeModel.rst =================================================================== --- lutinjaxx/trunk/jaxx-core/src/site/fr/rst/NavigationTreeModel.rst 2008-11-16 21:19:26 UTC (rev 1018) +++ lutinjaxx/trunk/jaxx-core/src/site/fr/rst/NavigationTreeModel.rst 2008-11-17 11:55:31 UTC (rev 1019) @@ -13,14 +13,14 @@ Le but de cette fonctionnalité est de pouvoir créer un arbre de navigation lié au context de JAXX, de définir des UI rattachés à chaque noeud. -Le développement est effectué dans le paquetage *jaxx.runtime.swing*. +Le développement est effectué dans le paquetage *jaxx.runtime.swing.navigation*. -jaxx.runtime.swing.NavigationTreeModel +jaxx.runtime.swing.navigation.NavigationTreeModel ====================================== Il s'agit du modèle de l'arbre utilisé, c'est une extension d'un *javax.swing.tree.DefaultTreeModel*. -Les noeuds présents dans ce modèle sont aussi typés en *jaxx.runtime.swing.NavigationTreeModel.NavigationTreeNode*. +Les noeuds présents dans ce modèle sont aussi typés en *jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode*. L'idée principale est de pouvoir associé à un noeud précis un chemin depuis la racine, ce que l'on appele *chemin de navigation*. @@ -29,7 +29,7 @@ Définition d'un noeud ===================== -Le noeud (*jaxx.runtime.swing.NavigationTreeModel.NavigationTreeNode*) est une extension d'un *javax.swing.tree.DefaultMutableTreeNode*. +Le noeud (*jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode*) est une extension d'un *javax.swing.tree.DefaultMutableTreeNode*. Il apporte les nouvelles propriétés suivantes : @@ -121,7 +121,7 @@ model.getJAXXContextValue(context, myNode); -jaxx.runtime.swing.NavigationTreeSelectionAdapter +jaxx.runtime.swing.navigation.NavigationTreeSelectionAdapter ================================================= Il s'agit d'un listener sur la sélection d'un noeud dans l'arbre de navigation basé sur notre modèle de navigation. Il @@ -146,7 +146,7 @@ Si une erreur survient lors de ces opérations, on entre dans la méthode *goBackToPreviousNode* qui est abstraite et permet de notifier les erreur de retourner au noeud précdent. -jaxx.runtime.swing.NavigationtreeSelectionAdapterWithCardLayout +jaxx.runtime.swing.navigation.NavigationtreeSelectionAdapterWithCardLayout *************************************************************** Il s'agit d'une implantation du listener précédent qui suppose que les uis associées aux noeuds sont affichées dans un Deleted: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/NavigationTreeModelTest.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/NavigationTreeModelTest.java 2008-11-16 21:19:26 UTC (rev 1018) +++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/NavigationTreeModelTest.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -1,398 +0,0 @@ -package jaxx.runtime.swing; - -import jaxx.runtime.DefaultJAXXContext; -import jaxx.runtime.JAXXContext; -import jaxx.runtime.JAXXContextEntryDef; -import jaxx.runtime.swing.NavigationTreeModel.NavigationTreeNode; -import org.junit.Assert; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - - -/** - * Test du model de navigation. - * - * @author chemit - */ -public class NavigationTreeModelTest { - - - private static final String ROOT_CONTEXT = "$root"; - private static final String FAKE = "-fake"; - private static final String DOT = "."; - - @Test - public void testFindNode() throws Exception { - - NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); - - for (int i = 0; i < 4; i++) { - NavigationTreeNode sonNode = new NavigationTreeNode(getNodeContext(i), null, null, null); - rootNode.insert(sonNode, i); - for (int j = 0; j < 4; j++) { - NavigationTreeNode sonSonNode = new NavigationTreeNode(getNodeContext(i, j), null, 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); - } - } - } - - NavigationTreeModel model = new NavigationTreeModel(rootNode); - - NavigationTreeNode node; - String contextPath; - String currentNode; - - contextPath = ROOT_CONTEXT; - node = model.findNode(contextPath); - assertNodeEquals(contextPath, ROOT_CONTEXT, 0, node, true); - - node = model.findNode(ROOT_CONTEXT + FAKE); - Assert.assertNull(node); - - for (int i = 0; i < 4; i++) { - currentNode = getNodeContext(i); - contextPath = ROOT_CONTEXT + DOT + currentNode; - node = model.findNode(contextPath); - assertNodeEquals(contextPath, currentNode, 1, node, false); - - for (int j = 0; j < 4; j++) { - currentNode = getNodeContext(i, j); - contextPath = ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + currentNode; - node = model.findNode(contextPath); - assertNodeEquals(contextPath, currentNode, 2, node, false); - - for (int k = 0; k < 4; k++) { - currentNode = getNodeContext(i, j, k); - contextPath = ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + getNodeContext(i, j) + DOT + currentNode; - node = model.findNode(contextPath); - assertNodeEquals(contextPath, currentNode, 3, node, false); - } - - node = model.findNode(ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + getNodeContext(i, j) + DOT + currentNode + FAKE); - Assert.assertNull(node); - } - - node = model.findNode(ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + currentNode + FAKE); - Assert.assertNull(node); - - } - - } - - /** - * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point - * as a bean. - * <p/> - * Tree is like this - * <pre> - * $root + - * - name <-- attached to context entry : java.lang.String.class,"name" - * - name2 <-- attached to context entry : java.lang.String.class,"name2" - * - model + <-- attached to context entry : Model.class,null - * - name - * -integerValue - * - sons + - * - 0 + - * - name - * - integerValue - * - sons - * - 1 + - * - name - * - integerValue - * - sons - * - 2 + - * - name - * - integerValue - * - sons - * </pre> - * <p/> - * With this tree, we will have to results : - * <pre> - * $root.name => context.get(String.class,"name") - * $root.name2 => context.get(String.class,"name2") - * $root.model => context.get(Model.class) - * $root.model.name => context.get(Model.class).getName() - * $root.model.integerValue => context.get(Model.class).getIntegerValue() - * $root.model.sons => context.get(Model.class).getSons() - * $root.model.sons.0 => context.get(Model.class).getSons().get(0) - * </pre> - * - * @throws Exception if any pb - */ - @Test - public void testGetJAXXContextValue() throws Exception { - - NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); - NavigationTreeNode sonNode; - NavigationTreeNode sonSonNode; - NavigationTreeNode sonSonSonNode; - - sonNode = new NavigationTreeNode("name", null, null, JAXXContextEntryDef.newDef("name", String.class)); - - rootNode.insert(sonNode, 0); - - sonNode = new NavigationTreeNode("name2", null, null, JAXXContextEntryDef.newDef("name2", String.class)); - - rootNode.insert(sonNode, 1); - - sonNode = new NavigationTreeNode("model", null, null, JAXXContextEntryDef.newDef(Model.class)); - - rootNode.insert(sonNode, 2); - - sonSonNode = new NavigationTreeNode("name", null, null, null); - sonNode.insert(sonSonNode, 0); - - sonSonNode = new NavigationTreeNode("integerValue", null, null, null); - sonNode.insert(sonSonNode, 1); - - sonSonNode = new NavigationTreeNode("sons", null, null, null); - sonNode.insert(sonSonNode, 2); - - sonSonSonNode = new NavigationTreeNode(0 + "", null, 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 = new NavigationTreeNode(1 + "", null, 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 = new NavigationTreeNode(2 + "", null, 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); - - NavigationTreeModel model = new NavigationTreeModel(rootNode); - - JAXXContext context = new DefaultJAXXContext(); - context.setContextValue("the name", "name"); - context.setContextValue("the name2", "name2"); - - - context.setContextValue( - new Model("modelName", 10, - Arrays.asList( - new Model("one", 1, Collections.<Model>emptyList()), - new Model("two", 2, Collections.<Model>emptyList()), - new Model("three", 3, Collections.<Model>emptyList()) - ) - ) - ); - - Assert.assertNull(model.getJAXXContextValue(context, "$root.name" + FAKE)); - - testBinding(model, context, "$root.name", context.getContextValue(String.class, "name")); - testBinding(model, context, "$root.name2", context.getContextValue(String.class, "name2")); - - Model bean = context.getContextValue(Model.class); - - testBinding(model, context, "$root.model", bean); - testBinding(model, context, "$root.model.name", bean.getName()); - testBinding(model, context, "$root.model.integerValue", bean.getIntegerValue()); - testBinding(model, context, "$root.model.sons", bean.getSons()); - - testBinding(model, context, "$root.model.sons.0.name", bean.getSons().get(0).getName()); - testBinding(model, context, "$root.model.sons.0.integerValue", bean.getSons().get(0).getIntegerValue()); - testBinding(model, context, "$root.model.sons.0.sons", bean.getSons().get(0).getSons()); - - - testBinding(model, context, "$root.model.sons.1.name", bean.getSons().get(1).getName()); - testBinding(model, context, "$root.model.sons.1.integerValue", bean.getSons().get(1).getIntegerValue()); - testBinding(model, context, "$root.model.sons.1.sons", bean.getSons().get(1).getSons()); - - testBinding(model, context, "$root.model.sons.2.name", bean.getSons().get(2).getName()); - testBinding(model, context, "$root.model.sons.2.integerValue", bean.getSons().get(2).getIntegerValue()); - testBinding(model, context, "$root.model.sons.2.sons", bean.getSons().get(2).getSons()); - } - - /** - * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point - * as a list. - * <p/> - * Tree is like this - * <pre> - * $root + - * - models + <-- attached to context entry : java.util.List.class,"models" - * - 0 + - * - name - * -integerValue - * - sons + - * - 0 + - * - name - * - 1 + - * - name - * - integerValue - * - sons - * - 2 + - * - name - * - integerValue - * - sons - * </pre> - * <p/> - * With this tree, we will have to results : - * <pre> - * $root.models => context.get(List.class,"models") - * $root.models.0 => context.get(List.class,"models").get(0) - * $root.models.0.name => context.get(List.class,"models").get(0).getName() - * </pre> - * - * @throws Exception if any pb - */ - @Test - public void testGetJAXXContextValueFromList() throws Exception { - - NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); - NavigationTreeNode sonNode; - NavigationTreeNode sonSonNode; - NavigationTreeNode sonSonSonNode; - - // first son is a list of models - sonNode = new NavigationTreeNode("models", null, null, JAXXContextEntryDef.newListDef("models")); - rootNode.insert(sonNode, 0); - - // first son son is a model - sonSonNode = new NavigationTreeNode("0", null, 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); - - sonSonSonNode.insert(sonSonSonNode = new NavigationTreeNode("0", null, null, null), 0); - sonSonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); - - // second son son is a model - sonSonNode = new NavigationTreeNode("1", null, 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); - - // third son son is a model - sonSonNode = new NavigationTreeNode("2", null, 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); - - NavigationTreeModel model = new NavigationTreeModel(rootNode); - - JAXXContext context = new DefaultJAXXContext(); - List<Model> list = new ArrayList<Model>(); - list.add(new Model("entryOne", 10, - Arrays.asList( - new Model("one", 1, Collections.<Model>emptyList()), - new Model("two", 2, Collections.<Model>emptyList()), - new Model("three", 3, Collections.<Model>emptyList()) - ) - )); - list.add(new Model("entryTwo", 20, - Arrays.asList( - new Model("2one", 1, Collections.<Model>emptyList()), - new Model("2two", 2, Collections.<Model>emptyList()), - new Model("2three", 3, Collections.<Model>emptyList()) - ) - )); - list.add(new Model("entryThree", 30, - Arrays.asList( - new Model("3one", 1, Collections.<Model>emptyList()), - new Model("3two", 2, Collections.<Model>emptyList()), - new Model("3three", 3, Collections.<Model>emptyList()) - ) - )); - context.setContextValue(list, "models"); - - Model bean; - - testBinding(model, context, "$root.models", list); - - bean = list.get(0); - testBinding(model, context, "$root.models.0", bean); - testBinding(model, context, "$root.models.0.name", bean.getName()); - testBinding(model, context, "$root.models.0.integerValue", bean.getIntegerValue()); - testBinding(model, context, "$root.models.0.sons", bean.getSons()); - testBinding(model, context, "$root.models.0.sons.0", bean.getSons().get(0)); - testBinding(model, context, "$root.models.0.sons.0.name", bean.getSons().get(0).getName()); - - bean = list.get(1); - testBinding(model, context, "$root.models.1", bean); - testBinding(model, context, "$root.models.1.name", bean.getName()); - testBinding(model, context, "$root.models.1.integerValue", bean.getIntegerValue()); - testBinding(model, context, "$root.models.1.sons", bean.getSons()); - - bean = list.get(2); - testBinding(model, context, "$root.models.2", bean); - testBinding(model, context, "$root.models.2.name", bean.getName()); - testBinding(model, context, "$root.models.2.integerValue", bean.getIntegerValue()); - testBinding(model, context, "$root.models.2.sons", bean.getSons()); - - } - - protected void testBinding(NavigationTreeModel model, JAXXContext context, String contextPath, Object expected) throws Exception { - - Object value; - value = model.getJAXXContextValue(context, contextPath); - Assert.assertNotNull(value); - Assert.assertEquals(expected, value); - } - - protected static String getNodeContext(int... context) { - String result = ""; - for (int i : context) { - result += i; - } - return result; - } - - protected void assertNodeEquals(String contextPath, String nodeContext, int level, NavigationTreeNode node, boolean root) { - //System.out.println(contextPath + " : " + (node == null ? null : node.getContextPath())); - Assert.assertNotNull(node); - Assert.assertEquals(root, node.isRoot()); - Assert.assertEquals(level, node.getLevel()); - Assert.assertEquals(nodeContext, node.getContext()); - Assert.assertEquals(contextPath, node.getContextPath()); - } - - public static class Model { - - protected String name; - - protected int integerValue; - - protected List<Model> sons; - - public Model(String name, int integerValue, List<Model> sons) { - this.name = name; - this.integerValue = integerValue; - this.sons = sons; - } - - public String getName() { - return name; - } - - public int getIntegerValue() { - return integerValue; - } - - public List<Model> getSons() { - return sons; - } - - @Override - public String toString() { - return super.toString() + "<name:" + name + ",integerValue:" + integerValue + ",sons: " + sons + ">"; - } - } - -} Copied: lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java (from rev 1017, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/NavigationTreeModelTest.java) =================================================================== --- lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java (rev 0) +++ lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java 2008-11-17 11:55:31 UTC (rev 1019) @@ -0,0 +1,398 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.DefaultJAXXContext; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXContextEntryDef; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + + +/** + * Test du model de navigation. + * + * @author chemit + */ +public class NavigationTreeModelTest { + + + private static final String ROOT_CONTEXT = "$root"; + private static final String FAKE = "-fake"; + private static final String DOT = "."; + + @Test + public void testFindNode() throws Exception { + + NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); + + for (int i = 0; i < 4; i++) { + NavigationTreeNode sonNode = new NavigationTreeNode(getNodeContext(i), null, null, null); + rootNode.insert(sonNode, i); + for (int j = 0; j < 4; j++) { + NavigationTreeNode sonSonNode = new NavigationTreeNode(getNodeContext(i, j), null, 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); + } + } + } + + NavigationTreeModel model = new NavigationTreeModel(rootNode); + + NavigationTreeNode node; + String contextPath; + String currentNode; + + contextPath = ROOT_CONTEXT; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, ROOT_CONTEXT, 0, node, true); + + node = model.findNode(ROOT_CONTEXT + FAKE); + Assert.assertNull(node); + + for (int i = 0; i < 4; i++) { + currentNode = getNodeContext(i); + contextPath = ROOT_CONTEXT + DOT + currentNode; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, currentNode, 1, node, false); + + for (int j = 0; j < 4; j++) { + currentNode = getNodeContext(i, j); + contextPath = ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + currentNode; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, currentNode, 2, node, false); + + for (int k = 0; k < 4; k++) { + currentNode = getNodeContext(i, j, k); + contextPath = ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + getNodeContext(i, j) + DOT + currentNode; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, currentNode, 3, node, false); + } + + node = model.findNode(ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + getNodeContext(i, j) + DOT + currentNode + FAKE); + Assert.assertNull(node); + } + + node = model.findNode(ROOT_CONTEXT + DOT + getNodeContext(i) + DOT + currentNode + FAKE); + Assert.assertNull(node); + + } + + } + + /** + * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point + * as a bean. + * <p/> + * Tree is like this + * <pre> + * $root + + * - name <-- attached to context entry : java.lang.String.class,"name" + * - name2 <-- attached to context entry : java.lang.String.class,"name2" + * - model + <-- attached to context entry : Model.class,null + * - name + * -integerValue + * - sons + + * - 0 + + * - name + * - integerValue + * - sons + * - 1 + + * - name + * - integerValue + * - sons + * - 2 + + * - name + * - integerValue + * - sons + * </pre> + * <p/> + * With this tree, we will have to results : + * <pre> + * $root.name => context.get(String.class,"name") + * $root.name2 => context.get(String.class,"name2") + * $root.model => context.get(Model.class) + * $root.model.name => context.get(Model.class).getName() + * $root.model.integerValue => context.get(Model.class).getIntegerValue() + * $root.model.sons => context.get(Model.class).getSons() + * $root.model.sons.0 => context.get(Model.class).getSons().get(0) + * </pre> + * + * @throws Exception if any pb + */ + @Test + public void testGetJAXXContextValue() throws Exception { + + NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); + NavigationTreeNode sonNode; + NavigationTreeNode sonSonNode; + NavigationTreeNode sonSonSonNode; + + sonNode = new NavigationTreeNode("name", null, null, JAXXContextEntryDef.newDef("name", String.class)); + + rootNode.insert(sonNode, 0); + + sonNode = new NavigationTreeNode("name2", null, null, JAXXContextEntryDef.newDef("name2", String.class)); + + rootNode.insert(sonNode, 1); + + sonNode = new NavigationTreeNode("model", null, null, JAXXContextEntryDef.newDef(Model.class)); + + rootNode.insert(sonNode, 2); + + sonSonNode = new NavigationTreeNode("name", null, null, null); + sonNode.insert(sonSonNode, 0); + + sonSonNode = new NavigationTreeNode("integerValue", null, null, null); + sonNode.insert(sonSonNode, 1); + + sonSonNode = new NavigationTreeNode("sons", null, null, null); + sonNode.insert(sonSonNode, 2); + + sonSonSonNode = new NavigationTreeNode(0 + "", null, 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 = new NavigationTreeNode(1 + "", null, 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 = new NavigationTreeNode(2 + "", null, 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); + + NavigationTreeModel model = new NavigationTreeModel(rootNode); + + JAXXContext context = new DefaultJAXXContext(); + context.setContextValue("the name", "name"); + context.setContextValue("the name2", "name2"); + + + context.setContextValue( + new Model("modelName", 10, + Arrays.asList( + new Model("one", 1, Collections.<Model>emptyList()), + new Model("two", 2, Collections.<Model>emptyList()), + new Model("three", 3, Collections.<Model>emptyList()) + ) + ) + ); + + Assert.assertNull(model.getJAXXContextValue(context, "$root.name" + FAKE)); + + testBinding(model, context, "$root.name", context.getContextValue(String.class, "name")); + testBinding(model, context, "$root.name2", context.getContextValue(String.class, "name2")); + + Model bean = context.getContextValue(Model.class); + + testBinding(model, context, "$root.model", bean); + testBinding(model, context, "$root.model.name", bean.getName()); + testBinding(model, context, "$root.model.integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root.model.sons", bean.getSons()); + + testBinding(model, context, "$root.model.sons.0.name", bean.getSons().get(0).getName()); + testBinding(model, context, "$root.model.sons.0.integerValue", bean.getSons().get(0).getIntegerValue()); + testBinding(model, context, "$root.model.sons.0.sons", bean.getSons().get(0).getSons()); + + + testBinding(model, context, "$root.model.sons.1.name", bean.getSons().get(1).getName()); + testBinding(model, context, "$root.model.sons.1.integerValue", bean.getSons().get(1).getIntegerValue()); + testBinding(model, context, "$root.model.sons.1.sons", bean.getSons().get(1).getSons()); + + testBinding(model, context, "$root.model.sons.2.name", bean.getSons().get(2).getName()); + testBinding(model, context, "$root.model.sons.2.integerValue", bean.getSons().get(2).getIntegerValue()); + testBinding(model, context, "$root.model.sons.2.sons", bean.getSons().get(2).getSons()); + } + + /** + * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point + * as a list. + * <p/> + * Tree is like this + * <pre> + * $root + + * - models + <-- attached to context entry : java.util.List.class,"models" + * - 0 + + * - name + * -integerValue + * - sons + + * - 0 + + * - name + * - 1 + + * - name + * - integerValue + * - sons + * - 2 + + * - name + * - integerValue + * - sons + * </pre> + * <p/> + * With this tree, we will have to results : + * <pre> + * $root.models => context.get(List.class,"models") + * $root.models.0 => context.get(List.class,"models").get(0) + * $root.models.0.name => context.get(List.class,"models").get(0).getName() + * </pre> + * + * @throws Exception if any pb + */ + @Test + public void testGetJAXXContextValueFromList() throws Exception { + + NavigationTreeNode rootNode = new NavigationTreeNode(ROOT_CONTEXT, null, null, null); + NavigationTreeNode sonNode; + NavigationTreeNode sonSonNode; + NavigationTreeNode sonSonSonNode; + + // first son is a list of models + sonNode = new NavigationTreeNode("models", null, null, JAXXContextEntryDef.newListDef("models")); + rootNode.insert(sonNode, 0); + + // first son son is a model + sonSonNode = new NavigationTreeNode("0", null, 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); + + sonSonSonNode.insert(sonSonSonNode = new NavigationTreeNode("0", null, null, null), 0); + sonSonSonNode.insert(new NavigationTreeNode("name", null, null, null), 0); + + // second son son is a model + sonSonNode = new NavigationTreeNode("1", null, 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); + + // third son son is a model + sonSonNode = new NavigationTreeNode("2", null, 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); + + NavigationTreeModel model = new NavigationTreeModel(rootNode); + + JAXXContext context = new DefaultJAXXContext(); + List<Model> list = new ArrayList<Model>(); + list.add(new Model("entryOne", 10, + Arrays.asList( + new Model("one", 1, Collections.<Model>emptyList()), + new Model("two", 2, Collections.<Model>emptyList()), + new Model("three", 3, Collections.<Model>emptyList()) + ) + )); + list.add(new Model("entryTwo", 20, + Arrays.asList( + new Model("2one", 1, Collections.<Model>emptyList()), + new Model("2two", 2, Collections.<Model>emptyList()), + new Model("2three", 3, Collections.<Model>emptyList()) + ) + )); + list.add(new Model("entryThree", 30, + Arrays.asList( + new Model("3one", 1, Collections.<Model>emptyList()), + new Model("3two", 2, Collections.<Model>emptyList()), + new Model("3three", 3, Collections.<Model>emptyList()) + ) + )); + context.setContextValue(list, "models"); + + Model bean; + + testBinding(model, context, "$root.models", list); + + bean = list.get(0); + testBinding(model, context, "$root.models.0", bean); + testBinding(model, context, "$root.models.0.name", bean.getName()); + testBinding(model, context, "$root.models.0.integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root.models.0.sons", bean.getSons()); + testBinding(model, context, "$root.models.0.sons.0", bean.getSons().get(0)); + testBinding(model, context, "$root.models.0.sons.0.name", bean.getSons().get(0).getName()); + + bean = list.get(1); + testBinding(model, context, "$root.models.1", bean); + testBinding(model, context, "$root.models.1.name", bean.getName()); + testBinding(model, context, "$root.models.1.integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root.models.1.sons", bean.getSons()); + + bean = list.get(2); + testBinding(model, context, "$root.models.2", bean); + testBinding(model, context, "$root.models.2.name", bean.getName()); + testBinding(model, context, "$root.models.2.integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root.models.2.sons", bean.getSons()); + + } + + protected void testBinding(NavigationTreeModel model, JAXXContext context, String contextPath, Object expected) throws Exception { + + Object value; + value = model.getJAXXContextValue(context, contextPath); + Assert.assertNotNull(value); + Assert.assertEquals(expected, value); + } + + protected static String getNodeContext(int... context) { + String result = ""; + for (int i : context) { + result += i; + } + return result; + } + + protected void assertNodeEquals(String contextPath, String nodeContext, int level, NavigationTreeNode node, boolean root) { + //System.out.println(contextPath + " : " + (node == null ? null : node.getContextPath())); + Assert.assertNotNull(node); + Assert.assertEquals(root, node.isRoot()); + Assert.assertEquals(level, node.getLevel()); + Assert.assertEquals(nodeContext, node.getContext()); + Assert.assertEquals(contextPath, node.getContextPath()); + } + + public static class Model { + + protected String name; + + protected int integerValue; + + protected List<Model> sons; + + public Model(String name, int integerValue, List<Model> sons) { + this.name = name; + this.integerValue = integerValue; + this.sons = sons; + } + + public String getName() { + return name; + } + + public int getIntegerValue() { + return integerValue; + } + + public List<Model> getSons() { + return sons; + } + + @Override + public String toString() { + return super.toString() + "<name:" + name + ",integerValue:" + integerValue + ",sons: " + sons + ">"; + } + } + +}
participants (1)
-
chemit@users.labs.libre-entreprise.org