You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2009/04/16 10:14:23 UTC

svn commit: r765504 [1/2] - in /myfaces/tobago/trunk: core/src/main/java/org/apache/myfaces/tobago/component/ core/src/main/java/org/apache/myfaces/tobago/model/ core/src/main/java/org/apache/myfaces/tobago/taglib/component/ core/src/main/java/org/apac...

Author: lofwyr
Date: Thu Apr 16 08:14:22 2009
New Revision: 765504

URL: http://svn.apache.org/viewvc?rev=765504&view=rev
Log:
TOBAGO-377: Working on 
* state 
* event listener
* remove old stuff
* using both: boolean and java.lang.Boolean in TagDeclaration

Added:
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/DefaultMutableTreeNodeAnalyser.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/Node.java
      - copied, changed from r722373, myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeAnalyser.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java   (contents, props changed)
      - copied, changed from r722373, myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java
    myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodePathUnitTest.java
    myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java   (contents, props changed)
      - copied, changed from r722373, myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java
    myfaces/tobago/trunk/example/demo/src/main/webapp/reference/tree/tree-state.xhtml   (contents, props changed)
      - copied, changed from r722373, myfaces/tobago/trunk/example/demo/src/main/webapp/reference/tree/tree-normal.xhtml
    myfaces/tobago/trunk/tobago-jsf-compat/src/main/java/org/apache/myfaces/tobago/event/MethodExpressionTreeExpansionListener.java   (contents, props changed)
      - copied, changed from r713180, myfaces/tobago/trunk/tobago-jsf-compat/src/main/java/org/apache/myfaces/tobago/event/MethodExpressionStateChangeListener.java
    myfaces/tobago/trunk/tobago-jsf-compat/src/main/java/org/apache/myfaces/tobago/event/TreeExpansionEvent.java   (contents, props changed)
      - copied, changed from r713180, myfaces/tobago/trunk/tobago-jsf-compat/src/main/java/org/apache/myfaces/tobago/event/TabChangeEvent.java
    myfaces/tobago/trunk/tobago-jsf-compat/src/main/java/org/apache/myfaces/tobago/event/TreeExpansionListener.java
Removed:
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java
    myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/TreeModelUnitTest.java
    myfaces/tobago/trunk/theme/standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tree.js
Modified:
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITree.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeData.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeNode.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/GridConstraintsTagDeclaration.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeNodeTagDeclaration.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeTagDeclaration.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsDisabled.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsImmediateCommand.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsReadonly.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRendered.java
    myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRequired.java
    myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java
    myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/Node.java
    myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/TreeController.java
    myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.jsp
    myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.xhtml
    myfaces/tobago/trunk/example/demo/src/main/webapp/reference/tree/tree-normal.xhtml
    myfaces/tobago/trunk/theme/scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java
    myfaces/tobago/trunk/theme/scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/mozilla/style/style.css
    myfaces/tobago/trunk/theme/scarborough/src/main/resources/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/style/style.css
    myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/java/org/apache/myfaces/tobago/apt/generate/PropertyInfo.java
    myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component1.1.stg
    myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/component1.2.stg
    myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/tag1.1.stg
    myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/tag1.2.stg
    myfaces/tobago/trunk/tobago-tool/tobago-tool-apt/src/main/resources/org/apache/myfaces/tobago/apt/tagAbstract1.1.stg

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITree.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITree.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITree.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITree.java Thu Apr 16 08:14:22 2009
@@ -28,32 +28,20 @@
 import javax.faces.validator.Validator;
 import javax.faces.validator.ValidatorException;
 import java.io.IOException;
