r1807 - trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation
Author: sletellier Date: 2010-03-25 14:20:44 +0100 (Thu, 25 Mar 2010) New Revision: 1807 Log: - Remove sorted tree adapter - Refactor helper to create generic builder / helper / model - Creating builder to build a sorted model Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/AbstractNavigationModelBuilder.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationHelper.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationTreeModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeModelBuilder.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeNode.java Removed: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationSortedTreeAdapter.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModelBuilder.java Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModelBuilder.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHelper.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModel.java Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/AbstractNavigationModelBuilder.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/AbstractNavigationModelBuilder.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/AbstractNavigationModelBuilder.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -0,0 +1,262 @@ +/* + * *##% + * JAXX Runtime + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.context.JAXXContextEntryDef; +import jaxx.runtime.decorator.Decorator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Enumeration; + +/** + * Interface to create a builder, this object is design to build a + * {@link NavigationModel}. + * + * @author sletellier + * @since 2.0.0 + */ +public abstract class AbstractNavigationModelBuilder<E extends NavigationTreeNode> implements NavigationModelBuilder<E> { + + /** + * Logger + */ + static private final Log log = LogFactory.getLog(AbstractNavigationModelBuilder.class); + /** + * The model dealed by the builder. + * + * <b>Note:</b> It is a good idea to keep only one instance of the model. + * If reset is required, should empty the model but not reinstanciate it. + */ + protected NavigationModel<E> model; + /** + * default ui class to use if node does not define an ui class + */ + protected Class<? extends JAXXObject> defaultUIClass; + /** + * [optional] default action class + */ + protected Class<? extends JAXXAction> defaultUIHandlerClass; + + public AbstractNavigationModelBuilder(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, NavigationModel<E> model) { + this.defaultUIClass = defaultUIClass; + this.defaultUIHandlerClass = defaultUIHandlerClass; + this.model = model; + } + + public NavigationModel<E> getModel() { + return model; + } + + public E buildEmptyRoot(JAXXContextEntryDef<?> entryDef, String contextName) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, entryDef, null); + addI18nNodeRenderer(node, ""); + return addChildNode(null, node); + } + + public E build(E parentNode, String libelle, + JAXXContextEntryDef<?> entryDef, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, entryDef, entryPath); + addI18nNodeRenderer(node, libelle); + addNodeJaxxClasses(node, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public E build(E parentNode, String libelle, + JAXXContextEntryDef<?> entryDef, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, entryDef, null); + addI18nNodeRenderer(node, libelle); + addNodeJaxxClasses(node, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public E build(E parentNode, String libelle, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, null, entryPath); + addI18nNodeRenderer(node, libelle); + addNodeJaxxClasses(node, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public E build(E parentNode, Decorator<?> decorator, + JAXXContextEntryDef<?> entryDef, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, entryDef, entryPath); + addDecoratorNodeRenderer(node, decorator); + addNodeJaxxClasses(node, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public E build(E parentNode, Decorator<?> decorator, + JAXXContextEntryDef<?> entryDef, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, entryDef, null); + addDecoratorNodeRenderer(node, decorator); + addNodeJaxxClasses(node, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public E build(E parentNode, Decorator<?> decorator, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + E node = createNavigationTreeNode(model.getPathSeparator(), contextName, null, entryPath); + addDecoratorNodeRenderer(node, decorator); + addNodeJaxxClasses(node, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + protected E addChildNode(E parentNode, E node) { + + if (node.getUIClass() == null) { + // no ui is associated with this node, use the default one + node.setUIClass(defaultUIClass); + } + + if (node.getUIHandlerClass() == null) { + // no ui handler associated with this node, use the default one + node.setUIHandlerClass(defaultUIHandlerClass); + } + if (parentNode == null) { + model.setRoot(node); + } else { + parentNode.add(node); + } + model.nodeStructureChanged(node); + return node; + } + + public E removeChildNode(E node) { + E parentNode = (E)node.getParent(); + model.removeNodeFromParent(node); + return parentNode; + } + + public void addI18nNodeRenderer(E node, String libelle) { + node.setRenderer(new NavigationTreeNodeRendererI18nImpl(libelle)); + } + + public void addDecoratorNodeRenderer(E node, Decorator<?> decorator) { + node.setRenderer(new NavigationTreeNodeRendererDecoratorImpl(decorator)); + } + + public void addNodeJaxxClasses( + E node, + Class<? extends JAXXObject> uIClass, + Class<? extends JAXXAction> uIHandlerClass) { + node.setUIClass(uIClass); + node.setUIHandlerClass(uIHandlerClass); + } + + public void printModel(E node) { + if (node == null) { + return; + } + log.info("node " + node.getFullPath() + ", jxpath: " + node.getJaxxContextEntryPath() + ", entryContextDef: " + node.getJaxxContextEntryDef()); + if (log.isDebugEnabled()) { + log.debug("node userObject" + node.getUserObject()); + log.debug("value from node " + node.getBean(getModel().getContext())); + log.debug("value from model " + getModel().getBean(node)); + } + Enumeration<?> children = node.children(); + while (children.hasMoreElements()) { + printModel((E) children.nextElement()); + } + } + + // To create your own instance of NavigationTreeTableNode + public abstract E createNavigationTreeNode(String pathSeparator, String contextName, JAXXContextEntryDef<?> jaxxContextEntryDef, String jaxxContextEntryPath); + + public static abstract class ChildBuilder<O, E extends NavigationTreeNode> { + + protected AbstractNavigationModelBuilder<E> builder; + + protected ChildBuilder(AbstractNavigationModelBuilder<E> builder) { + this.builder = builder; + } + + protected abstract void init(Class<? extends O> klass); + + protected abstract Decorator<? extends O> getDecorator(O child); + + protected abstract String getJXPath(O child); + + protected abstract String getNavigationPath(O child); + + public void build(E parent, boolean cacheValues, Class<? extends O> klass, java.util.Collection<? extends O> beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { + + if (beans == null || beans.isEmpty()) { + // no bean to treate + return; + } + + init(klass); + + E node; + + for (O o : beans) { + node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); + if (cacheValues) { + // cache the bean value to improve performance + node.setBean(o); + } + } + } + + public void build(E parent, boolean cacheValues, Class<? extends O> klass, O[] beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { + + if (beans == null || beans.length == 0) { + // no bean to treate + return; + } + + init(klass); + + E node; + + for (O o : beans) { + node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); + if (cacheValues) { + // cache the bean value to improve performance + node.setBean(o); + } + } + } + } +} Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationHelper.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationHelper.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationHelper.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -0,0 +1,309 @@ +/* + * *##% + * JAXX Runtime + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXObject; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.swingx.JXTreeTable; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.lang.reflect.InvocationTargetException; +import java.util.Enumeration; +import java.util.regex.Pattern; + +/** + * Helper object associated to a given navigation tree system. + * + * To helper is context safe (base on a {@link NavigationTreeContextHelper}. + * + * @author Letellier + * @since 2.0.1 + * @see NavigationTreeModel + */ +public abstract class GenericNavigationHelper <E extends NavigationTreeNode> extends NavigationTreeContextHelper<E>{ + + /** + * Logger + */ + static private final Log log = + LogFactory.getLog(NavigationTreeHelper.class); + + /** + * Create the model. + * + * @param context the context to associate with fresh model + * @return the new model build with data from the given context + */ + public abstract NavigationModel createTreeModel(JAXXContext context); + + /** + * Create the tree handler. + * + * @param context the context to associate with fresh handler + * @return the new handler + */ + public abstract NavigationTreeHandler createTreeHandler(JAXXObject context); + + public GenericNavigationHelper(String contextPrefix) { + super(contextPrefix); + } + + public Object getContextValue(JAXXContext context, String path) + throws InvocationTargetException, NoSuchMethodException, + IllegalAccessException { + NavigationModel treeModel = getSafeModel(context); + return treeModel.getBean(path); + } + + public E findNode(JAXXContext context, String path) { + NavigationModel<E> treeModel = getSafeModel(context); + return treeModel.findNode(path); + } + + public E findNode(JAXXContext context, String path, + String regex) { + NavigationModel<E> treeModel = getSafeModel(context); + return treeModel.findNode(path, regex); + } + + public E findNode(JAXXContext context, String path, + Pattern regex) { + + NavigationModel<E> treeModel = getSafeModel(context); + return treeModel.findNode(path, regex); + } + + public E findNode(JAXXContext context, String path, + String regex, String suffix) { + + NavigationModel<E> treeModel = getSafeModel(context); + + E node= treeModel.findNode(path, regex); + if (node != null && suffix != null) { + node = treeModel.findNode(node, suffix); + } + return node; + } + + public E findNode(JAXXContext context, String path, + Pattern regex, String suffix) { + + NavigationModel<E> treeModel = getSafeModel(context); + + E node = treeModel.findNode(path, regex); + if (node != null && suffix != null) { + node = treeModel.findNode(node, suffix); + } + return node; + } + + /** + * Sélection d'un noeud dans l'arbre de navigation à partir de son path. + * + * @param context le contexte applicatif + * @param path le path absolue du noeud dans l'arbre + */ + public void selectNode(JAXXContext context, String path) { + E node = findNode(context, path); + if (log.isDebugEnabled()) { + log.debug(path + " :: " + node); + } + if (node != null) { + selectNode(context, node); + } + } + + /** + * Sélection d'un noeud dans l'arbre de navigation. + * + * @param context le contexte applicatif + * @param node le noeud à sélectionner dans l'arbre + */ + public void selectNode(JAXXContext context, E node) { + + + NavigationModel navigationModel = getSafeModel(context); + if (log.isDebugEnabled()) { + log.debug(node); + } + TreePath path = new TreePath(navigationModel.getPathToRoot(node)); + JTree tree = getTree(context); + if (tree == null){ + // FIXME : Refactor in other helper ? + // If its JXTreeTable + JXTreeTable treeTable = getSafeTreeTable(context); + treeTable.getTreeSelectionModel().setSelectionPath(path); + treeTable.scrollPathToVisible(path); + return; + } + tree.setSelectionPath(path); + tree.scrollPathToVisible(path); + } + + /** + * Sélection du parent du noeud selectionne dans l'arbre de navigation. + * + * @param context le contexte applicatif + */ + public void gotoParentNode(JAXXContext context) { + + E node = getSelectedNode(context); + + if (node == null) { + // pas de noeud selectionne + throw new NullPointerException("no selected node in context"); + } + node = (E)node.getParent(); + + selectNode(context, node); + } + + /** + * Obtain the first ancestor with the matching internalClass + * + * @param current the node to test + * @param beanClass the type of the internal class to seek of + * @return the first ancestor node with the matching class or + * {@code null} if not found + */ + public E getParentNode(E current, + Class<?> beanClass) { + if (current == null) { + // ancestor not found + return null; + } + if (beanClass.isAssignableFrom(current.getInternalClass())) { + // matching node + return current; + } + // try in the parent of node + return getParentNode((E)current.getParent(), beanClass); + } + + /** + * Sélection d'un fils du noeud selectionne dans l'arbre de navigation. + * + * @param context le contexte applicatif + * @param childIndex index du fils a selectionner + */ + public void gotoChildNode(JAXXContext context, int childIndex) { + + E node = getSelectedNode(context); + + if (node == null) { + // pas de noeud selectionne + throw new NullPointerException("no selected node in context"); + } + node = (E)node.getChildAt(childIndex); + + selectNode(context, node); + } + + /** + * Demande une opération de repaint sur un noeud de l'arbre de navigation. + * + * <b>Note:</b> La descendance du noeud n'est pas repainte. + * + * @param context le contexte applicatif + * @param node le noeud à repaindre + */ + public void repaintNode(JAXXContext context, E node) { + repaintNode(context, node, false); + } + + /** + * Demande une opération de repaint sur un noeud de l'arbre de navigation. + * + * <b>Note:</b> La descendance du noeud est repainte si le paramètre + * <code>deep</code> est à <code>true</code>. + * + * @param context le contexte applicatif + * @param node le noeud à repaindre + * @param deep un flag pour activer la repainte de la descendance du noeud + */ + public void repaintNode(JAXXContext context, E node, + boolean deep) { + NavigationModel navigationModel = getSafeModel(context); + if (log.isDebugEnabled()) { + log.debug(node); + } + navigationModel.nodeChanged(node); + if (deep) { + // repaint childs nodes + //todo we should only repaint necessary nodes ? + Enumeration<?> e = node.children(); + while (e.hasMoreElements()) { + E child = (E) e.nextElement(); + repaintNode(context, child, true); + } + } + } + + /** + * @deprecated please use {@link #getSafeModel(JAXXContext)}, will be + * remove soon + * @param context where to find + * @return the tree model + * @throws NullPointerException if model is null + */ + @Deprecated + public NavigationTreeModel getSafeTreeModel(JAXXContext context) + throws NullPointerException { + NavigationModel model = getSafeModel(context); + if (model instanceof NavigationTreeModel){ + return (NavigationTreeModel) model; + } + return null; + } + + public NavigationModel getSafeModel(JAXXContext context) + throws NullPointerException { + NavigationModel model = getModel(context); + if (model == null) { + throw new NullPointerException("could not find tree model " + + "with key " + getModelContextEntry() + " in context " + + context); + } + return model; + } + + public JTree getSafeTree(JAXXContext context) throws NullPointerException { + JTree tree = getTree(context); + if (tree == null) { + throw new NullPointerException("could not find tree with key " + + getTreeContextEntry() + " in context " + context); + } + return tree; + } + + public JXTreeTable getSafeTreeTable(JAXXContext context) + throws NullPointerException { + JXTreeTable treeTable = getTreeTable(context); + if (treeTable == null) { + throw new NullPointerException("could not find tree with key " + + getTreeTableContextEntry() + " in context " + context); + } + return treeTable; + } +} Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationTreeModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationTreeModel.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/GenericNavigationTreeModel.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -0,0 +1,251 @@ +/* + * *##% + * JAXX Runtime + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Model of the tree used for a navigation tree. + * <p/> + * Il est composé de {@link NavigationTreeNode} + * + * @author letellier + * @since 2.0.1 + */ +public class GenericNavigationTreeModel<E extends NavigationTreeNode> extends DefaultTreeModel implements NavigationModel<E>{ + + static private final long serialVersionUID = 1L; + /** + * Logger + */ + static private final Log log = LogFactory.getLog(NavigationTreeModel.class); + /** + * The path separator used to build the {@link NavigationTreeNode#fullPath}. + * + * @see NavigationTreeNode#getNodePath() + * @see NavigationTreeNode#getFullPath() + */ + protected final String pathSeparator; + /** + * Context to retrieve beans + */ + private JAXXContext context; + + public GenericNavigationTreeModel(String pathSeparator, JAXXContext context) { + super(null); + this.pathSeparator = pathSeparator; + this.context = context; + } + + /** + * @see NavigationModel#getRoot() + */ + @Override + public E getRoot() { + return (E) super.getRoot(); + } + + @Override + public void setRoot(E root) { + super.setRoot(root); + } + + /** + * @see NavigationModel#findNode(String) + */ + @Override + public E findNode(String path) { + return findNode(getRoot(), path, (Pattern) null); + } + + /** + * @see NavigationModel#findNode(String, String) + */ + @Override + public E findNode(String path, String regex) { + return findNode(getRoot(), path, regex); + } + + /** + * @see NavigationModel#findNode(String, Pattern) + */ + @Override + public E findNode(String path, Pattern regex) { + return findNode(getRoot(), path, regex); + } + + /** + * @see NavigationModel#findNode(NavigationTreeNode, String) + */ + @Override + public E findNode(E root, String path) { + return findNode(root, path, (Pattern) null); + } + + /** + * @see NavigationModel#findNode(NavigationTreeNode, String, String) + */ + @Override + public E findNode(E root, + String path, + String regex) { + return findNode(root, path, + regex == null ? null : Pattern.compile(regex)); + } + + /** + * @see NavigationModel#findNode(NavigationTreeNode, String, Pattern) + */ + @Override + public E findNode(E 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); + if (log.isDebugEnabled()) { + log.debug("matching regex " + regex + " : " + path); + } + } + StringTokenizer stk = new StringTokenizer(path, pathSeparator); + E result = root; + // pas the first token (matches the root node) + if (root.isRoot() && stk.hasMoreTokens()) { + String rootPath = stk.nextToken(); + if (!rootPath.equals(root.getNodePath())) { + return null; + } + } + while (stk.hasMoreTokens()) { + result = (E)result.getChild(stk.nextToken()); + } + return result; + } + + /** + * @see NavigationModel#getContext() + */ + @Override + public JAXXContext getContext() { + return context; + } + + /** + * @see NavigationModel#getBean(String) + */ + @Override + public Object getBean(String navigationPath) { + Object result; + E node = findNode(navigationPath, (Pattern) null); + result = getBean(node); + return result; + } + + /** + * @see NavigationModel#getBean(NavigationTreeNode) + */ + @Override + public Object getBean(E node) { + if (node == null) { + return null; + //fixme should throw a NPE exception + //throw new NullPointerException("node can not be null"); + } + return node.getBean(getContext()); + } + + /** + * @see NavigationModel#nodeChanged(TreeNode) + */ + @Override + public void nodeChanged(TreeNode node) { + nodeChanged(node, false); + if (log.isDebugEnabled()) { + log.debug(node); + } + } + + /** + * @see NavigationModel#nodeStructureChanged(TreeNode) + */ + @Override + public void nodeStructureChanged(TreeNode node) { + E n = (E) node; + //TC-20091004 never launch a deep reload + reload(n, true); + super.nodeStructureChanged(node); + if (log.isDebugEnabled()) { + log.debug(node); + } + } + + /** + * @see NavigationModel#nodeChanged(TreeNode, boolean) + */ + @Override + public void nodeChanged(TreeNode node, boolean deep) { + + E n = (E) node; + //TC-20091004 never launch a deep clean, since we do a deep nodeChanged. + reload(n, deep); + super.nodeChanged(node); + } + + protected void reload(E node) { + reload(node, false); + } + + protected void reload(E node, boolean deep) { + if (node == null) { + return; + } + node.reload(getContext()); + + if (deep) { + Enumeration<?> childs = node.children(); + while (childs.hasMoreElements()) { + E o = (E) childs.nextElement(); + reload(o, true); + } + } + } + + /** + * @see NavigationModel#getPathSeparator() + */ + @Override + public String getPathSeparator() { + return pathSeparator; + } +} Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModel.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModel.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -22,6 +22,7 @@ import jaxx.runtime.JAXXContext; +import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import java.util.regex.Pattern; @@ -34,12 +35,16 @@ * @author sletellier * @since 2.0.0 */ -public interface NavigationModel extends TreeModel { +public interface NavigationModel<E extends NavigationTreeNode> extends TreeModel { - Object getRoot(); + E getRoot(); + void setRoot(E root); + TreeNode[] getPathToRoot(TreeNode aNode); + public void removeNodeFromParent(MutableTreeNode node); + /** * Search from the root node a node named by his fully path (concatenation * of nodes {@link NavigationTreeNode#path} valued separated by dot. @@ -52,7 +57,7 @@ * @return the node matching the fully context from the root node, * or <code>null</code> if not find. */ - NavigationTreeNode findNode(String path); + E findNode(String path); /** * Apply first the regex pattern to obtain the searched node fi the given @@ -72,7 +77,7 @@ * @return the node matching the fully context from the root node, or * <code>null</code> if not found. */ - NavigationTreeNode findNode(String path, String regex); + E findNode(String path, String regex); /** * Apply first the regex pattern to obtain the searched node. @@ -90,7 +95,7 @@ * @return the node matching the fully context from the root node, or * <code>null</code> if not found. */ - NavigationTreeNode findNode(String path, Pattern regex); + E findNode(String path, Pattern regex); /** * Search from a given root node a node named by his fully path @@ -102,7 +107,7 @@ * @return the node matching the fully context from the given root node, or * <code>null</code> if not found. */ - NavigationTreeNode findNode(NavigationTreeNode root, String path); + E findNode(E root, String path); /** * Apply first the regex pattern to obtain the searched node. @@ -117,7 +122,7 @@ * @return the node matching the fully context from the given root node, * or <code>null</code> if not found. */ - NavigationTreeNode findNode(NavigationTreeNode root, String path, + E findNode(E root, String path, String regex); /** @@ -133,7 +138,7 @@ * @return the node matching the fully context from the given root node, * or <code>null</code> if not found. */ - NavigationTreeNode findNode(NavigationTreeNode root, String path, + E findNode(E root, String path, Pattern regex); JAXXContext getContext(); @@ -153,7 +158,7 @@ * @param node the current node * @return the value associated in context with the given node. */ - Object getBean(NavigationTreeNode node); + Object getBean(E node); void nodeChanged(TreeNode node); Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModelBuilder.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModelBuilder.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationModelBuilder.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -32,14 +32,14 @@ * @author sletellier * @since 2.0.0 */ -public interface NavigationModelBuilder { +public interface NavigationModelBuilder <E extends NavigationTreeNode> { NavigationModel getModel(); - NavigationTreeNode buildEmptyRoot(JAXXContextEntryDef<?> entryDef, + E buildEmptyRoot(JAXXContextEntryDef<?> entryDef, String contextName); - NavigationTreeNode build(NavigationTreeNode parentNode, + E build(E parentNode, String libelle, JAXXContextEntryDef<?> entryDef, String entryPath, @@ -47,21 +47,21 @@ Class<? extends JAXXObject> uiClass, Class<? extends JAXXAction> actionClass); - NavigationTreeNode build(NavigationTreeNode parentNode, + E build(E parentNode, String libelle, JAXXContextEntryDef<?> entryDef, String contextName, Class<? extends JAXXObject> uiClass, Class<? extends JAXXAction> actionClass); - NavigationTreeNode build(NavigationTreeNode parentNode, + E build(E parentNode, String libelle, String entryPath, String contextName, Class<? extends JAXXObject> uiClass, Class<? extends JAXXAction> actionClass); - NavigationTreeNode build(NavigationTreeNode parentNode, + E build(E parentNode, Decorator<?> decorator, JAXXContextEntryDef<?> entryDef, String entryPath, @@ -69,32 +69,32 @@ Class<? extends JAXXObject> uiClass, Class<? extends JAXXAction> actionClass); - NavigationTreeNode build(NavigationTreeNode parentNode, + E build(E parentNode, Decorator<?> decorator, JAXXContextEntryDef<?> entryDef, String contextName, Class<? extends JAXXObject> uiClass, Class<? extends JAXXAction> actionClass); - NavigationTreeNode build(NavigationTreeNode parentNode, + E build(E parentNode, Decorator<?> decorator, String entryPath, String contextName, Class<? extends JAXXObject> uiClass, Class<? extends JAXXAction> actionClass); - NavigationTreeNode removeChildNode(NavigationTreeNode node); + E removeChildNode(E node); - void addI18nNodeRenderer(NavigationTreeNode node, + void addI18nNodeRenderer(E node, String libelle); - void addDecoratorNodeRenderer(NavigationTreeNode node, + void addDecoratorNodeRenderer(E node, Decorator<?> decorator); void addNodeJaxxClasses( - NavigationTreeNode node, + E node, Class<? extends JAXXObject> uIClass, Class<? extends JAXXAction> uIHandlerClass); - void printModel(NavigationTreeNode node); + void printModel(E node); } Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationSortedTreeAdapter.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationSortedTreeAdapter.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationSortedTreeAdapter.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -1,260 +0,0 @@ -/* - * *##% - * JAXX Runtime - * Copyright (C) 2008 - 2009 CodeLutin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * ##%* - */ -package jaxx.runtime.swing.navigation; - -import jaxx.runtime.decorator.Decorator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import javax.swing.event.TreeModelEvent; -import javax.swing.event.TreeModelListener; -import java.util.*; - -/** - * Adapter to sort NavigationModel - * FIXME : Dont work with TreeTable - * - * @author sletellier - * @since 2.0.1 - */ -public class NavigationSortedTreeAdapter implements TreeModelListener { - - /** - * Logger - */ - static private final Log log = LogFactory.getLog(NavigationSortedTreeAdapter.class); - - protected NavigationModel model; - protected List<Comparator> comparators; - protected boolean ignoreCase = false; - - /** - * Used to sort NavigationTreeModel by decorator - * - * @param model of navigation tree - */ - public NavigationSortedTreeAdapter(NavigationModel model){ - this.model = model; - model.addTreeModelListener(this); - } - - /** - * Used to sort NavigationTreeModel by decorator - * - * @param model of navigation tree - * @param ignoreCase tio ignore renderer case renderer - */ - public NavigationSortedTreeAdapter(NavigationModel model, boolean ignoreCase){ - this.ignoreCase = ignoreCase; - this.model = model; - model.addTreeModelListener(this); - } - - /** - * Used to sort NavigationTreeModel by comparator - * - * @param model of navigation tree - * @param comparator used to sort tree - */ - public NavigationSortedTreeAdapter(NavigationModel model, Comparator comparator){ - this.model = model; - comparators = new ArrayList<Comparator>(); - comparators.add(comparator); - model.addTreeModelListener(this); - } - - /** - * Used to sort NavigationTreeModel by comparators - * - * @param model of navigation tree - * @param comparators used to sort tree - */ - public NavigationSortedTreeAdapter(NavigationModel model, List<Comparator> comparators){ - this.model = model; - this.comparators = comparators; - model.addTreeModelListener(this); - } - - /** - * Used to sort NavigationTreeModel by comparators - * - * @param model of navigation tree - * @param comparators used to sort tree - */ - public NavigationSortedTreeAdapter(NavigationModel model, Comparator ... comparators){ - this.model = model; - this.comparators = Arrays.asList(comparators); - model.addTreeModelListener(this); - } - - // TODO : find how optimize this (structure not change every times) - @Override - public void treeNodesChanged(TreeModelEvent e) { - sort(getCurrentNode(e), true); - } - - @Override - public void treeNodesInserted(TreeModelEvent e) { - sort(getCurrentNode(e), true); - } - - @Override - public void treeNodesRemoved(TreeModelEvent e) { - } - - @Override - public void treeStructureChanged(TreeModelEvent e) { - sort(getCurrentNode(e), true); - } - - protected NavigationTreeNode getCurrentNode(TreeModelEvent e){ - return (NavigationTreeNode) e.getTreePath().getLastPathComponent(); - } - - // Sort - protected void sort() { - NavigationTreeNode rootNode = (NavigationTreeNode) model.getRoot(); - if (rootNode != null && log.isDebugEnabled()){ - log.debug("Sort from root node : " + rootNode.getBean()); - } - sort(rootNode, true); - } - protected void sort(NavigationTreeNode parent, boolean structureChanged) { - - if (parent == null){ - return; - } - - List<NavigationTreeNode> children = Collections.list(parent.children()); - - if (comparators == null || comparators.isEmpty()){ - Collections.sort(children, rendererDecorator); - } else { - children = sortWithComparators(children); - } - - if (children == null || children.isEmpty()){ - return; - } - - Iterator<NavigationTreeNode> childrenIterator = children.iterator(); - if (childrenIterator != null){ - - model.removeTreeModelListener(this); - - parent.removeAllChildren(); - while (childrenIterator.hasNext()) { - NavigationTreeNode childNode = childrenIterator.next(); - if (log.isDebugEnabled()){ - log.debug("Adding child " + childNode.getBean() + " to parent " + parent.getBean()); - } - parent.add(childNode); - } - - if (structureChanged){ - model.nodeStructureChanged(parent); - } else { - model.nodeChanged(parent, true); - } - model.addTreeModelListener(this); - } - } - - protected List<NavigationTreeNode> sortWithComparators(List<NavigationTreeNode> children) { - for (Comparator<?> comparator : comparators){ - List<NavigationTreeNode> result = sortWithComparator(children, comparator); - if (result != null){ - return result; - } - } - return null; - } - - protected <T> List<NavigationTreeNode> sortWithComparator(List<NavigationTreeNode> children, - Comparator<T> comparator) { - Map<T, NavigationTreeNode> toSort = new HashMap<T, NavigationTreeNode>(); - - List<T> beans = new ArrayList<T>(); - - // Extract beans - for (NavigationTreeNode child : children){ - Object o = child.getBean(); - if (o != null){ - try{ - T casted = (T) o; - beans.add(casted); - toSort.put(casted, child); - } catch (ClassCastException eee){ - return null; - } - } - } - - if (beans.isEmpty()){ - return null; - } - - // Sort beans - if (log.isDebugEnabled()){ - log.debug("Sorting : " + - beans.get(0).getClass().getName() + - " With comparator : " + comparator.getClass().getName()); - } - - try{ - Collections.sort(beans, comparator); - } catch (Exception eee){ - if (log.isWarnEnabled()){ - log.warn("Cant appply comparator : " + comparator.getClass().getName() - + " with entity of type : " - + (beans.isEmpty() ? " vide " : beans.get(0).getClass().getName())); - } - return null; - } - - // Retrieve sorted nodes - children.clear(); - int cnt = 0; - for (T bean : beans){ - if (log.isDebugEnabled()){ - log.debug("Retrieve sorted bean : " + ++cnt + " - " + bean); - } - children.add(toSort.get(bean)); - } - return children; - } - - final Comparator rendererDecorator = new Comparator() { - @Override - public int compare(Object o1, Object o2) { - try { - String label1 = ((NavigationTreeNode)o1).getRenderer().toString(); - String label2 = ((NavigationTreeNode)o2).getRenderer().toString(); - if (ignoreCase){ - return label1.compareToIgnoreCase(label2); - } - return label1.compareTo(label2); - } catch (Exception eee) { - return 0; - } - } - }; -} Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -64,7 +64,7 @@ * @author chemit * @since 1.7.2 */ -public class NavigationTreeContextHelper { +public class NavigationTreeContextHelper <E extends NavigationTreeNode> { /** * Logger @@ -74,7 +74,7 @@ protected final String prefix; protected JAXXContextEntryDef<List<String>> selectedPathsContextEntry; protected JAXXContextEntryDef<List<Object>> selectedBeansContextEntry; - protected JAXXContextEntryDef<List<NavigationTreeNode>> selectedNodesContextEntry; + protected JAXXContextEntryDef<List<E>> selectedNodesContextEntry; protected JAXXContextEntryDef<NavigationModel> modelContextEntry; protected JAXXContextEntryDef<NavigationTreeHandler> handlerContextEntry; protected JAXXContextEntryDef<JTree> treeContextEntry; @@ -140,12 +140,12 @@ return getSelectedPathContextEntry().getContextValue(context); } - public NavigationTreeNode getSelectedNode(JAXXContext context) { - NavigationTreeNode result = getSelectedValue(getSelectedNodeContextEntry(),context); + public E getSelectedNode(JAXXContext context) { + E result = getSelectedValue(getSelectedNodeContextEntry(),context); return result; } - public List<NavigationTreeNode> getSelectedNodes(JAXXContext context) { + public List<E> getSelectedNodes(JAXXContext context) { return getSelectedNodeContextEntry().getContextValue(context); } @@ -194,11 +194,11 @@ setSelectedValues(getSelectedPathContextEntry(), context, paths); } - public void setSelectedNode(JAXXContext context, NavigationTreeNode node) { + public void setSelectedNode(JAXXContext context, E node) { setSelectedValue(getSelectedNodeContextEntry(), context, node); } - public void setSelectedNodes(JAXXContext context, List<NavigationTreeNode> nodes) { + public void setSelectedNodes(JAXXContext context, List<E> nodes) { setSelectedValues(getSelectedNodeContextEntry(), context, nodes); } @@ -223,7 +223,7 @@ return selectedBeansContextEntry; } - protected JAXXContextEntryDef<List<NavigationTreeNode>> getSelectedNodeContextEntry() { + protected JAXXContextEntryDef<List<E>> getSelectedNodeContextEntry() { return selectedNodesContextEntry; } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHelper.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHelper.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHelper.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -40,269 +40,9 @@ * @since 1.7.2 * @see NavigationTreeModel */ -public abstract class NavigationTreeHelper extends NavigationTreeContextHelper { - - /** - * Logger - */ - static private final Log log = - LogFactory.getLog(NavigationTreeHelper.class); - - /** - * Create the model. - * - * @param context the context to associate with fresh model - * @return the new model build with data from the given context - */ - public abstract NavigationModel createTreeModel(JAXXContext context); - - /** - * Create the tree handler. - * - * @param context the context to associate with fresh handler - * @return the new handler - */ - public abstract NavigationTreeHandler createTreeHandler(JAXXObject context); - - public NavigationTreeHelper(String contextPrefix) { +public abstract class NavigationTreeHelper extends GenericNavigationHelper<NavigationTreeNode> { + + protected NavigationTreeHelper(String contextPrefix) { super(contextPrefix); } - - public Object getContextValue(JAXXContext context, String path) - throws InvocationTargetException, NoSuchMethodException, - IllegalAccessException { - NavigationModel treeModel = getSafeModel(context); - return treeModel.getBean(path); - } - - public NavigationTreeNode findNode(JAXXContext context, String path) { - NavigationModel treeModel = getSafeModel(context); - return treeModel.findNode(path); - } - - public NavigationTreeNode findNode(JAXXContext context, String path, - String regex) { - NavigationModel treeModel = getSafeModel(context); - return treeModel.findNode(path, regex); - } - - public NavigationTreeNode findNode(JAXXContext context, String path, - Pattern regex) { - - NavigationModel treeModel = getSafeModel(context); - return treeModel.findNode(path, regex); - } - - public NavigationTreeNode findNode(JAXXContext context, String path, - String regex, String suffix) { - - NavigationModel treeModel = getSafeModel(context); - - NavigationTreeNode navigationTreeNode = treeModel.findNode(path, regex); - if (navigationTreeNode != null && suffix != null) { - navigationTreeNode = treeModel.findNode(navigationTreeNode, suffix); - } - return navigationTreeNode; - } - - public NavigationTreeNode findNode(JAXXContext context, String path, - Pattern regex, String suffix) { - - NavigationModel treeModel = getSafeModel(context); - - NavigationTreeNode navigationTreeNode = treeModel.findNode(path, regex); - if (navigationTreeNode != null && suffix != null) { - navigationTreeNode = treeModel.findNode(navigationTreeNode, suffix); - } - return navigationTreeNode; - } - - /** - * Sélection d'un noeud dans l'arbre de navigation à partir de son path. - * - * @param context le contexte applicatif - * @param path le path absolue du noeud dans l'arbre - */ - public void selectNode(JAXXContext context, String path) { - NavigationTreeNode node = findNode(context, path); - if (log.isDebugEnabled()) { - log.debug(path + " :: " + node); - } - if (node != null) { - selectNode(context, node); - } - } - - /** - * Sélection d'un noeud dans l'arbre de navigation. - * - * @param context le contexte applicatif - * @param node le noeud à sélectionner dans l'arbre - */ - public void selectNode(JAXXContext context, NavigationTreeNode node) { - - - NavigationModel navigationModel = getSafeModel(context); - if (log.isDebugEnabled()) { - log.debug(node); - } - TreePath path = new TreePath(navigationModel.getPathToRoot(node)); - JTree tree = getTree(context); - if (tree == null){ - // FIXME : Refactor in other helper ? - // If its JXTreeTable - JXTreeTable treeTable = getSafeTreeTable(context); - treeTable.getTreeSelectionModel().setSelectionPath(path); - treeTable.scrollPathToVisible(path); - return; - } - tree.setSelectionPath(path); - tree.scrollPathToVisible(path); - } - - /** - * Sélection du parent du noeud selectionne dans l'arbre de navigation. - * - * @param context le contexte applicatif - */ - public void gotoParentNode(JAXXContext context) { - - NavigationTreeNode node = getSelectedNode(context); - - if (node == null) { - // pas de noeud selectionne - throw new NullPointerException("no selected node in context"); - } - node = node.getParent(); - - selectNode(context, node); - } - - /** - * Obtain the first ancestor with the matching internalClass - * - * @param current the node to test - * @param beanClass the type of the internal class to seek of - * @return the first ancestor node with the matching class or - * {@code null} if not found - */ - public NavigationTreeNode getParentNode(NavigationTreeNode current, - Class<?> beanClass) { - if (current == null) { - // ancestor not found - return null; - } - if (beanClass.isAssignableFrom(current.getInternalClass())) { - // matching node - return current; - } - // try in the parent of node - return getParentNode(current.getParent(), beanClass); - } - - /** - * Sélection d'un fils du noeud selectionne dans l'arbre de navigation. - * - * @param context le contexte applicatif - * @param childIndex index du fils a selectionner - */ - public void gotoChildNode(JAXXContext context, int childIndex) { - - NavigationTreeNode node = getSelectedNode(context); - - if (node == null) { - // pas de noeud selectionne - throw new NullPointerException("no selected node in context"); - } - node = node.getChildAt(childIndex); - - selectNode(context, node); - } - - /** - * Demande une opération de repaint sur un noeud de l'arbre de navigation. - * - * <b>Note:</b> La descendance du noeud n'est pas repainte. - * - * @param context le contexte applicatif - * @param node le noeud à repaindre - */ - public void repaintNode(JAXXContext context, NavigationTreeNode node) { - repaintNode(context, node, false); - } - - /** - * Demande une opération de repaint sur un noeud de l'arbre de navigation. - * - * <b>Note:</b> La descendance du noeud est repainte si le paramètre - * <code>deep</code> est à <code>true</code>. - * - * @param context le contexte applicatif - * @param node le noeud à repaindre - * @param deep un flag pour activer la repainte de la descendance du noeud - */ - public void repaintNode(JAXXContext context, NavigationTreeNode node, - boolean deep) { - NavigationModel navigationModel = getSafeModel(context); - if (log.isDebugEnabled()) { - log.debug(node); - } - navigationModel.nodeChanged(node); - if (deep) { - // repaint childs nodes - //todo we should only repaint necessary nodes ? - Enumeration<?> e = node.children(); - while (e.hasMoreElements()) { - NavigationTreeNode child = (NavigationTreeNode) e.nextElement(); - repaintNode(context, child, true); - } - } - } - - /** - * @deprecated please use {@link #getSafeModel(JAXXContext)}, will be - * remove soon - * @param context where to find - * @return the tree model - * @throws NullPointerException if model is null - */ - @Deprecated - public NavigationTreeModel getSafeTreeModel(JAXXContext context) - throws NullPointerException { - NavigationModel model = getSafeModel(context); - if (model instanceof NavigationTreeModel){ - return (NavigationTreeModel) model; - } - return null; - } - - public NavigationModel getSafeModel(JAXXContext context) - throws NullPointerException { - NavigationModel model = getModel(context); - if (model == null) { - throw new NullPointerException("could not find tree model " + - "with key " + getModelContextEntry() + " in context " + - context); - } - return model; - } - - public JTree getSafeTree(JAXXContext context) throws NullPointerException { - JTree tree = getTree(context); - if (tree == null) { - throw new NullPointerException("could not find tree with key " + - getTreeContextEntry() + " in context " + context); - } - return tree; - } - - public JXTreeTable getSafeTreeTable(JAXXContext context) - throws NullPointerException { - JXTreeTable treeTable = getTreeTable(context); - if (treeTable == null) { - throw new NullPointerException("could not find tree with key " + - getTreeTableContextEntry() + " in context " + context); - } - return treeTable; - } } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -21,16 +21,7 @@ package jaxx.runtime.swing.navigation; import jaxx.runtime.JAXXContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeNode; -import java.util.Enumeration; -import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * Model of the tree used for a navigation tree. * <p/> @@ -39,209 +30,9 @@ * @author chemit * @since 1.7.2 */ -public class NavigationTreeModel extends DefaultTreeModel implements - NavigationModel{ +public class NavigationTreeModel extends GenericNavigationTreeModel<NavigationTreeNode> { - static private final long serialVersionUID = 1L; - /** - * Logger - */ - static private final Log log = LogFactory.getLog(NavigationTreeModel.class); - /** - * The path separator used to build the {@link NavigationTreeNode#fullPath}. - * - * @see NavigationTreeNode#getNodePath() - * @see NavigationTreeNode#getFullPath() - */ - protected final String pathSeparator; - /** - * Context to retrieve beans - */ - private JAXXContext context; - public NavigationTreeModel(String pathSeparator, JAXXContext context) { - super(null); - this.pathSeparator = pathSeparator; - this.context = context; + super(pathSeparator, context); } - - /** - * @see NavigationModel#getRoot() - */ - @Override - public NavigationTreeNode getRoot() { - return (NavigationTreeNode) super.getRoot(); - } - - /** - * @see NavigationModel#findNode(String) - */ - @Override - public NavigationTreeNode findNode(String path) { - return findNode(getRoot(), path, (Pattern) null); - } - - /** - * @see NavigationModel#findNode(String, String) - */ - @Override - public NavigationTreeNode findNode(String path, String regex) { - return findNode(getRoot(), path, regex); - } - - /** - * @see NavigationModel#findNode(String, Pattern) - */ - @Override - public NavigationTreeNode findNode(String path, Pattern regex) { - return findNode(getRoot(), path, regex); - } - - /** - * @see NavigationModel#findNode(NavigationTreeNode, String) - */ - @Override - public NavigationTreeNode findNode(NavigationTreeNode root, String path) { - return findNode(root, path, (Pattern) null); - } - - /** - * @see NavigationModel#findNode(NavigationTreeNode, String, String) - */ - @Override - public NavigationTreeNode findNode(NavigationTreeNode root, - String path, - String regex) { - return findNode(root, path, - regex == null ? null : Pattern.compile(regex)); - } - - /** - * @see NavigationModel#findNode(NavigationTreeNode, String, Pattern) - */ - @Override - 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); - if (log.isDebugEnabled()) { - log.debug("matching regex " + regex + " : " + path); - } - } - StringTokenizer stk = new StringTokenizer(path, pathSeparator); - NavigationTreeNode result = root; - // pas the first token (matches the root node) - if (root.isRoot() && stk.hasMoreTokens()) { - String rootPath = stk.nextToken(); - if (!rootPath.equals(root.getNodePath())) { - return null; - } - } - while (stk.hasMoreTokens()) { - result = result.getChild(stk.nextToken()); - } - return result; - } - - /** - * @see NavigationModel#getContext() - */ - @Override - public JAXXContext getContext() { - return context; - } - - /** - * @see NavigationModel#getBean(String) - */ - @Override - public Object getBean(String navigationPath) { - Object result; - NavigationTreeNode node = findNode(navigationPath, (Pattern) null); - result = getBean(node); - return result; - } - - /** - * @see NavigationModel#getBean(NavigationTreeNode) - */ - @Override - public Object getBean(NavigationTreeNode node) { - if (node == null) { - return null; - //fixme should throw a NPE exception - //throw new NullPointerException("node can not be null"); - } - return node.getBean(getContext()); - } - - /** - * @see NavigationModel#nodeChanged(TreeNode) - */ - @Override - public void nodeChanged(TreeNode node) { - nodeChanged(node, false); - if (log.isDebugEnabled()) { - log.debug(node); - } - } - - /** - * @see NavigationModel#nodeStructureChanged(TreeNode) - */ - @Override - public void nodeStructureChanged(TreeNode node) { - NavigationTreeNode n = (NavigationTreeNode) node; - //TC-20091004 never launch a deep reload - reload(n, true); - super.nodeStructureChanged(node); - if (log.isDebugEnabled()) { - log.debug(node); - } - } - - /** - * @see NavigationModel#nodeChanged(TreeNode, boolean) - */ - @Override - public void nodeChanged(TreeNode node, boolean deep) { - - NavigationTreeNode n = (NavigationTreeNode) node; - //TC-20091004 never launch a deep clean, since we do a deep nodeChanged. - reload(n, deep); - super.nodeChanged(node); - } - - protected void reload(NavigationTreeNode node) { - reload(node, false); - } - - protected void reload(NavigationTreeNode node, boolean deep) { - if (node == null) { - return; - } - node.reload(getContext()); - - if (deep) { - Enumeration<?> childs = node.children(); - while (childs.hasMoreElements()) { - NavigationTreeNode o = (NavigationTreeNode) childs.nextElement(); - reload(o, true); - } - } - } - - /** - * @see NavigationModel#getPathSeparator() - */ - @Override - public String getPathSeparator() { - return pathSeparator; - } } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -37,229 +37,34 @@ * @author chemit * @since 17.2 */ -public class NavigationTreeModelBuilder implements NavigationModelBuilder{ +public class NavigationTreeModelBuilder extends AbstractNavigationModelBuilder<NavigationTreeNode>{ /** * Logger */ static private final Log log = LogFactory.getLog(NavigationTreeModelBuilder.class); - /** - * The model dealed by the builder. - * - * <b>Note:</b> It is a good idea to keep only one instance of the model. - * If reset is required, should empty the model but not reinstanciate it. - */ - protected NavigationTreeModel model; - /** - * default ui class to use if node does not define an ui class - */ - protected Class<? extends JAXXObject> defaultUIClass; - /** - * [optional] default action class - */ - protected Class<? extends JAXXAction> defaultUIHandlerClass; public NavigationTreeModelBuilder(String pathSeparator, JAXXContext context, Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass) { this(defaultUIClass, defaultUIHandlerClass, new NavigationTreeModel(pathSeparator, context)); } public NavigationTreeModelBuilder(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, NavigationTreeModel model) { - this.defaultUIClass = defaultUIClass; - this.defaultUIHandlerClass = defaultUIHandlerClass; - this.model = model; + super(defaultUIClass, defaultUIHandlerClass, model); } - public NavigationTreeModel getModel() { - return model; + @Override + public NavigationTreeNode createNavigationTreeNode(String pathSeparator, String contextName, JAXXContextEntryDef<?> jaxxContextEntryDef, String jaxxContextEntryPath) { + return new NavigationTreeNode(pathSeparator, contextName, jaxxContextEntryDef, jaxxContextEntryPath); } - public NavigationTreeNode buildEmptyRoot(JAXXContextEntryDef<?> entryDef, String contextName) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, entryDef, null); - addI18nNodeRenderer(node, ""); - return addChildNode(null, node); + // TODO : to remove + /** + * @deprecated please use NavigationModel for return type + * @return the tree model + */ + @Override + @Deprecated + public NavigationTreeModel getModel() { + return (NavigationTreeModel)super.getModel(); } - - public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, - JAXXContextEntryDef<?> entryDef, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, entryDef, entryPath); - addI18nNodeRenderer(node, libelle); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, - JAXXContextEntryDef<?> entryDef, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, entryDef); - // TODO : Must be : NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, null, entryDef); ??? - addI18nNodeRenderer(node, libelle); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, entryPath); - addI18nNodeRenderer(node, libelle); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, - JAXXContextEntryDef<?> entryDef, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, entryDef, entryPath); - addDecoratorNodeRenderer(node, decorator); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, - JAXXContextEntryDef<?> entryDef, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, entryDef); - addDecoratorNodeRenderer(node, decorator); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeNode node = new NavigationTreeNode(model.pathSeparator, contextName, null, entryPath); - addDecoratorNodeRenderer(node, decorator); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - protected NavigationTreeNode addChildNode(NavigationTreeNode parentNode, NavigationTreeNode node) { - - if (node.getUIClass() == null) { - // no ui is associated with this node, use the default one - node.setUIClass(defaultUIClass); - } - - if (node.getUIHandlerClass() == null) { - // no ui handler associated with this node, use the default one - node.setUIHandlerClass(defaultUIHandlerClass); - } - if (parentNode == null) { - model.setRoot(node); - } else { - parentNode.add(node); - } - model.nodeStructureChanged(parentNode); - return node; - } - - public NavigationTreeNode removeChildNode(NavigationTreeNode node) { - NavigationTreeNode parentNode = node.getParent(); - model.removeNodeFromParent(node); - return parentNode; - } - - public void addI18nNodeRenderer(NavigationTreeNode node, String libelle) { - node.setRenderer(new NavigationTreeNodeRendererI18nImpl(libelle)); - } - - public void addDecoratorNodeRenderer(NavigationTreeNode node, Decorator<?> decorator) { - node.setRenderer(new NavigationTreeNodeRendererDecoratorImpl(decorator)); - } - - public void addNodeJaxxClasses( - NavigationTreeNode node, - Class<? extends JAXXObject> uIClass, - Class<? extends JAXXAction> uIHandlerClass) { - node.setUIClass(uIClass); - node.setUIHandlerClass(uIHandlerClass); - } - - public void printModel(NavigationTreeNode node) { - if (node == null) { - return; - } - log.info("node " + node.getFullPath() + ", jxpath: " + node.getJaxxContextEntryPath() + ", entryContextDef: " + node.getJaxxContextEntryDef()); - if (log.isDebugEnabled()) { - log.debug("node userObject" + node.getUserObject()); - log.debug("value from node " + node.getBean(getModel().getContext())); - log.debug("value from model " + getModel().getBean(node)); - } - Enumeration<?> children = node.children(); - while (children.hasMoreElements()) { - printModel((NavigationTreeNode) children.nextElement()); - } - } - - public static abstract class ChildBuilder<O> { - - protected NavigationTreeModelBuilder builder; - - protected ChildBuilder(NavigationTreeModelBuilder builder) { - this.builder = builder; - } - - protected abstract void init(Class<? extends O> klass); - - protected abstract Decorator<? extends O> getDecorator(O child); - - protected abstract String getJXPath(O child); - - protected abstract String getNavigationPath(O child); - - public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, java.util.Collection<? extends O> beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { - - if (beans == null || beans.isEmpty()) { - // no bean to treate - return; - } - - init(klass); - - NavigationTreeNode node; - - for (O o : beans) { - node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); - if (cacheValues) { - // cache the bean value to improve performance - node.setBean(o); - } - } - } - - public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, O[] beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { - - if (beans == null || beans.length == 0) { - // no bean to treate - return; - } - - init(klass); - - NavigationTreeNode node; - - for (O o : beans) { - node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); - if (cacheValues) { - // cache the bean value to improve performance - node.setBean(o); - } - } - } - } } Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModel.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModel.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModel.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -46,7 +46,7 @@ * @author sletellier * @since 2.0.0 */ -public class NavigationTreeTableModel extends DefaultTreeTableModel implements NavigationModel { +public class NavigationTreeTableModel extends DefaultTreeTableModel implements NavigationModel<NavigationTreeTableNode> { static private final long serialVersionUID = 1L; @@ -80,10 +80,12 @@ /** * @see NavigationModel#getRoot() */ + @Override public NavigationTreeTableNode getRoot() { return (NavigationTreeTableNode) super.root; } + @Override public TreeNode[] getPathToRoot(TreeNode aNode) { if (aNode == null){ return null; @@ -92,6 +94,7 @@ } + @Override public void setRoot(NavigationTreeTableNode root) { this.root = root; getModelSupport().fireNewRoot(); @@ -102,7 +105,8 @@ * nodesWereRemoved to create the appropriate event. This is the preferred * way to remove a node as it handles the event creation for you. */ - public void removeNodeFromParent(NavigationTreeNode node) { + @Override + public void removeNodeFromParent(MutableTreeNode node) { NavigationTreeTableNode parent = (NavigationTreeTableNode)node.getParent(); if (parent == null) { @@ -119,42 +123,48 @@ /** * @see NavigationModel#findNode(String) */ - public NavigationTreeNode findNode(String path) { + @Override + public NavigationTreeTableNode findNode(String path) { return findNode(getRoot(), path, (Pattern) null); } /** * @see NavigationModel#findNode(String, String) */ - public NavigationTreeNode findNode(String path, String regex) { + @Override + public NavigationTreeTableNode findNode(String path, String regex) { return findNode(getRoot(), path, regex); } /** * @see NavigationModel#findNode(String, Pattern) */ - public NavigationTreeNode findNode(String path, Pattern regex) { + @Override + public NavigationTreeTableNode findNode(String path, Pattern regex) { return findNode(getRoot(), path, regex); } /** * @see NavigationModel#findNode(NavigationTreeNode, String) */ - public NavigationTreeNode findNode(NavigationTreeNode root, String path) { + @Override + public NavigationTreeTableNode findNode(NavigationTreeTableNode root, String path) { return findNode(root, path, (Pattern) null); } /** * @see NavigationModel#findNode(NavigationTreeNode, String, String) */ - public NavigationTreeNode findNode(NavigationTreeNode root, String path, String regex) { + @Override + public NavigationTreeTableNode findNode(NavigationTreeTableNode root, String path, String regex) { return findNode(root, path, regex == null ? null : Pattern.compile(regex)); } /** * @see NavigationModel#findNode(NavigationTreeNode, String, Pattern) */ - public NavigationTreeNode findNode(NavigationTreeNode root, String path, Pattern regex) { + @Override + public NavigationTreeTableNode findNode(NavigationTreeTableNode root, String path, Pattern regex) { if (regex != null) { Matcher matcher = regex.matcher(path); if (!matcher.matches() || matcher.groupCount() < 1) { @@ -167,7 +177,7 @@ } } StringTokenizer stk = new StringTokenizer(path, pathSeparator); - NavigationTreeNode result = root; + NavigationTreeTableNode result = root; // pas the first token (matches the root node) if (root.isRoot() && stk.hasMoreTokens()) { String rootPath = stk.nextToken(); @@ -191,9 +201,10 @@ /** * @see NavigationModel#getBean(String) */ + @Override public Object getBean(String navigationPath) { Object result; - NavigationTreeNode node = findNode(navigationPath, (Pattern) null); + NavigationTreeTableNode node = findNode(navigationPath, (Pattern) null); result = getBean(node); return result; } @@ -201,7 +212,8 @@ /** * @see NavigationModel#getBean(NavigationTreeNode) */ - public Object getBean(NavigationTreeNode node) { + @Override + public Object getBean(NavigationTreeTableNode node) { if (node == null) { return null; //fixme should throw a NPE exception Deleted: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModelBuilder.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModelBuilder.java 2010-03-24 16:59:37 UTC (rev 1806) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeTableModelBuilder.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -1,264 +0,0 @@ -/* - * *##% - * JAXX Runtime - * Copyright (C) 2008 - 2009 CodeLutin - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * ##%* - */ -package jaxx.runtime.swing.navigation; - -import jaxx.runtime.JAXXAction; -import jaxx.runtime.JAXXContext; -import jaxx.runtime.JAXXObject; -import jaxx.runtime.context.JAXXContextEntryDef; -import jaxx.runtime.decorator.Decorator; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Enumeration; - -/** - * This object is design to build a {@link NavigationTreeTableModel}. - * - * @see NavigationModelBuilder - * - * @author sletellier - * @since 2.0.0 - */ -public abstract class NavigationTreeTableModelBuilder implements NavigationModelBuilder{ - - /** - * Logger - */ - static private final Log log = LogFactory.getLog(NavigationTreeModelBuilder.class); - /** - * The model dealed by the builder. - * - * <b>Note:</b> It is a good idea to keep only one instance of the model. - * If reset is required, should empty the model but not reinstanciate it. - */ - protected NavigationTreeTableModel model; - /** - * default ui class to use if node does not define an ui class - */ - protected Class<? extends JAXXObject> defaultUIClass; - /** - * [optional] default action class - */ - protected Class<? extends JAXXAction> defaultUIHandlerClass; - - public NavigationTreeTableModelBuilder(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, NavigationTreeTableModel model) { - this.defaultUIClass = defaultUIClass; - this.defaultUIHandlerClass = defaultUIHandlerClass; - this.model = model; - } - - public NavigationTreeTableModel getModel() { - return model; - } - - public NavigationTreeNode buildEmptyRoot(JAXXContextEntryDef<?> entryDef, String contextName) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, entryDef, null); - addI18nNodeRenderer(node, ""); - return addChildNode(null, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, - JAXXContextEntryDef<?> entryDef, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, entryDef, entryPath); - addI18nNodeRenderer(node, libelle); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, - JAXXContextEntryDef<?> entryDef, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, entryDef, null); - addI18nNodeRenderer(node, libelle); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, null, entryPath); - addI18nNodeRenderer(node, libelle); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, - JAXXContextEntryDef<?> entryDef, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, entryDef, entryPath); - addDecoratorNodeRenderer(node, decorator); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, - JAXXContextEntryDef<?> entryDef, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, entryDef, null); - addDecoratorNodeRenderer(node, decorator); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, - String entryPath, - String contextName, - Class<? extends JAXXObject> uiClass, - Class<? extends JAXXAction> actionClass) { - NavigationTreeTableNode node = createNavigationTreeTableNode(model.pathSeparator, contextName, null, entryPath); - addDecoratorNodeRenderer(node, decorator); - addNodeJaxxClasses(node, uiClass, actionClass); - return addChildNode(parentNode, node); - } - - protected NavigationTreeNode addChildNode(NavigationTreeNode parentNode, NavigationTreeTableNode node) { - - if (node.getUIClass() == null) { - // no ui is associated with this node, use the default one - node.setUIClass(defaultUIClass); - } - - if (node.getUIHandlerClass() == null) { - // no ui handler associated with this node, use the default one - node.setUIHandlerClass(defaultUIHandlerClass); - } - if (parentNode == null) { - model.setRoot(node); - } else { - parentNode.add(node); - } - model.nodeStructureChanged(node); - return node; - } - - public NavigationTreeNode removeChildNode(NavigationTreeNode node) { - NavigationTreeNode parentNode = node.getParent(); - model.removeNodeFromParent(node); - return parentNode; - } - - public void addI18nNodeRenderer(NavigationTreeNode node, String libelle) { - node.setRenderer(new NavigationTreeNodeRendererI18nImpl(libelle)); - } - - public void addDecoratorNodeRenderer(NavigationTreeNode node, Decorator<?> decorator) { - node.setRenderer(new NavigationTreeNodeRendererDecoratorImpl(decorator)); - } - - public void addNodeJaxxClasses( - NavigationTreeNode node, - Class<? extends JAXXObject> uIClass, - Class<? extends JAXXAction> uIHandlerClass) { - node.setUIClass(uIClass); - node.setUIHandlerClass(uIHandlerClass); - } - - public void printModel(NavigationTreeNode node) { - if (node == null) { - return; - } - log.info("node " + node.getFullPath() + ", jxpath: " + node.getJaxxContextEntryPath() + ", entryContextDef: " + node.getJaxxContextEntryDef()); - if (log.isDebugEnabled()) { - log.debug("node userObject" + node.getUserObject()); - log.debug("value from node " + node.getBean(getModel().getContext())); - log.debug("value from model " + getModel().getBean(node)); - } - Enumeration<?> children = node.children(); - while (children.hasMoreElements()) { - printModel((NavigationTreeNode) children.nextElement()); - } - } - - // To create your own instance of NavigationTreeTableNode - public abstract NavigationTreeTableNode createNavigationTreeTableNode(String pathSeparator, String contextName, JAXXContextEntryDef<?> jaxxContextEntryDef, String jaxxContextEntryPath); - - public static abstract class ChildBuilder<O> { - - protected NavigationTreeModelBuilder builder; - - protected ChildBuilder(NavigationTreeModelBuilder builder) { - this.builder = builder; - } - - protected abstract void init(Class<? extends O> klass); - - protected abstract Decorator<? extends O> getDecorator(O child); - - protected abstract String getJXPath(O child); - - protected abstract String getNavigationPath(O child); - - public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, java.util.Collection<? extends O> beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { - - if (beans == null || beans.isEmpty()) { - // no bean to treate - return; - } - - init(klass); - - NavigationTreeNode node; - - for (O o : beans) { - node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); - if (cacheValues) { - // cache the bean value to improve performance - node.setBean(o); - } - } - } - - public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, O[] beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { - - if (beans == null || beans.length == 0) { - // no bean to treate - return; - } - - init(klass); - - NavigationTreeNode node; - - for (O o : beans) { - node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); - if (cacheValues) { - // cache the bean value to improve performance - node.setBean(o); - } - } - } - } -} Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeModelBuilder.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeModelBuilder.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeModelBuilder.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -0,0 +1,52 @@ +/* + * *##% + * JAXX Runtime + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.context.JAXXContextEntryDef; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This object is design to build a {@link NavigationTreeModel} with sorted nodes {@link SortedNavigationTreeNode} . + * + * @see NavigationModelBuilder + * + * @author sletellier + * @since 2.0.1 + */ +public class SortedNavigationTreeModelBuilder extends AbstractNavigationModelBuilder<SortedNavigationTreeNode> { + + /** + * Logger + */ + static private final Log log = LogFactory.getLog(SortedNavigationTreeModelBuilder.class); + + public SortedNavigationTreeModelBuilder(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, NavigationModel<SortedNavigationTreeNode> navigationModel) { + super(defaultUIClass, defaultUIHandlerClass, navigationModel); + } + + @Override + public SortedNavigationTreeNode createNavigationTreeNode(String pathSeparator, String contextName, JAXXContextEntryDef<?> jaxxContextEntryDef, String jaxxContextEntryPath) { + return new SortedNavigationTreeNode(pathSeparator, contextName, jaxxContextEntryDef, jaxxContextEntryPath); + } +} Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeNode.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeNode.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/SortedNavigationTreeNode.java 2010-03-25 13:20:44 UTC (rev 1807) @@ -0,0 +1,129 @@ +/* + * *##% + * JAXX Runtime + * Copyright (C) 2008 - 2009 CodeLutin + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXContext; +import jaxx.runtime.context.JAXXContextEntryDef; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.tree.MutableTreeNode; +import java.util.*; + +/** + * Sprted node + * + * @see NavigationTreeNode + * + * @author sletellier + * @since 2.0.1 + */ +public class SortedNavigationTreeNode extends NavigationTreeNode { + + /** + * Logger + */ + static private final Log log = LogFactory.getLog(SortedNavigationTreeNode.class); + + @Override + public SortedNavigationTreeNode getChildAt(int index) { + return (SortedNavigationTreeNode) super.getChildAt(index); + } + + @Override + public SortedNavigationTreeNode getParent() { + return (SortedNavigationTreeNode) super.getParent(); + } + + @Override + public void add(MutableTreeNode newChild) { + + List<SortedNavigationTreeNode> children = Collections.list(children()); + + if (children.isEmpty()){ + insert(newChild, 0); + return; + } + + SortedNavigationTreeNode newNode = (SortedNavigationTreeNode) newChild; + + children.add(newNode); + + Collections.sort(children, rendererDecorator); + int index = children.indexOf(newChild); + + log.info("Insert node : " + newNode.getRenderer().toString() + " in " + index + " of parent " + this.getRenderer().toString()); + + insert(newChild, index); + } + + + public SortedNavigationTreeNode(String pathSeparator, String navigationPath, Object jaxxContextEntryDef) { + super(pathSeparator, navigationPath, jaxxContextEntryDef); +// sort(); + } + + public SortedNavigationTreeNode(String pathSeparator, String navigationPath, JAXXContextEntryDef<?> jaxxContextEntryDef, String jaxxContextEntryPath) { + super(pathSeparator, navigationPath, jaxxContextEntryDef, jaxxContextEntryPath); +// sort(); + } + +// public void sort() { +// List<SortedNavigationTreeNode> children = Collections.list(children()); +// +// if (children.isEmpty() || children.size() == 1){ +// return; +// } +// +// Collections.sort(children, rendererDecorator); +// +// if (children == null){ +// return; +// } +// +// Iterator<SortedNavigationTreeNode> childrenIterator = children.iterator(); +// if (childrenIterator != null){ +// removeAllChildren(); +// +// if (log.isDebugEnabled()){ +// log.debug("Adding " + children.size() + " children to parent " + getBean()); +// } +// while (childrenIterator.hasNext()) { +// SortedNavigationTreeNode childNode = childrenIterator.next(); +// childNode.sort(); +// add(childNode); +// } +// } +// } + + final Comparator rendererDecorator = new Comparator() { + @Override + public int compare(Object o1, Object o2) { + try { + String label1 = ((NavigationTreeNode)o1).getRenderer().toString(); + String label2 = ((NavigationTreeNode)o2).getRenderer().toString(); + return label1.compareToIgnoreCase(label2); + } catch (Exception eee) { + return 0; + } + } + }; +}
participants (1)
-
sletellier@users.nuiton.org