-import java.io.Serializable;
 import java.util.Iterator;
 import java.util.List;
 
 public abstract class AbstractUITree extends UIInput implements NamingContainer {
 
-  public static final String COMPONENT_TYPE = "org.apache.myfaces.tobago.Tree";
   public static final String MESSAGE_NOT_LEAF = "tobago.tree.MESSAGE_NOT_LEAF";
 
   public static final String SEP = "-";
 
-  public static final String TREE_STATE = SEP + "treeState";
   public static final String SELECT_STATE = SEP + "selectState";
   public static final String MARKER = SEP + "marker";
 
-  public static final String PARAMETER_TREE_NODE_ID = "treeNodeId";
-
- /* private Boolean showJunctions = true;
-  private Boolean showIcons = true;
-  private Boolean showRoot = true;
-  private Boolean showRootJunction = true;
-
-  private String mode;*/
   private MixedTreeModel model;
 
-
   public UIComponent getRoot() {
     // find the UITreeNode in the childen.
     for (UIComponent child : (List<UIComponent>) getChildren()) {
@@ -67,22 +55,24 @@
     return null;
   }
 
-  public void encodeEnd(FacesContext context) throws IOException {
+  public void encodeEnd(FacesContext facesContext) throws IOException {
     model = new MixedTreeModel();
-
-    buildModel();
-    super.encodeEnd(context);
-  }
-
-  private void buildModel() {
     for (Object child : getChildren()) {
       if (child instanceof TreeModelBuilder) {
         TreeModelBuilder builder = (TreeModelBuilder) child;
-        builder.buildBegin(model);
-        builder.buildChildren(model);
-        builder.buildEnd(model);
+        builder.buildTreeModelBegin(facesContext, model);
+        builder.buildTreeModelChildren(facesContext, model);
+        builder.buildTreeModelEnd(facesContext, model);
       }
     }
+
+    super.encodeEnd(facesContext);
+
+    model = null;
+  }
+
+  public MixedTreeModel getModel() {
+    return model;
   }
 
   public boolean getRendersChildren() {
@@ -175,108 +165,6 @@
   public abstract boolean isShowJunctions();
 
   public abstract boolean isShowRootJunction();
-   
-  public abstract boolean isShowRoot();
-
-  /*public Object saveState(FacesContext context) {
-   Object[] state = new Object[6];
-   state[0] = super.saveState(context);
-   state[1] = showJunctions;
-   state[2] = showIcons;
-   state[3] = showRoot;
-   state[4] = showRootJunction;
-   state[5] = mode;
-   return state;
- }
-
- public void restoreState(FacesContext context, Object state) {
-   Object[] values = (Object[]) state;
-   super.restoreState(context, values[0]);
-   showJunctions = (Boolean) values[1];
-   showIcons = (Boolean) values[2];
-   showRoot = (Boolean) values[3];
-   showRootJunction = (Boolean) values[4];
-   mode = (String) values[5];
- }
-
- public boolean isShowJunctions() {
-   if (showJunctions != null) {
-     return (showJunctions);
-   }
-   ValueBinding vb = getValueBinding(SHOW_JUNCTIONS);
-   if (vb != null) {
-     return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
-   } else {
-     return (this.showJunctions);
-   }
- }
-
- public void setShowJunctions(boolean showJunctions) {
-   this.showJunctions = showJunctions;
- }
-
- public boolean isShowIcons() {
-   if (showIcons != null) {
-     return (showIcons);
-   }
-   ValueBinding vb = getValueBinding(SHOW_ICONS);
-   if (vb != null) {
-     return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
-   } else {
-     return (this.showIcons);
-   }
- }
-
- public void setShowIcons(boolean showIcons) {
-   this.showIcons = showIcons;
- }
-
- public boolean isShowRoot() {
-   if (showRoot != null) {
-     return (showRoot);
-   }
-   ValueBinding vb = getValueBinding(SHOW_ROOT);
-   if (vb != null) {
-     return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
-   } else {
-     return (this.showRoot);
-   }
- }
-
- public void setShowRoot(boolean showRoot) {
-   this.showRoot = showRoot;
-
- }
-
- public boolean isShowRootJunction() {
-   if (showRootJunction != null) {
-     return (showRootJunction);
-   }
-   ValueBinding vb = getValueBinding(SHOW_ROOT_JUNCTION);
-   if (vb != null) {
-     return (!Boolean.FALSE.equals(vb.getValue(getFacesContext())));
-   } else {
-     return (this.showRootJunction);
-   }
- }
-
- public void setShowRootJunction(boolean showRootJunction) {
-   this.showRootJunction = showRootJunction;
- } */
-
-  public static class Command implements Serializable {
-    private String command;
-
-    public Command(String command) {
-      this.command = command;
-    }
 
-    public String getCommand() {
-      return command;
-    }
-  }
-
-  public MixedTreeModel getModel() {
-    return model;
-  }
+  public abstract boolean isShowRoot();
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeData.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeData.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeData.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeData.java Thu Apr 16 08:14:22 2009
@@ -17,11 +17,12 @@
  * limitations under the License.
  */
 
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.tobago.model.MixedTreeModel;
-import org.apache.myfaces.tobago.model.TreeModel;
+import org.apache.myfaces.tobago.model.Node;
+import org.apache.myfaces.tobago.model.TreePath;
 
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
@@ -32,6 +33,7 @@
 import javax.faces.event.PhaseId;
 import javax.swing.tree.DefaultMutableTreeNode;
 import java.io.IOException;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -44,47 +46,40 @@
 
   private String var;
 
-  private TreeModel treeModel;
-
   private DefaultMutableTreeNode currentNode;
 
-  private String currentNodeId;
-
-  private String currentParentNodeId;
-
-  private String pathIndex;
+  private TreePath rowIndex;
 
   // XXX hack: fix this if there is a Listener
   private Object marker;
 
-//  @Override public void processDecodes(FacesContext facesContext) {
-//    LOG.info("processDecodes for nodes");
-//    LOG.warn("todo"); // todo
-//    super.processDecodes(facesContext);
-//  }
-
   // Holds for each node the states of the child components of this UITreeData.
-  private Map<String, Object> pathStates = new HashMap<String, Object>();
+  private Map<TreePath, Object> pathStates = new HashMap<TreePath, Object>();
 
   @Override
   public void processDecodes(FacesContext facesContext) {
 
-    // todo: does treeModel should be stored in the state?
-    // todo: what is, when the value has been changed since last rendering?
-    treeModel = new TreeModel((DefaultMutableTreeNode) getValue());
-    AbstractUITreeNode node = getTemplateComponent();
-
-    // TODO invoke decode on the children which are not instanceof UITreeNode
-    for (String pathIndex : treeModel.getPathIndexList()) {
-      setPathIndex(pathIndex);
-      node.processDecodes(facesContext);
-
-      // XXX hack: fix this if there is a Listener
-      if (node.isMarked()) {
-        marker = node.getValue();
-      }
+    decodeNodes(facesContext, (DefaultMutableTreeNode) getValue(), new TreePath(0));
+  }
 
-      setPathIndex(null);
+  private void decodeNodes(FacesContext facesContext, DefaultMutableTreeNode node, TreePath position) {
+
+    setRowIndex(facesContext, position);
+    LOG.info("path index (decode) = '" + position + "'");
+    AbstractUITreeNode templateComponent = getTemplateComponent();
+    templateComponent.processDecodes(facesContext);
+    setRowIndex(facesContext, null);
+
+    // XXX hack: fix this if there is a Listener
+    if (templateComponent.isMarked()) {
+      marker = templateComponent.getValue();
+    }
+
+    int index = 0;
+    for (Enumeration e = node.children(); e.hasMoreElements();) {
+      DefaultMutableTreeNode sub = (DefaultMutableTreeNode) e.nextElement();
+      decodeNodes(facesContext, sub, new TreePath(position, index));
+      index++;
     }
   }
 
@@ -93,68 +88,103 @@
 
   }
 
-  public String getPathIndex() {
-    return pathIndex;
+  public TreePath getRowIndex() {
+    return rowIndex;
   }
 
-  public void setPathIndex(String pathIndex) {
+  private void setRowIndex(FacesContext facesContext, TreePath rowIndex) {
 
-    if (StringUtils.equals(this.pathIndex, pathIndex)) {
+    if (ObjectUtils.equals(this.rowIndex, rowIndex)) {
       return; // nothing to do, if already set.
     }
 
-    FacesContext facesContext = FacesContext.getCurrentInstance();
-
     AbstractUITreeNode template = getTemplateComponent();
-    pathStates.put(this.pathIndex, template.saveState(facesContext));
+    pathStates.put(this.rowIndex, template.saveState(facesContext));
     if (LOG.isDebugEnabled()) {
-      LOG.debug("save   " + this.pathIndex + " ex=" + template.isExpanded());
+      LOG.debug("save   " + this.rowIndex + " ex=" + template.isExpanded());
     }
 
     // reset the client id (see spec 3.1.6)
     template.setId(template.getId());
 
-    this.pathIndex = pathIndex;
-    if (pathIndex != null) {
-      currentNode = treeModel.getNode(pathIndex);
+    this.rowIndex = rowIndex;
+    if (rowIndex != null) {
+      DefaultMutableTreeNode model = (DefaultMutableTreeNode) getValue();
+      currentNode = rowIndex.getNode(model);
       facesContext.getExternalContext().getRequestMap().put(var, currentNode);
-      // todo: remove currentNodeId
-      currentNodeId = pathIndex;
-      currentParentNodeId = treeModel.getParentPathIndex(pathIndex);
     } else {
       FacesContext.getCurrentInstance().getExternalContext().getRequestMap().remove(var);
       currentNode = null;
-      currentNodeId = null;
-      currentParentNodeId = null;
     }
 
-    Object state = pathStates.get(this.pathIndex);
+    Object state = pathStates.get(this.rowIndex);
     if (state != null) {
       template.restoreState(facesContext, state);
       if (LOG.isDebugEnabled()) {
-        LOG.debug("restore " + this.pathIndex + " ex=" + template.isExpanded());
+        LOG.debug("restore " + this.rowIndex + " ex=" + template.isExpanded());
       }
     }
+  }
+/*
+  public void buildTreeModel(MixedTreeModel model) {
+    model.beginBuildNodeData(this);
+    // childred are not needed to add here
+    model.endBuildNodeData(this);
+  }
+  */
+
+  public void buildTreeModelBegin(FacesContext facesContext, MixedTreeModel model) {
+    Object data = getValue();
+    if (data instanceof Node) {
+      buildTreeModelNodes(facesContext, model, (Node)data, new TreePath(0));
+    } else if (data instanceof DefaultMutableTreeNode) {
+      buildTreeModelNodes(facesContext, model, (DefaultMutableTreeNode)data, new TreePath(0));
+    }
+  }
 
+  public void buildTreeModelChildren(FacesContext facesContext, MixedTreeModel model) {
   }
 
-  public void buildBegin(MixedTreeModel model) {
-    model.beginBuildNodeData(this);
+  public void buildTreeModelEnd(FacesContext facesContext, MixedTreeModel model) {
   }
 
-  public void buildChildren(MixedTreeModel model) {
-    for (Object child : getChildren()) {
-      if (child instanceof TreeModelBuilder) {
-        TreeModelBuilder builder = (TreeModelBuilder) child;
-        builder.buildBegin(model);
-        builder.buildChildren(model);
-        builder.buildEnd(model);
-      }
+  public void buildTreeModelNodes(
+      FacesContext facesContext, MixedTreeModel model, Node node, TreePath position) {
+
+    setRowIndex(facesContext, position);
+    LOG.info("path index (build) node = '" + position + "'");
+
+    getTemplateComponent().buildTreeModelBegin(facesContext, model);
+
+    int index = 0;
+    for (Node sub : node.getChildren()) {
+      buildTreeModelNodes(facesContext, model, sub, new TreePath(position, index));
+      index++;
     }
+
+    getTemplateComponent().buildTreeModelEnd(facesContext, model);
+
+    setRowIndex(facesContext, null);
   }
 
-  public void buildEnd(MixedTreeModel model) {
-    model.endBuildNodeData(this);
+  public void buildTreeModelNodes(
+      FacesContext facesContext, MixedTreeModel model, DefaultMutableTreeNode node, TreePath position) {
+
+    setRowIndex(facesContext, position);
+    LOG.info("path index (build) dmtn = '" + position + "'");
+
+    getTemplateComponent().buildTreeModelBegin(facesContext, model);
+
+    int index = 0;
+    for (Enumeration e = node.children(); e.hasMoreElements();) {
+      DefaultMutableTreeNode sub = (DefaultMutableTreeNode) e.nextElement();
+      buildTreeModelNodes(facesContext, model, sub, new TreePath(position, index));
+      index++;
+    }
+
+    getTemplateComponent().buildTreeModelEnd(facesContext, model);
+
+    setRowIndex(facesContext, null);
   }
 
   @Override
@@ -163,22 +193,29 @@
 
   @Override
   public void encodeEnd(FacesContext facesContext) throws IOException {
+    encodeNodes(facesContext, (DefaultMutableTreeNode) getValue(), new TreePath(0));
+    super.encodeEnd(facesContext);
+  }
 
-    // todo: does treeModel should be stored in the state?
-    treeModel = new TreeModel((DefaultMutableTreeNode) getValue());
+  private void encodeNodes(FacesContext facesContext, DefaultMutableTreeNode node, TreePath position)
+      throws IOException {
 
-    for (TreeModel.Tag pathIndex : treeModel.getDoublePathIndexList()) {
-      setPathIndex(pathIndex.getName());
-      if (pathIndex.isStart()) {
-        getTemplateComponent().encodeBegin(facesContext);
-      } else {
-        getTemplateComponent().encodeEnd(facesContext);
-      }
-//      RenderUtil.encode(facesContext, getTemplateComponent());
-      setPathIndex(null);
-    }
-
-    super.encodeEnd(facesContext);
+    setRowIndex(facesContext, position);
+    LOG.info("path index (begin)  = '" + position + "'");
+    getTemplateComponent().encodeBegin(facesContext);
+    setRowIndex(facesContext, null);
+
+    int index = 0;
+    for (Enumeration e = node.children(); e.hasMoreElements();) {
+      DefaultMutableTreeNode sub = (DefaultMutableTreeNode) e.nextElement();
+      encodeNodes(facesContext, sub, new TreePath(position, index));
+      index++;
+    }
+
+    setRowIndex(facesContext, position);
+    LOG.info("path index (end)    = '" + position + "'");
+    getTemplateComponent().encodeEnd(facesContext);
+    setRowIndex(facesContext, null);
   }
 
   @Override
@@ -204,10 +241,10 @@
   @Override
   public String getClientId(FacesContext context) {
     String clientId = super.getClientId(context);
-    if (pathIndex == null) {
+    if (rowIndex == null) {
       return clientId;
     }
-    return clientId + NamingContainer.SEPARATOR_CHAR + pathIndex;
+    return clientId + NamingContainer.SEPARATOR_CHAR + rowIndex;
   }
 
   public UIComponent findComponent(String searchId) {
@@ -221,20 +258,21 @@
 
   @Override
   public void queueEvent(FacesEvent event) {
-    super.queueEvent(new FacesEventWrapper(event, getPathIndex(), this));
+    super.queueEvent(new FacesEventWrapper(event, getRowIndex(), this));
   }
 
   @Override
   public void broadcast(FacesEvent event) throws AbortProcessingException {
     if (event instanceof FacesEventWrapper) {
+      FacesContext facesContext = FacesContext.getCurrentInstance();
       FacesEvent originalEvent = ((FacesEventWrapper) event).getWrappedFacesEvent();
-      String eventPathIndex = ((FacesEventWrapper) event).getPathIndex();
-      String currentPathIndex = getPathIndex();
-      setPathIndex(eventPathIndex);
+      TreePath eventPathIndex = ((FacesEventWrapper) event).getRowIndex();
+      TreePath currentPathIndex = getRowIndex();
+      setRowIndex(facesContext, eventPathIndex);
       try {
         originalEvent.getComponent().broadcast(originalEvent);
       } finally {
-        setPathIndex(currentPathIndex);
+        setRowIndex(facesContext, currentPathIndex);
       }
     } else {
       super.broadcast(event);
@@ -272,33 +310,17 @@
     this.currentNode = currentNode;
   }
 
-  public String getCurrentNodeId() {
-    return currentNodeId;
-  }
-
-  public void setCurrentNodeId(String currentNodeId) {
-    this.currentNodeId = currentNodeId;
-  }
-
-  public String getCurrentParentNodeId() {
-    return currentParentNodeId;
-  }
-
-  public void setCurrentParentNodeId(String currentParentNodeId) {
-    this.currentParentNodeId = currentParentNodeId;
-  }
-
   private static class FacesEventWrapper extends FacesEvent {
 
     private static final long serialVersionUID = 1L;
 
     private FacesEvent wrappedFacesEvent;
-    private String pathIndex;
+    private TreePath rowIndex;
 
-    FacesEventWrapper(FacesEvent facesEvent, String pathIndex, AbstractUITreeData redirectComponent) {
+    FacesEventWrapper(FacesEvent facesEvent, TreePath rowIndex, AbstractUITreeData redirectComponent) {
       super(redirectComponent);
       wrappedFacesEvent = facesEvent;
-      this.pathIndex = pathIndex;
+      this.rowIndex = rowIndex;
     }
 
     @Override
@@ -336,8 +358,8 @@
       return wrappedFacesEvent;
     }
 
-    public String getPathIndex() {
-      return pathIndex;
+    public TreePath getRowIndex() {
+      return rowIndex;
     }
   }
 

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeNode.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeNode.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeNode.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/AbstractUITreeNode.java Thu Apr 16 08:14:22 2009
@@ -19,41 +19,157 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.tobago.event.TreeExpansionEvent;
 import org.apache.myfaces.tobago.model.MixedTreeModel;
+import org.apache.myfaces.tobago.model.TreePath;
 
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.MethodBinding;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
 import javax.swing.tree.DefaultMutableTreeNode;
+import java.io.IOException;
+import java.util.List;
 
 public abstract class AbstractUITreeNode extends AbstractUICommand implements SupportsMarkup, TreeModelBuilder {
 
   private static final Log LOG = LogFactory.getLog(AbstractUITreeNode.class);
 
+  private int depth;
+  private boolean folder;
+  private TreePath path;
+  private List<Boolean> junctions;
+  private boolean hasNextSibling;
+
   @Override
   public boolean getRendersChildren() {
     return true;
   }
 
-  public void buildBegin(MixedTreeModel model) {
+  public void buildTreeModelBegin(FacesContext facesContext, MixedTreeModel model) {
     model.beginBuildNode(this);
+    setDepth(computeDepth(this));
+    setFolder(computeFolder());
   }
 
-  public void buildChildren(MixedTreeModel model) {
+  public void buildTreeModelChildren(FacesContext facesContext, MixedTreeModel model) {
     for (Object child : getChildren()) {
       if (child instanceof TreeModelBuilder) {
         TreeModelBuilder builder = (TreeModelBuilder) child;
-        builder.buildBegin(model);
-        builder.buildChildren(model);
-        builder.buildEnd(model);
+        builder.buildTreeModelBegin(facesContext, model);
+        builder.buildTreeModelChildren(facesContext, model);
+        builder.buildTreeModelEnd(facesContext, model);
       }
     }
   }
 
-  public void buildEnd(MixedTreeModel model) {
+  public void buildTreeModelEnd(FacesContext facesContext, MixedTreeModel model) {
     model.endBuildNode(this);
   }
 
   @Override
+  public void encodeBegin(FacesContext context) throws IOException {
+    AbstractUITree tree = findTree();
+    MixedTreeModel mixedModel = tree.getModel();
+    mixedModel.onEncodeBegin();
+    setPath(mixedModel.getPath());
+    setHasNextSibling(computeHasNextSibling());
+    setJunctions(mixedModel.getJunctions());
+    super.encodeBegin(context);
+  }
+
+  @Override
+  public void encodeEnd(FacesContext context) throws IOException {
+    super.encodeEnd(context);
+    AbstractUITree tree = findTree();
+    MixedTreeModel mixedModel = tree.getModel();
+    mixedModel.onEncodeEnd();
+  }
+
+  private int computeDepth(UIComponent node) {
+    int depth = 0;
+    while (node != null) {
+      depth++;
+      if (node instanceof AbstractUITree) {
+        return depth;
+      }
+      if (node instanceof AbstractUITreeData) {
+        Object dataTree = ((AbstractUITreeData) node).getValue();
+        // todo: make independent from impl.
+        if (dataTree instanceof DefaultMutableTreeNode) {
+          return ((DefaultMutableTreeNode) dataTree).getDepth();
+        }
+        LOG.warn("Tree type not supported");
+      }
+      node = node.getParent();
+    }
+    throw new RuntimeException("Not inside of a UITree");
+  }
+
+  private boolean computeFolder() {
+    if (isInData()) {
+      Object value = getValue();
+      // todo: make independent from impl.
+      if (value instanceof DefaultMutableTreeNode) {
+        return !((DefaultMutableTreeNode)value).isLeaf();
+      }
+      LOG.warn("Tree type not supported");
+      return true;
+    } else {
+      return getChildCount() != 0;
+    }
+  }
+
+  private boolean computeHasNextSibling() {
+    if (isInData()) {
+      Object value = getValue();
+      // todo: make independent from impl.
+      if (value instanceof DefaultMutableTreeNode) {
+
+        DefaultMutableTreeNode tree = (DefaultMutableTreeNode) value;
+        if (tree.isRoot()) {
+          return hasSiblingAfter(getParent().getParent(), getParent());
+        } else {
+          return tree.getNextSibling() != null;
+        }
+      }
+      LOG.warn("Tree type not supported");
+      return false;
+    } else {
+      return hasSiblingAfter(getParent(), this);
+    }
+  }
+
+  private boolean hasSiblingAfter(UIComponent parent, UIComponent child) {
+    boolean found = false;
+    for (Object sibling : parent.getChildren()) {
+      if (child.equals(sibling)) {
+        found = true;
+        continue;
+      }
+      if (found) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean isInData() {
+    UIComponent component = this;
+    while (component != null) {
+      if (component instanceof AbstractUITreeData) {
+        return true;
+      } else if (component instanceof AbstractUITree) {
+        return false;
+      }
+      component = component.getParent();
+    }
+    return false;
+  }
+
+  @Override
   public Object getValue() {
     DefaultMutableTreeNode value = (DefaultMutableTreeNode) super.getValue();
     if (value == null) { // XXX: hack!
@@ -68,7 +184,6 @@
   }
 
   public String nodeStateId(FacesContext facesContext) {
-    // this must do the same as nodeStateId() in tree.js
     String clientId = getClientId(facesContext);
     AbstractUITree tree = findTree(this);
     String treeId = tree.getClientId(facesContext);
@@ -89,12 +204,93 @@
     return null;
   }
 
+  @Override
+  public void broadcast(FacesEvent event) throws AbortProcessingException {
+    super.broadcast(event);
+    if (event instanceof TreeExpansionEvent) {
+      invokeMethodBinding(getTreeExpansionListener(), event);
+    }
+  }
+
+  private void invokeMethodBinding(MethodBinding methodBinding, FacesEvent event) {
+    if (methodBinding != null && event != null) {
+      try {
+        methodBinding.invoke(getFacesContext(), new Object[]{event});
+      } catch (EvaluationException e) {
+        Throwable cause = e.getCause();
+        if (cause instanceof AbortProcessingException) {
+          throw (AbortProcessingException) cause;
+        } else {
+          throw e;
+        }
+      }
+    }
+  }
+
+  public void restoreState(FacesContext context, Object componentState) {
+    Object[] values = (Object[]) componentState;
+    super.restoreState(context, values[0]);
+    path = (TreePath) values[1];
+    folder = (Boolean) values[2];
+  }
+
+  public Object saveState(FacesContext context) {
+    Object[] values = new Object[3];
+    values[0] = super.saveState(context);
+    values[1] = path;
+    values[2] = folder;
+    return values;
+  }
+
+  public int getDepth() {
+    return depth;
+  }
+
+  public void setDepth(int depth) {
+    this.depth = depth;
+  }
+
+  public boolean isFolder() {
+    return folder;
+  }
+
+  public void setFolder(boolean folder) {
+    this.folder = folder;
+  }
+
+  public TreePath getPath() {
+    return path;
+  }
+
+  public void setPath(TreePath path) {
+    this.path = path;
+  }
+
+  public List<Boolean> getJunctions() {
+    return junctions;
+  }
+
+  public void setJunctions(List<Boolean> junctions) {
+    this.junctions = junctions;
+  }
+
+  public boolean isHasNextSibling() {
+    return hasNextSibling;
+  }
+
+  public void setHasNextSibling(boolean hasNextSibling) {
+    this.hasNextSibling = hasNextSibling;
+  }
+
+  public abstract MethodBinding getTreeExpansionListener();
+
+  public abstract void setTreeExpansionListener(MethodBinding treeExpansionListener);
 
-  public abstract void setExpanded(boolean expanded);
+  public abstract void setExpanded(Boolean expanded);
 
-  public abstract void setMarked(boolean b);
+  public abstract void setMarked(Boolean b);
 
-  public abstract boolean isMarked();
+  public abstract Boolean isMarked();
 
-  public abstract boolean isExpanded();
+  public abstract Boolean isExpanded();
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/component/TreeModelBuilder.java Thu Apr 16 08:14:22 2009
@@ -19,16 +19,12 @@
 
 import org.apache.myfaces.tobago.model.MixedTreeModel;
 
-/**
- * User: lofwyr
- * Date: 23.04.2007 18:08:08
- */
-public interface TreeModelBuilder {
-
-  void buildBegin(MixedTreeModel model);
+import javax.faces.context.FacesContext;
 
-  void buildChildren(MixedTreeModel model);
+public interface TreeModelBuilder {
 
-  void buildEnd(MixedTreeModel model);
+  void buildTreeModelBegin(FacesContext facesContext, MixedTreeModel model);
+  void buildTreeModelChildren(FacesContext facesContext, MixedTreeModel model);
+  void buildTreeModelEnd(FacesContext facesContext, MixedTreeModel model);
 
 }

Added: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/DefaultMutableTreeNodeAnalyser.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/DefaultMutableTreeNodeAnalyser.java?rev=765504&view=auto
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/DefaultMutableTreeNodeAnalyser.java (added)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/DefaultMutableTreeNodeAnalyser.java Thu Apr 16 08:14:22 2009
@@ -0,0 +1,37 @@
+package org.apache.myfaces.tobago.model;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * User: lofwyr
+ * Date: 04.12.2008
+ */
+public class DefaultMutableTreeNodeAnalyser implements TreeAnalyser {
+
+  private DefaultMutableTreeNode node;
+
+  public DefaultMutableTreeNodeAnalyser(DefaultMutableTreeNode node) {
+    this.node = node;
+  }
+
+  public int computeDepth() {
+    return node.getDepth();
+  }
+}

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java Thu Apr 16 08:14:22 2009
@@ -19,11 +19,9 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.myfaces.tobago.component.AbstractUITreeData;
 import org.apache.myfaces.tobago.component.AbstractUITreeNode;
 import org.apache.myfaces.tobago.component.Attributes;
 
-import javax.swing.tree.DefaultMutableTreeNode;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Stack;
@@ -36,57 +34,31 @@
 
   private static final Log LOG = LogFactory.getLog(MixedTreeModel.class);
 
-  private DefaultMutableTreeNode root;
-  private DefaultMutableTreeNode current;
+  private Node root;
+  private Node current;
   private Integer nextChildIndex;
-  private DefaultMutableTreeNode dataRoot;
-  private boolean isInData;
   private Stack<Boolean> junctions = new Stack<Boolean>();
 
   public void beginBuildNode(AbstractUITreeNode node) {
     if (LOG.isDebugEnabled()) {
       LOG.debug(node.getAttributes().get(Attributes.LABEL));
     }
-    if (!isInData) {
-      DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(node.getAttributes().get(Attributes.LABEL));
-      if (root == null) {
-        root = newNode;
-        current = root;
-      } else {
-        current.add(newNode);
-        current = newNode;
-      }
-    }
-  }
-
-  public void endBuildNode(AbstractUITreeNode node) {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug(node.getAttributes().get(Attributes.LABEL));
-    }
-    if (!isInData) {
-      current = (DefaultMutableTreeNode) current.getParent();
-    }
-  }
-
-  public void beginBuildNodeData(AbstractUITreeData data) {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("var=" + data.getVar());
-    }
-    current = new DefaultMutableTreeNode(data.getValue());
+    Node newNode = new Node();
+    newNode.setLabel((String) node.getAttributes().get(Attributes.LABEL));
     if (root == null) {
-      root = current;
+      root = newNode;
+      current = root;
     } else {
-      root.add(current);
+      current.add(newNode);
+      current = newNode;
     }
-    isInData = true;
   }
 
-  public void endBuildNodeData(AbstractUITreeData data) {
+  public void endBuildNode(AbstractUITreeNode node) {
     if (LOG.isDebugEnabled()) {
-      LOG.debug("var=" + data.getVar());
+      LOG.debug(node.getAttributes().get(Attributes.LABEL));
     }
-    current = (DefaultMutableTreeNode) current.getParent();
-    isInData = false;
+    current = current.getParent();
   }
 
   public void onEncodeBegin() {
@@ -96,12 +68,7 @@
     if (current == null) {
       current = root;
     } else {
-      current = (DefaultMutableTreeNode) current.getChildAt(nextChildIndex);
-    }
-    if (!isInData && current.getUserObject() instanceof DefaultMutableTreeNode) {
-      isInData = true;
-      dataRoot = current;
-      current = (DefaultMutableTreeNode) current.getUserObject();
+      current = current.getChildAt(nextChildIndex);
     }
     nextChildIndex = 0;
 
@@ -112,11 +79,7 @@
     if (LOG.isDebugEnabled()) {
       LOG.debug("current=" + current);
     }
-    if (isInData && current.isRoot()) {
-      current = dataRoot;
-      isInData = false;
-    }
-    DefaultMutableTreeNode parent = (DefaultMutableTreeNode) current.getParent();
+    Node parent = current.getParent();
     if (parent != null) {
       nextChildIndex = parent.getIndex(current) + 1;
       current = parent;
@@ -129,27 +92,7 @@
   }
 
   public boolean hasCurrentNodeNextSibling() {
-    boolean result;
-    if (isInData && current.isRoot()) {
-      result = dataRoot.getNextSibling() != null;
-    } else {
-      result = current.getNextSibling() != null;
-    }
-    return result;
-  }
-
-  public boolean isFolder() {
-    boolean folder = current.getChildCount() > 0;
-    return folder;
-  }
-
-  public int getDepth() {
-    int depth = junctions.size();
-    return depth;
-  }
-
-  public boolean isRoot() {
-    return junctions.size() < 2;
+    return current.hasNextSibling();
   }
 
   public List<Boolean> getJunctions() {
@@ -159,4 +102,7 @@
     return result;
   }
 
+  public TreePath getPath() {
+    return current.getPath();
+  }
 }

Copied: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/Node.java (from r722373, myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/Node.java?p2=myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/Node.java&p1=myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java&r1=722373&r2=765504&rev=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeModel.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/Node.java Thu Apr 16 08:14:22 2009
@@ -1,5 +1,9 @@
 package org.apache.myfaces.tobago.model;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -17,107 +21,87 @@
  * limitations under the License.
  */
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import javax.swing.tree.DefaultMutableTreeNode;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-// todo: make more general (e.g. support other trees)
+public class Node {
 
-// todo: Should be the model for the whole tree, (also for tc:treeNode on the JSP)
-public class TreeModel {
+  private List<Node> children;
 
-  private static final Log LOG = LogFactory.getLog(TreeModel.class);
+  private Node parent;
 
-  private Map<String, DefaultMutableTreeNode> nodes = new HashMap<String, DefaultMutableTreeNode>();
-  private List<String> keys = new ArrayList<String>();
+  // XXX is this okay?
+  private String label;
 
-  // XXX not nice
-  private List<Tag> doubleKeys = new ArrayList<Tag>(); // with "begin tags" and "end tags"
-
-  public TreeModel(DefaultMutableTreeNode node) {
-    putNodes(node, "", 0);
+  public void add(Node node) {
+    initChildren();
+    children.add(node);
+    node.setParent(this);
   }
 
-  private void putNodes(
-      DefaultMutableTreeNode node, String position, int index) {
-
-    if (node == null) { // XXX hotfix
-      LOG.warn("node is null");
-      return;
-    }
-
-    position += "_" + index;
-
-    keys.add(position);
-    doubleKeys.add(new Tag(position, true));
-    nodes.put(position, node);
-
-    index = 0;
-    for (Enumeration e = node.children(); e.hasMoreElements();) {
-      DefaultMutableTreeNode subNode = (DefaultMutableTreeNode) e.nextElement();
-      putNodes(subNode, position, index);
-      index++;
-    }
-
-    doubleKeys.add(new Tag(position, false));
+  public List<Node> getChildren() {
+    initChildren();
+    return children;
   }
 
-  public DefaultMutableTreeNode getNode(String pathIndex) {
-    return nodes.get(pathIndex);
+  private void initChildren() {
+    if (children == null) {
+      children = new ArrayList<Node>();
+    }
   }
 
-  public List<String> getPathIndexList() {
-    return Collections.unmodifiableList(keys);
+  public Node getChildAt(int index) {
+    initChildren();
+    return children.get(index);
   }
 
-  public List<Tag> getDoublePathIndexList() {
-    return Collections.unmodifiableList(doubleKeys);
+  public boolean isRoot() {
+    return parent == null;
   }
 
-  public String getParentPathIndex(String pathIndex) {
-    int lastUnderscore = pathIndex.lastIndexOf('_');
-    switch (lastUnderscore) {
-      case -1:
-        throw new IllegalArgumentException();
-      case 0:
-        return null;
-      default:
-        return pathIndex.substring(0, lastUnderscore);
+  public int getIndex(Node node) {
+    for (int i = 0; i < children.size(); i++) {
+      Node child = children.get(i);
+      if (child.equals(node)) {
+         return i;
+      }
     }
+    return -1;
   }
 
-  public static class Tag {
-
-    private String name;
+  public int getChildCount() {
+    return children == null ? 0 : children.size();
+  }
 
-    private boolean start;
+  public boolean hasNextSibling() {
+    return parent != null && parent.getIndex(this) + 1 < parent.getChildCount();
+  }
 
-    public Tag(String name, boolean start) {
-      this.name = name;
-      this.start = start;
+  public TreePath getPath() {
+    List<Integer> result = new ArrayList<Integer>();
+    Node node = this;
+    Node parent = this.parent;
+    while (parent != null) {
+      int index = parent.getIndex(node);
+      result.add(index);
+      node = parent;
+      parent = node.getParent();
     }
+    result.add(0);
+    Collections.reverse(result);
+    return new TreePath(result);
+  }
 
-    public String getName() {
-      return name;
-    }
+  public Node getParent() {
+    return parent;
+  }
 
-    public void setName(String name) {
-      this.name = name;
-    }
+  public void setParent(Node parent) {
+    this.parent = parent;
+  }
 
-    public boolean isStart() {
-      return start;
-    }
+  public String getLabel() {
+    return label;
+  }
 
-    public void setStart(boolean start) {
-      this.start = start;
-    }
+  public void setLabel(String label) {
+    this.label = label;
   }
 }

Added: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeAnalyser.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeAnalyser.java?rev=765504&view=auto
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeAnalyser.java (added)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeAnalyser.java Thu Apr 16 08:14:22 2009
@@ -0,0 +1,27 @@
+package org.apache.myfaces.tobago.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * User: lofwyr
+ * Date: 04.12.2008
+ */
+public interface TreeAnalyser {
+
+  int computeDepth();
+}

Copied: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java (from r722373, myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java?p2=myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java&p1=myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java&r1=722373&r2=765504&rev=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/MixedTreeModel.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java Thu Apr 16 08:14:22 2009
@@ -17,146 +17,91 @@
  * limitations under the License.
  */
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.myfaces.tobago.component.AbstractUITreeData;
-import org.apache.myfaces.tobago.component.AbstractUITreeNode;
-import org.apache.myfaces.tobago.component.Attributes;
-
 import javax.swing.tree.DefaultMutableTreeNode;
-import java.util.ArrayList;
+import java.io.Serializable;
+import java.util.Arrays;
 import java.util.List;
-import java.util.Stack;
 
 /**
+ * Handles a path in a tree from the root node to the position inside this tree.
+ *
  * User: lofwyr
- * Date: 23.04.2007 16:10:22
+ * Date: 02.12.2008
  */
-public class MixedTreeModel {
+public class TreePath implements Serializable {
 
-  private static final Log LOG = LogFactory.getLog(MixedTreeModel.class);
+  private int[] path;
 
-  private DefaultMutableTreeNode root;
-  private DefaultMutableTreeNode current;
-  private Integer nextChildIndex;
-  private DefaultMutableTreeNode dataRoot;
-  private boolean isInData;
-  private Stack<Boolean> junctions = new Stack<Boolean>();
-
-  public void beginBuildNode(AbstractUITreeNode node) {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug(node.getAttributes().get(Attributes.LABEL));
-    }
-    if (!isInData) {
-      DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(node.getAttributes().get(Attributes.LABEL));
-      if (root == null) {
-        root = newNode;
-        current = root;
-      } else {
-        current.add(newNode);
-        current = newNode;
-      }
-    }
+  public TreePath(int... path) {
+    assert path[0] == 0;
+    this.path = path;
   }
 
-  public void endBuildNode(AbstractUITreeNode node) {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug(node.getAttributes().get(Attributes.LABEL));
-    }
-    if (!isInData) {
-      current = (DefaultMutableTreeNode) current.getParent();
+  public TreePath(List<Integer> pathList) {
+    assert pathList.get(0) == 0;
+    path = new int[pathList.size()];
+    for (int i = 0; i < path.length; i++) {
+      path[i] = pathList.get(i);
     }
   }
 
-  public void beginBuildNodeData(AbstractUITreeData data) {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("var=" + data.getVar());
-    }
-    current = new DefaultMutableTreeNode(data.getValue());
-    if (root == null) {
-      root = current;
-    } else {
-      root.add(current);
-    }
-    isInData = true;
+  public TreePath(TreePath position, int addendum) {
+    this.path = new int[position.path.length + 1];
+    System.arraycopy(position.path, 0, path, 0, position.path.length);
+    path[position.path.length] = addendum;
   }
 
-  public void endBuildNodeData(AbstractUITreeData data) {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("var=" + data.getVar());
-    }
-    current = (DefaultMutableTreeNode) current.getParent();
-    isInData = false;
+  public int[] getPath() {
+    return path;
   }
 
-  public void onEncodeBegin() {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("current=" + current);
-    }
-    if (current == null) {
-      current = root;
-    } else {
-      current = (DefaultMutableTreeNode) current.getChildAt(nextChildIndex);
+  public String getPathString() {
+    StringBuffer buffer = new StringBuffer();
+    for (int item : path) {
+      buffer.append("_");
+      buffer.append(item);
     }
-    if (!isInData && current.getUserObject() instanceof DefaultMutableTreeNode) {
-      isInData = true;
-      dataRoot = current;
-      current = (DefaultMutableTreeNode) current.getUserObject();
-    }
-    nextChildIndex = 0;
-
-    junctions.push(hasCurrentNodeNextSibling());
+    return buffer.toString();
   }
 
-  public void onEncodeEnd() {
-    if (LOG.isDebugEnabled()) {
-      LOG.debug("current=" + current);
-    }
-    if (isInData && current.isRoot()) {
-      current = dataRoot;
-      isInData = false;
-    }
-    DefaultMutableTreeNode parent = (DefaultMutableTreeNode) current.getParent();
-    if (parent != null) {
-      nextChildIndex = parent.getIndex(current) + 1;
-      current = parent;
-    } else {
-      nextChildIndex = null;
-      current = null;
+  public String getParentPathString() {
+    StringBuffer buffer = new StringBuffer();
+    for (int i = 0; i < path.length - 1; i++) {
+      buffer.append("_");
+      buffer.append(path[i]);
     }
-
-    junctions.pop();
+    return buffer.toString();
   }
 
-  public boolean hasCurrentNodeNextSibling() {
-    boolean result;
-    if (isInData && current.isRoot()) {
-      result = dataRoot.getNextSibling() != null;
-    } else {
-      result = current.getNextSibling() != null;
+  /**
+   * Returns the node at the position of this NodePath applied to the parameter node.
+   * @param tree The start node.
+   * @return The node applied to the given path.
+   */
+  public DefaultMutableTreeNode getNode(DefaultMutableTreeNode tree) {
+    for (int i = 1; i < path.length; i++) { // i = 1: first entry must be 0 and means the root
+      int pos = path[i];
+      tree = (DefaultMutableTreeNode) tree.getChildAt(pos);
     }
-    return result;
+    return tree;
   }
 
-  public boolean isFolder() {
-    boolean folder = current.getChildCount() > 0;
-    return folder;
-  }
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    TreePath nodeIndex = (TreePath) o;
+    return Arrays.equals(path, nodeIndex.path);
 
-  public int getDepth() {
-    int depth = junctions.size();
-    return depth;
   }
 
-  public boolean isRoot() {
-    return junctions.size() < 2;
+  @Override
+  public int hashCode() {
+    return path != null ? Arrays.hashCode(path) : 0;
   }
 
-  public List<Boolean> getJunctions() {
-    Boolean top = junctions.pop();
-    List<Boolean> result = new ArrayList<Boolean>(junctions);
-    junctions.push(top);
-    return result;
+  @Override
+  public String toString() {
+    return getPathString();
   }
-
 }

Propchange: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java
------------------------------------------------------------------------------
    svn:mergeinfo = 

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java Thu Apr 16 08:14:22 2009
@@ -17,10 +17,9 @@
  * limitations under the License.
  */
 
-import javax.swing.tree.DefaultMutableTreeNode;
-
 import org.apache.commons.lang.StringUtils;
 
+import javax.swing.tree.DefaultMutableTreeNode;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Set;
@@ -33,32 +32,58 @@
  */
 public class TreeState {
 
-  public static final String SEP = ";";
+  private Set<TreePath> expanded;
+  private Set<TreePath> selected;
+  private Set<TreePath> marked;
 
+  @Deprecated
   private Set<DefaultMutableTreeNode> selection;
+  @Deprecated
   private Set<DefaultMutableTreeNode> expandState;
+  @Deprecated
   private DefaultMutableTreeNode marker;
+  @Deprecated
   private DefaultMutableTreeNode lastMarker;
+  @Deprecated
   private String lastCommand;
   private Integer[] scrollPosition;
 
   public TreeState() {
     selection = new HashSet<DefaultMutableTreeNode>();
     expandState = new HashSet<DefaultMutableTreeNode>();
+    expanded = new HashSet<TreePath>();
+    selected = new HashSet<TreePath>();
+    marked = new HashSet<TreePath>();
+  }
+
+  public Set<TreePath> getExpanded() {
+    return expanded;
+  }
+
+  public Set<TreePath> getSelected() {
+    return selected;
+  }
+
+  public Set<TreePath> getMarked() {
+    return marked;
   }
 
+  @Deprecated
   public void addExpandState(DefaultMutableTreeNode expandStateItem) {
     expandState.add(expandStateItem);
   }
 
+  @Deprecated
   public void addSelection(DefaultMutableTreeNode selectItem) {
     selection.add(selectItem);
   }
 
+  @Deprecated
   public void clearExpandState() {
     expandState.clear();
   }
 
+  @Deprecated
   public void clearSelection() {
     selection.clear();
   }
@@ -66,12 +91,14 @@
   /**
    * Adds a (external created) node to the actually marked node.
    */
+  @Deprecated
   public void commandNew(DefaultMutableTreeNode newNode) {
     marker.insert(newNode, 0);
     setLastMarker(null);
     setLastCommand(null);
   }
 
+  @Deprecated
   public void expand(DefaultMutableTreeNode node, int level) {
     if (level > 0) {
       if (!expandState.contains(node)) {
@@ -87,12 +114,14 @@
   /**
    * Expands all parents which contains selected children.
    */
+  @Deprecated
   public void expandSelection() {
     for (DefaultMutableTreeNode treeNode : selection) {
       expandTo(treeNode);
     }
   }
 
+  @Deprecated
   public void expandTo(DefaultMutableTreeNode node) {
     node = (DefaultMutableTreeNode) node.getParent();
     while (node != null) {
@@ -103,54 +132,67 @@
     }
   }
 
+  @Deprecated
   public boolean isExpanded(DefaultMutableTreeNode node) {
     return expandState.contains(node);
   }
 
+  @Deprecated
   public boolean isMarked(DefaultMutableTreeNode node) {
     return node != null && node.equals(marker);
   }
 
+  @Deprecated
   public boolean isSelected(DefaultMutableTreeNode node) {
     return selection.contains(node);
   }
 
+  @Deprecated
   public Set<DefaultMutableTreeNode> getExpandState() {
     return expandState;
   }
 
+  @Deprecated
   public void setExpandState(Set<DefaultMutableTreeNode> expandState) {
     this.expandState = expandState;
   }
 
+  @Deprecated
   public String getLastCommand() {
     return lastCommand;
   }
 
+  @Deprecated
   public void setLastCommand(String lastCommand) {
     this.lastCommand = lastCommand;
   }
 
+  @Deprecated
   public DefaultMutableTreeNode getLastMarker() {
     return lastMarker;
   }
 
+  @Deprecated
   public void setLastMarker(DefaultMutableTreeNode lastMarker) {
     this.lastMarker = lastMarker;
   }
 
+  @Deprecated
   public DefaultMutableTreeNode getMarker() {
     return marker;
   }
 
+  @Deprecated
   public void setMarker(DefaultMutableTreeNode marker) {
     this.marker = marker;
   }
 
+  @Deprecated
   public Set<DefaultMutableTreeNode> getSelection() {
     return selection;
   }
 
+  @Deprecated
   public void setSelection(Set<DefaultMutableTreeNode> selection) {
     this.selection = selection;
   }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/GridConstraintsTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/GridConstraintsTagDeclaration.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/GridConstraintsTagDeclaration.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/GridConstraintsTagDeclaration.java Thu Apr 16 08:14:22 2009
@@ -19,10 +19,10 @@
 
 import org.apache.myfaces.tobago.apt.annotation.BodyContent;
 import org.apache.myfaces.tobago.apt.annotation.Tag;
+import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
-import org.apache.myfaces.tobago.taglib.decl.HasHeight;
+import org.apache.myfaces.tobago.apt.annotation.UIComponentTagAttribute;
 import org.apache.myfaces.tobago.taglib.decl.HasId;
-import org.apache.myfaces.tobago.taglib.decl.HasWidth;
 
 @Tag(name = "gridConstraints", bodyContent = BodyContent.EMPTY)
 @UIComponentTag(
@@ -30,5 +30,19 @@
     uiComponentBaseClass = "org.apache.myfaces.tobago.component.AbstractUIGridConstraints",
     componentFamily = "org.apache.myfaces.tobago.GridConstraints",
     allowedChildComponenents = "NONE", isLayout = true)
-public interface GridConstraintsTagDeclaration extends HasId, HasWidth, HasHeight {
+public interface GridConstraintsTagDeclaration extends HasId {
+
+  /**
+   *  The width for this component.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "org.apache.myfaces.tobago.layout.Measure")
+  void setWidth(String width);
+
+  /**
+   *  The height for this component.
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "org.apache.myfaces.tobago.layout.Measure")
+  void setHeight(String height);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeNodeTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeNodeTagDeclaration.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeNodeTagDeclaration.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeNodeTagDeclaration.java Thu Apr 16 08:14:22 2009
@@ -18,6 +18,7 @@
  */
 
 import org.apache.myfaces.tobago.apt.annotation.BodyContentDescription;
+import org.apache.myfaces.tobago.apt.annotation.DynamicExpression;
 import org.apache.myfaces.tobago.apt.annotation.Facet;
 import org.apache.myfaces.tobago.apt.annotation.Tag;
 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
@@ -66,13 +67,22 @@
    * Flag indicating if the subnodes are to be displayed.
    */
   @TagAttribute()
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "true")
+  @UIComponentTagAttribute(type = "java.lang.Boolean")
   void setExpanded(String expanded);
 
   /**
    * Flag indicating if the node is marked, and should be displayed in a special way.
    */
   @TagAttribute()
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "Boolean.FALSE")
   void setMarked(String marked);
+
+  /**
+   * Method binding representing a expansionListener method that ....
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = {},
+       expression = DynamicExpression.METHOD_BINDING_REQUIRED,
+       methodSignature = "org.apache.myfaces.tobago.event.TreeExpansionEvent")
+  void setTreeExpansionListener(String treeExpansionListener);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeTagDeclaration.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeTagDeclaration.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/component/TreeTagDeclaration.java Thu Apr 16 08:14:22 2009
@@ -18,6 +18,7 @@
  */
 
 import org.apache.myfaces.tobago.apt.annotation.BodyContentDescription;
+import org.apache.myfaces.tobago.apt.annotation.DynamicExpression;
 import org.apache.myfaces.tobago.apt.annotation.Tag;
 import org.apache.myfaces.tobago.apt.annotation.TagAttribute;
 import org.apache.myfaces.tobago.apt.annotation.UIComponentTag;
@@ -64,19 +65,19 @@
   void setSelectable(String selectable);
 
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setShowRootJunction(String showRootJunction);
 
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setShowIcons(String showIcons);
 
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setShowJunctions(String showJunctions);
 
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setShowRoot(String showRoot);
   
   /**
@@ -86,4 +87,13 @@
   @UIComponentTagAttribute(defaultValue = "tree", allowedValues = {"tree", "menu"})
   void setMode(String mode);
 
+  /**
+   *
+   * <strong>ValueBindingExpression</strong> pointing to a object to save the
+   * component's state.
+   *
+   */
+  @TagAttribute
+  @UIComponentTagAttribute(type = "java.lang.Object", expression = DynamicExpression.VALUE_BINDING_REQUIRED)
+  void setState(String state);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsDisabled.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsDisabled.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsDisabled.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsDisabled.java Thu Apr 16 08:14:22 2009
@@ -30,6 +30,6 @@
    * Flag indicating that this element is disabled.
    */
   @TagAttribute()
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setDisabled(String disabled);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsImmediateCommand.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsImmediateCommand.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsImmediateCommand.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsImmediateCommand.java Thu Apr 16 08:14:22 2009
@@ -31,6 +31,6 @@
    * waiting until Invoke Application phase.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "false")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setImmediate(String immediate);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsReadonly.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsReadonly.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsReadonly.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsReadonly.java Thu Apr 16 08:14:22 2009
@@ -30,6 +30,6 @@
    * Flag indicating that this component will prohibit changes by the user.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean")
+  @UIComponentTagAttribute(type = "boolean")
   void setReadonly(String readonly);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRendered.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRendered.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRendered.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRendered.java Thu Apr 16 08:14:22 2009
@@ -29,6 +29,6 @@
    * (during Render Response Phase), or processed on any subsequent form submit.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean", defaultValue = "true")
+  @UIComponentTagAttribute(type = "boolean", defaultValue = "true")
   void setRendered(String rendered);
 }

Modified: myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRequired.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRequired.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRequired.java (original)
+++ myfaces/tobago/trunk/core/src/main/java/org/apache/myfaces/tobago/taglib/decl/IsRequired.java Thu Apr 16 08:14:22 2009
@@ -32,6 +32,6 @@
    * ValidationError occurs and a Error Message is rendered.
    */
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Boolean")
+  @UIComponentTagAttribute(type = "boolean")
   void setRequired(String required);
 }

Modified: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java (original)
+++ myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java Thu Apr 16 08:14:22 2009
@@ -35,6 +35,7 @@
     model.endBuildNode(n1);
 
     model.onEncodeBegin();
+    assertEquals(new TreePath(0), model.getPath());
     model.onEncodeEnd();
   }
 
@@ -64,53 +65,100 @@
   public void testLifecycleFromModel() {
 
     MixedTreeModel model = new MixedTreeModel();
-    DefaultMutableTreeNode tree = new DefaultMutableTreeNode();
-    tree.add(new DefaultMutableTreeNode());
-    tree.add(new DefaultMutableTreeNode());
+    DefaultMutableTreeNode tree = new DefaultMutableTreeNode("D_0");
+    tree.add(new DefaultMutableTreeNode("D_0_0"));
+    tree.add(new DefaultMutableTreeNode("D_0_1"));
 
     UITreeData data = new UITreeData();
     data.setValue(tree);
     UITreeNode node = new UITreeNode();
 
-    model.beginBuildNodeData(data);
+//    model.beginBuildNodeData(data);
     model.beginBuildNode(node);
+    model.beginBuildNode(node);
+    model.endBuildNode(node);
+    model.beginBuildNode(node);
+    model.endBuildNode(node);
     model.endBuildNode(node);
-    model.endBuildNodeData(data);
+//    model.endBuildNodeData(data);
 
     model.onEncodeBegin();
+    assertEquals(new TreePath(0), model.getPath());
     model.onEncodeBegin();
+    assertEquals(new TreePath(0, 0), model.getPath());
     model.onEncodeEnd();
     model.onEncodeBegin();
+    assertEquals(new TreePath(0, 1), model.getPath());
     model.onEncodeEnd();
     model.onEncodeEnd();
   }
 
+  /**
+   * * --o Root (0)
+   * *   |
+   * *   +--o Individual Node (0,0)
+   * *   |
+   * *   +--o Data Root Node (0,1)
+   * *      |
+   * *      +--o Data Sub Node 1 (0,1,0)
+   * *      |
+   * *      +--o Data Sub Node 2 (0,1,1)
+   * *         |
+   * *         +--o Data Sub Sub Node 3 (0,1,1,0)
+   */
   public void testLifecycleMixed() {
 
     MixedTreeModel model = new MixedTreeModel();
-    DefaultMutableTreeNode tree = new DefaultMutableTreeNode();
-    tree.add(new DefaultMutableTreeNode());
-    tree.add(new DefaultMutableTreeNode());
+    DefaultMutableTreeNode tree = new DefaultMutableTreeNode("root");
+    tree.add(new DefaultMutableTreeNode("node1"));
+    DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("node2");
+    node2.add(new DefaultMutableTreeNode("node3"));
+    tree.add(node2);
 
     UITreeData data = new UITreeData();
     data.setValue(tree);
+    UITreeNode root = new UITreeNode();
+    UITreeNode individual = new UITreeNode();
     UITreeNode node = new UITreeNode();
 
+    model.beginBuildNode(root);
+    model.beginBuildNode(individual);
+    model.endBuildNode(individual);
+//    model.beginBuildNodeData(data);
     model.beginBuildNode(node);
-    model.beginBuildNodeData(data);
     model.beginBuildNode(node);
     model.endBuildNode(node);
-    model.endBuildNodeData(data);
+    model.beginBuildNode(node);
+    model.beginBuildNode(node);
+    model.endBuildNode(node);
+    model.endBuildNode(node);
     model.endBuildNode(node);
+//    model.endBuildNodeData(data);
+    model.endBuildNode(root);
 
-    model.onEncodeBegin();
-    model.onEncodeBegin();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeEnd();
-    model.onEncodeEnd();
+    model.onEncodeBegin(); // root
+    assertEquals(new TreePath(0), model.getPath());
+    model.onEncodeBegin(); // individual
+    assertEquals(new TreePath(0, 0), model.getPath());
+    model.onEncodeEnd(); // individual
+    assertEquals(new TreePath(0), model.getPath());
+    model.onEncodeBegin(); // data root node
+    assertEquals(new TreePath(0, 1), model.getPath());
+    model.onEncodeBegin(); // data sub node 1
+    assertEquals(new TreePath(0, 1, 0), model.getPath());
+    model.onEncodeEnd(); // data sub node 1
+    assertEquals(new TreePath(0, 1), model.getPath());
+    model.onEncodeBegin(); // data sub node 2
+    assertEquals(new TreePath(0, 1, 1), model.getPath());
+    model.onEncodeBegin(); // data sub node 3
+    assertEquals(new TreePath(0, 1, 1, 0), model.getPath());
+    model.onEncodeEnd(); // data sub node 3
+    assertEquals(new TreePath(0, 1, 1), model.getPath());
+    model.onEncodeEnd(); // data sub node 2
+    assertEquals(new TreePath(0, 1), model.getPath());
+    model.onEncodeEnd();  // data root node
+    assertEquals(new TreePath(0), model.getPath());
+    model.onEncodeEnd(); // root
   }
 
 }

Added: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodePathUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodePathUnitTest.java?rev=765504&view=auto
==============================================================================
--- myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodePathUnitTest.java (added)
+++ myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodePathUnitTest.java Thu Apr 16 08:14:22 2009
@@ -0,0 +1,78 @@
+package org.apache.myfaces.tobago.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import junit.framework.TestCase;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.util.Arrays;
+
+public class NodePathUnitTest extends TestCase {
+
+  public void testGetPath() {
+    TreePath nodePath = new TreePath(0, 1, 2);
+    assertTrue(Arrays.equals(new int[]{0, 1, 2}, nodePath.getPath()));
+    TreePath nodePath2 = new TreePath(nodePath, 3);
+    assertTrue(Arrays.equals(new int[]{0, 1, 2, 3}, nodePath2.getPath()));
+  }
+
+  public void testGetPathString() {
+    TreePath nodePath = new TreePath(0, 1, 2);
+    assertEquals("_0_1_2", nodePath.getPathString());
+    TreePath nodePath2 = new TreePath(nodePath, 3);
+    assertEquals("_0_1_2_3", nodePath2.getPathString());
+  }
+
+  public void testGetNode() {
+
+    DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
+    DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("node1");
+    root.add(node1);
+    DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("node2");
+    DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("node3");
+    node2.add(node3);
+    root.add(node2);
+
+    assertEquals(root, new TreePath(0).getNode(root));
+    assertEquals(node1, new TreePath(0, 0).getNode(root));
+    assertEquals(node2, new TreePath(0, 1).getNode(root));
+    assertEquals(node3, new TreePath(0, 1, 0).getNode(root));
+  }
+
+  public void testGetNode2() {
+
+    DefaultMutableTreeNode tree = new DefaultMutableTreeNode("Category");
+    tree.add(new DefaultMutableTreeNode("Sports"));
+    tree.add(new DefaultMutableTreeNode("Movies"));
+    DefaultMutableTreeNode sience = new DefaultMutableTreeNode("Science");
+    tree.add(sience);
+    sience.add(new DefaultMutableTreeNode("Geography"));
+    sience.add(new DefaultMutableTreeNode("Mathematics"));
+    DefaultMutableTreeNode astronomy = new DefaultMutableTreeNode("Astronomy");
+    astronomy.add(new DefaultMutableTreeNode("Education"));
+    astronomy.add(new DefaultMutableTreeNode("Pictures"));
+    sience.add(astronomy);
+    tree.add(new DefaultMutableTreeNode("Music"));
+    tree.add(new DefaultMutableTreeNode("Games"));
+
+    assertEquals("Category", new TreePath(0).getNode(tree).getUserObject());
+    assertEquals("Sports", new TreePath(0, 0).getNode(tree).getUserObject());
+    assertEquals("Astronomy", new TreePath(0, 2, 2).getNode(tree).getUserObject());
+    assertEquals("Games", new TreePath(0, 4).getNode(tree).getUserObject());
+  }
+}

Copied: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java (from r722373, myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java)
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java?p2=myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java&p1=myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java&r1=722373&r2=765504&rev=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/MixedTreeModelUnitTest.java (original)
+++ myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java Thu Apr 16 08:14:22 2009
@@ -18,99 +18,81 @@
  */
 
 import junit.framework.TestCase;
-import org.apache.myfaces.tobago.component.UITreeData;
-import org.apache.myfaces.tobago.component.UITreeNode;
 
-import javax.swing.tree.DefaultMutableTreeNode;
+public class NodeUnitTest extends TestCase {
 
-public class MixedTreeModelUnitTest extends TestCase {
+  private Node r;
+  private Node a;
+  private Node b;
+  private Node c;
+  private Node x;
+  private Node y;
+  private Node π;
+
+  /**
+   * * --o r (0)
+   * *   |
+   * *   +--o a (0,0)
+   * *   |
+   * *   +--o b (0,1)
+   * *   |   |
+   * *   |   +--o x (0,1,0)
+   * *   |   |
+   * *   |   +--o y (0,1,1)
+   * *   |      |
+   * *   |      +--o π (0,1,1,0)
+   * *   |
+   * *   +--o c (0,1,1,0)
+   */
+  public void setUp() {
+
+    r = new Node();
+    a = new Node();
+    b = new Node();
+    c = new Node();
+    x = new Node();
+    y = new Node();
+    π = new Node();
+
+    r.add(a);
+    r.add(b);
+    r.add(c);
 
-  public void testLifecycleSmall() {
+    b.add(x);
+    b.add(y);
 
-    MixedTreeModel model = new MixedTreeModel();
+    y.add(π);
 
-    UITreeNode n1 = new UITreeNode();
-
-    model.beginBuildNode(n1);
-    model.endBuildNode(n1);
-
-    model.onEncodeBegin();
-    model.onEncodeEnd();
   }
 
-  public void testLifecycleStatic() {
-
-    MixedTreeModel model = new MixedTreeModel();
-
-    UITreeNode n1 = new UITreeNode();
-    UITreeNode n2 = new UITreeNode();
-    UITreeNode n3 = new UITreeNode();
-
-    model.beginBuildNode(n1);
-    model.beginBuildNode(n2);
-    model.endBuildNode(n2);
-    model.beginBuildNode(n3);
-    model.endBuildNode(n3);
-    model.endBuildNode(n1);
-
-    model.onEncodeBegin();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeEnd();
+  public void testIsRoot() {
+    assertTrue(r.isRoot());
+    assertFalse(a.isRoot());
+    assertFalse(b.isRoot());
+    assertFalse(c.isRoot());
+    assertFalse(x.isRoot());
+    assertFalse(y.isRoot());
+    assertFalse(π.isRoot());
   }
 
-  public void testLifecycleFromModel() {
-
-    MixedTreeModel model = new MixedTreeModel();
-    DefaultMutableTreeNode tree = new DefaultMutableTreeNode();
-    tree.add(new DefaultMutableTreeNode());
-    tree.add(new DefaultMutableTreeNode());
-
-    UITreeData data = new UITreeData();
-    data.setValue(tree);
-    UITreeNode node = new UITreeNode();
-
-    model.beginBuildNodeData(data);
-    model.beginBuildNode(node);
-    model.endBuildNode(node);
-    model.endBuildNodeData(data);
-
-    model.onEncodeBegin();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeEnd();
+  public void testGetChildCount() {
+    assertEquals(3, r.getChildCount());
+    assertEquals(0, a.getChildCount());
+    assertEquals(2, b.getChildCount());
+    assertEquals(0, c.getChildCount());
+    assertEquals(0, x.getChildCount());
+    assertEquals(1, y.getChildCount());
+    assertEquals(0, π.getChildCount());
   }
 
-  public void testLifecycleMixed() {
-
-    MixedTreeModel model = new MixedTreeModel();
-    DefaultMutableTreeNode tree = new DefaultMutableTreeNode();
-    tree.add(new DefaultMutableTreeNode());
-    tree.add(new DefaultMutableTreeNode());
-
-    UITreeData data = new UITreeData();
-    data.setValue(tree);
-    UITreeNode node = new UITreeNode();
-
-    model.beginBuildNode(node);
-    model.beginBuildNodeData(data);
-    model.beginBuildNode(node);
-    model.endBuildNode(node);
-    model.endBuildNodeData(data);
-    model.endBuildNode(node);
-
-    model.onEncodeBegin();
-    model.onEncodeBegin();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeBegin();
-    model.onEncodeEnd();
-    model.onEncodeEnd();
-    model.onEncodeEnd();
+  public void testHasNextSibling() {
+    assertFalse(r.hasNextSibling());
+    assertTrue(a.hasNextSibling());
+    assertTrue(b.hasNextSibling());
+    assertFalse(c.hasNextSibling());
+    assertTrue(x.hasNextSibling());
+    assertFalse(y.hasNextSibling());
+    assertFalse(π.hasNextSibling());
   }
 
-}
+}
\ No newline at end of file

Propchange: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: myfaces/tobago/trunk/core/src/test/java/org/apache/myfaces/tobago/model/NodeUnitTest.java
------------------------------------------------------------------------------
    svn:mergeinfo = 

Modified: myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/Node.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/Node.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/Node.java (original)
+++ myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/Node.java Thu Apr 16 08:14:22 2009
@@ -19,7 +19,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-//import org.apache.myfaces.tobago.event.TreeExpansionEvent;
+import org.apache.myfaces.tobago.event.TreeExpansionEvent;
 
 public class Node {
 
@@ -48,12 +48,12 @@
     LOG.info("action: name='" + name + "'");
     return null;
   }
-/*
+
   public void expansionListener(TreeExpansionEvent event) {
     LOG.info("event='" + event + "'");
     expanded = event.isNewExpanded();
   }
-*/
+
   public String getName() {
     return name;
   }
@@ -89,4 +89,11 @@
   public void setDisabled(boolean disabled) {
     this.disabled = disabled;
   }
+
+  @Override
+  public String toString() {
+    return "Node{" +
+        "name='" + name + '\'' +
+        '}';
+  }
 }

Modified: myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/TreeController.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/TreeController.java?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/TreeController.java (original)
+++ myfaces/tobago/trunk/example/demo/src/main/java/org/apache/myfaces/tobago/example/demo/TreeController.java Thu Apr 16 08:14:22 2009
@@ -63,6 +63,11 @@
     temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.12 Animal")));
     temp2.add(new DefaultMutableTreeNode(new Node("1.3.3.13 Personal")));
     temp.add(temp2);
+    DefaultMutableTreeNode bulk = new DefaultMutableTreeNode(new Node("1.6 Bulk"));
+    for (int i = 0; i < 5; i++) {
+      bulk.add(new DefaultMutableTreeNode(new Node("1.6." + (i + 1) + " Some Node")));
+    }
+    tree.add(bulk);
 
     // state
 

Modified: myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.jsp
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.jsp?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.jsp (original)
+++ myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.jsp Thu Apr 16 08:14:22 2009
@@ -23,13 +23,13 @@
       <tc:gridLayout rows="*"/>
     </f:facet>
 
-    <tc:tree id="nav" mode="menu" showRoot="true">
+    <tc:tree id="nav" mode="menu" showRoot="true" state="#{navigation.state}">
       <tc:treeData value="#{navigation.tree}" var="node" id="data">
         <tc:treeNode label="#{node.userObject.title}"
                      action="#{node.userObject.action}"
                      immediate="true"
-            value="#{node}"
-            expanded="true"/>
+                     value="#{node}"
+                     expanded="true"/>
       </tc:treeData>
     </tc:tree>
 

Modified: myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.xhtml
URL: http://svn.apache.org/viewvc/myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.xhtml?rev=765504&r1=765503&r2=765504&view=diff
==============================================================================
--- myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.xhtml (original)
+++ myfaces/tobago/trunk/example/demo/src/main/webapp/navigation.xhtml Thu Apr 16 08:14:22 2009
@@ -28,7 +28,7 @@
       <tc:gridLayout rows="*"/>
     </f:facet>
 
-    <tc:tree id="nav" mode="menu" showRoot="true">
+    <tc:tree id="nav" mode="menu" showRoot="true" state="#{navigation.state}">
       <tc:treeData value="#{navigation.tree}" var="node" id="data">
         <tc:treeNode label="#{node.userObject.title}"
                      action="#{node.userObject.action}"