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 2012/04/18 11:04:23 UTC

svn commit: r1327429 [1/2] - in /myfaces/tobago/branches/tobago-tree-table: tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/ tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/ tobago-core/src/main/java...

Author: lofwyr
Date: Wed Apr 18 09:04:22 2012
New Revision: 1327429

URL: http://svn.apache.org/viewvc?rev=1327429&view=rev
Log:
TOBAGO-1107: Using a TreeState object instead of "expanded" and "marked" in the tree node tag
TOBAGO-1049: Tree inside of the Sheet (aka TreeTable)

 - introduce the tree state
 - implement AJAX reload, when open a sub tree
 - possibility to have unlimited tree (node will only accessed, when they are rendered)

Added:
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/ExpandedState.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/MarkedState.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/test/java/org/apache/myfaces/tobago/model/ExpandedStateUnitTest.java
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-data/src/main/java/org/apache/myfaces/tobago/example/data/CantorInterval.java
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-infinite.xhtml
      - copied, changed from r1324674, myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRendererBase.java
Modified:
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIData.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeListboxTagDeclaration.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeMenuTagDeclaration.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeNodeTagDeclaration.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeTagDeclaration.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Node.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeDataModel.java
    myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Navigation.java
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/webapp/navigation.xhtml
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TestPageFilter.java
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TreeController.java
    myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIconRenderer.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIndentRenderer.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeMenuNodeRenderer.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeRenderer.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-standard/src/main/java/org/apache/myfaces/tobago/renderkit/util/RenderUtils.java
    myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-standard/src/main/resources/org/apache/myfaces/tobago/renderkit/html/standard/standard/script/tobago-tree.js

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIData.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIData.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIData.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUIData.java Wed Apr 18 09:04:22 2012
@@ -17,15 +17,22 @@ package org.apache.myfaces.tobago.intern
  * limitations under the License.
  */
 
+import org.apache.myfaces.tobago.compat.FacesUtils;
+import org.apache.myfaces.tobago.compat.InvokeOnComponent;
+import org.apache.myfaces.tobago.model.ExpandedState;
 import org.apache.myfaces.tobago.model.TreeDataModel;
+import org.apache.myfaces.tobago.model.TreePath;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.faces.FacesException;
+import javax.faces.component.ContextCallback;
+import javax.faces.context.FacesContext;
 import javax.faces.model.DataModel;
 import javax.swing.tree.DefaultMutableTreeNode;
-import java.util.List;
+import java.io.IOException;
 
-public abstract class AbstractUIData extends javax.faces.component.UIData {
+public abstract class AbstractUIData extends javax.faces.component.UIData implements InvokeOnComponent {
 
   private static final Logger LOG = LoggerFactory.getLogger(AbstractUIData.class);
 
@@ -42,16 +49,6 @@ public abstract class AbstractUIData ext
    */
   private TreeDataModel dataModel;
 
-  // is transient, for internal use
-  // XXX is introduced temporarily:
-  @Deprecated
-  private Integer submittedMarked;
-
-  // is transient, for internal use
-  // XXX is introduced temporarily:
-  @Deprecated
-  private List<Integer> submittedExpanded;
-
   public boolean isTreeModel() {
     init();
     return dataModel != null;
@@ -73,12 +70,23 @@ public abstract class AbstractUIData ext
       Object value = getValue();
       boolean showRoot = isShowRoot();
       if (value instanceof DefaultMutableTreeNode) {
-        dataModel = new TreeDataModel((DefaultMutableTreeNode) value, showRoot);
+        dataModel = new TreeDataModel((DefaultMutableTreeNode) value, showRoot, getExpandedState());
       }
       initialized = true;
     }
   }
 
+  @Override
+  public void encodeBegin(FacesContext context) throws IOException {
+    init();
+    if (dataModel != null) {
+      dataModel.reset();
+    }
+    super.encodeBegin(context);
+  }
+
+  public abstract ExpandedState getExpandedState();
+
   public boolean hasRows() {
     return getRows() != 0;
   }
@@ -109,6 +117,13 @@ public abstract class AbstractUIData ext
   }
 
   /**
+   * @return Is the (maximum) number of rows to display set to zero?
+   */
+  public boolean isRowsUnlimited() {
+    return getRows() == 0;
+  }
+
+  /**
    * The value describes, if the UIData renderer creates container elements to hold the row information.
    * This information is important for the TreeNodeRenderer to set the visible state in the output or not.
    * Typically the Sheet returns true and a Tree returns false, because the sheet renders the HTML TR tags,
@@ -118,27 +133,54 @@ public abstract class AbstractUIData ext
     return false;
   }
 
-  // XXX is introduced temporarily:
-  @Deprecated
-  public Integer getSubmittedMarked() {
-    return submittedMarked;
-  }
+    // todo: after removing jsf 1.1: @Override
+  public boolean invokeOnComponent(FacesContext facesContext, String clientId, ContextCallback callback)
+      throws FacesException {
+    // we may need setRowIndex on UISheet
+    int oldRowIndex = getRowIndex();
+    try {
+      String sheetId = getClientId(facesContext);
+      if (clientId.startsWith(sheetId)) {
+        String idRemainder = clientId.substring(sheetId.length());
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("idRemainder = '" + idRemainder + "'");
+        }
+        if (idRemainder.matches("^:\\d+:.*")) {
+          idRemainder = idRemainder.substring(1);
+          int idx = idRemainder.indexOf(":");
+          try {
+            int rowIndex = Integer.parseInt(idRemainder.substring(0, idx));
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("set rowIndex = '" + rowIndex + "'");
+            }
+            setRowIndex(rowIndex);
+          } catch (NumberFormatException e) {
+            LOG.warn("idRemainder = '" + idRemainder + "'", e);
+          }
+        } else {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("no match for '^:\\d+:.*'");
+          }
+        }
+      }
 
-  // XXX is introduced temporarily:
-  @Deprecated
-  public void setSubmittedMarked(Integer submittedMarked) {
-    this.submittedMarked = submittedMarked;
-  }
+      return FacesUtils.invokeOnComponent(facesContext, this, clientId, callback);
 
-  // XXX is introduced temporarily:
-  @Deprecated
-  public List<Integer> getSubmittedExpanded() {
-    return submittedExpanded;
+    } finally {
+      // we should reset rowIndex on UISheet
+      setRowIndex(oldRowIndex);
+    }
   }
 
-  // XXX is introduced temporarily:
-  @Deprecated
-  public void setSubmittedExpanded(List<Integer> submittedExpanded) {
-    this.submittedExpanded = submittedExpanded;
+  /**
+   * @return The TreePath of the current row index.
+   */
+  public TreePath getPath() {
+    final DataModel model = getDataModel();
+    if (model instanceof TreeDataModel) {
+      return ((TreeDataModel)model).getPath();
+    } else {
+      throw new IllegalStateException("Not a tree model");
+    }
   }
 }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUISheet.java Wed Apr 18 09:04:22 2012
@@ -18,7 +18,6 @@ package org.apache.myfaces.tobago.intern
  */
 
 import org.apache.myfaces.tobago.compat.FacesUtils;
-import org.apache.myfaces.tobago.compat.InvokeOnComponent;
 import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.component.ColumnEvent;
 import org.apache.myfaces.tobago.component.ComponentTypes;
@@ -37,6 +36,7 @@ import org.apache.myfaces.tobago.layout.
 import org.apache.myfaces.tobago.layout.LayoutContainer;
 import org.apache.myfaces.tobago.layout.LayoutManager;
 import org.apache.myfaces.tobago.layout.LayoutTokens;
+import org.apache.myfaces.tobago.model.ExpandedState;
 import org.apache.myfaces.tobago.model.SheetState;
 import org.apache.myfaces.tobago.renderkit.LayoutComponentRenderer;
 import org.apache.myfaces.tobago.util.ComponentUtils;
@@ -44,8 +44,6 @@ import org.apache.myfaces.tobago.util.Cr
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.faces.FacesException;
-import javax.faces.component.ContextCallback;
 import javax.faces.component.UIColumn;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
@@ -60,7 +58,7 @@ import java.util.List;
 import java.util.Map;
 
 public abstract class AbstractUISheet extends AbstractUIData
-    implements SheetStateChangeSource, SortActionSource, InvokeOnComponent, OnComponentPopulated,
+    implements SheetStateChangeSource, SortActionSource, OnComponentPopulated,
     LayoutContainer, LayoutComponent, SupportsRenderedPartially {
 
   private static final Logger LOG = LoggerFactory.getLogger(AbstractUISheet.class);
@@ -264,13 +262,6 @@ public abstract class AbstractUISheet ex
   }
 
   /**
-   * @return Is the (maximum) number of rows to display set to zero?
-   */
-  public boolean isRowsUnlimited() {
-    return getRows() == 0;
-  }
-
-  /**
    * @return Should the paging controls be rendered? Either because of the need of paging or because
    * the show is enforced by {@link #isShowPagingAlways()}
    */
@@ -508,45 +499,6 @@ public abstract class AbstractUISheet ex
     return searchId;
   }
 
-  // todo: after removing jsf 1.1: @Override
-  public boolean invokeOnComponent(FacesContext facesContext, String clientId, ContextCallback callback)
-      throws FacesException {
-    // we may need setRowIndex on UISheet
-    int oldRowIndex = getRowIndex();
-    try {
-      String sheetId = getClientId(facesContext);
-      if (clientId.startsWith(sheetId)) {
-        String idRemainder = clientId.substring(sheetId.length());
-        if (LOG.isDebugEnabled()) {
-          LOG.debug("idRemainder = '" + idRemainder + "'");
-        }
-        if (idRemainder.matches("^:\\d+:.*")) {
-          idRemainder = idRemainder.substring(1);
-          int idx = idRemainder.indexOf(":");
-          try {
-            int rowIndex = Integer.parseInt(idRemainder.substring(0, idx));
-            if (LOG.isDebugEnabled()) {
-              LOG.debug("set rowIndex = '" + rowIndex + "'");
-            }
-            setRowIndex(rowIndex);
-          } catch (NumberFormatException e) {
-            LOG.warn("idRemainder = '" + idRemainder + "'", e);
-          }
-        } else {
-          if (LOG.isDebugEnabled()) {
-            LOG.debug("no match for '^:\\d+:.*'");
-          }
-        }
-      }
-
-      return FacesUtils.invokeOnComponent(facesContext, this, clientId, callback);
-
-    } finally {
-      // we should reset rowIndex on UISheet
-      setRowIndex(oldRowIndex);
-    }
-  }
-
   public void performPaging(PageActionEvent pageEvent) {
 
     int first;
@@ -684,4 +636,10 @@ public abstract class AbstractUISheet ex
   public void setNeedVerticalScrollbar(Boolean needVerticalScrollbar) {
     this.needVerticalScrollbar = needVerticalScrollbar;
   }
+
+  @Override
+  public ExpandedState getExpandedState() {
+    return getState().getExpandedState();
+  }
+
 }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITree.java Wed Apr 18 09:04:22 2012
@@ -19,11 +19,15 @@ package org.apache.myfaces.tobago.intern
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.tobago.compat.FacesUtils;
 import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.internal.util.Deprecation;
 import org.apache.myfaces.tobago.layout.LayoutComponent;
+import org.apache.myfaces.tobago.model.ExpandedState;
+import org.apache.myfaces.tobago.model.MarkedState;
 import org.apache.myfaces.tobago.model.MixedTreeModel;
 import org.apache.myfaces.tobago.model.TreeSelectable;
+import org.apache.myfaces.tobago.model.TreeState;
 import org.apache.myfaces.tobago.util.ComponentUtils;
 
 import javax.faces.component.NamingContainer;
@@ -39,18 +43,20 @@ public abstract class AbstractUITree ext
 
   public static final String MESSAGE_NOT_LEAF = "tobago.tree.MESSAGE_NOT_LEAF";
 
-  /** deprecated since XXX 1.6.0 ??? */
+  /** @deprecated since XXX 1.6.0 ??? */
   @Deprecated
   public static final String SEP = "-";
 
-  /** deprecated since XXX 1.6.0 ??? */
+  /** @deprecated since XXX 1.6.0 ??? */
   @Deprecated
   public static final String SELECT_STATE = SEP + "selectState";
 
-  /** deprecated since XXX 1.6.0 ???  */
+  /** @deprecated since XXX 1.6.0 ???  */
   @Deprecated
   public static final String MARKED = "marked";
 
+  private TreeState state;
+
   @Override
   public void processValidators(FacesContext facesContext) {
     final int last = hasRows() ? getFirst() + getRows() : Integer.MAX_VALUE;
@@ -195,7 +201,49 @@ public abstract class AbstractUITree ext
     // TODO: updating the model here and *NOT* in the decode phase
   }
 */
+  public void setState(TreeState state) {
+    this.state = state;
+  }
 
-  public abstract Object getState();
+  public TreeState getState() {
+    if (state != null) {
+      return state;
+    } else {
+      if (FacesUtils.hasValueBindingOrValueExpression(this, Attributes.STATE)) {
+        final FacesContext facesContext = FacesContext.getCurrentInstance();
+        TreeState state = (TreeState)
+            FacesUtils.getValueFromValueBindingOrValueExpression(facesContext, this, Attributes.STATE);
+        if (state == null) {
+          state = new TreeState(new ExpandedState(2), new MarkedState());
+          FacesUtils.setValueOfBindingOrExpression(facesContext, state, this, Attributes.STATE);
+        }
+        return state;
+      } else {
+        state = new TreeState(new ExpandedState(2), new MarkedState());
+        return state;
+      }
+    }
+  }
 
+  public MarkedState getMarkedState() {
+    return getState().getMarkedState();
+  }
+
+  @Override
+  public ExpandedState getExpandedState() {
+    return getState().getExpandedState();
+  }
+
+  public void restoreState(FacesContext context, Object componentState) {
+    Object[] values = (Object[]) componentState;
+    super.restoreState(context, values[0]);
+    state = (TreeState) values[1];
+  }
+
+  public Object saveState(FacesContext context) {
+    Object[] values = new Object[2];
+    values[0] = super.saveState(context);
+    values[1] = state;
+    return values;
+  }
 }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/component/AbstractUITreeNode.java Wed Apr 18 09:04:22 2012
@@ -17,14 +17,10 @@ package org.apache.myfaces.tobago.intern
  * limitations under the License.
  */
 
-import org.apache.myfaces.tobago.compat.FacesUtils;
-import org.apache.myfaces.tobago.component.Attributes;
 import org.apache.myfaces.tobago.component.SupportsMarkup;
 import org.apache.myfaces.tobago.component.TreeModelBuilder;
 import org.apache.myfaces.tobago.config.Configurable;
-import org.apache.myfaces.tobago.event.TreeExpansionEvent;
 import org.apache.myfaces.tobago.event.TreeExpansionListener;
-import org.apache.myfaces.tobago.event.TreeMarkedEvent;
 import org.apache.myfaces.tobago.event.TreeMarkedListener;
 import org.apache.myfaces.tobago.internal.util.Deprecation;
 import org.apache.myfaces.tobago.model.MixedTreeModel;
@@ -38,8 +34,6 @@ import javax.faces.component.UIData;
 import javax.faces.component.UIOutput;
 import javax.faces.context.FacesContext;
 import javax.faces.el.MethodBinding;
-import javax.faces.event.AbortProcessingException;
-import javax.faces.event.FacesEvent;
 import javax.faces.model.DataModel;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.TreeNode;
@@ -58,7 +52,6 @@ public abstract class AbstractUITreeNode
     DataModel model = data.getDataModel();
     if (model instanceof TreeDataModel) {
       final TreeDataModel treeDataModel = (TreeDataModel) model;
-      treeDataModel.setRowExpanded(isExpandedWithTemporaryState());
       treeDataModel.setRowClientId(getClientId(facesContext));
     }
 
@@ -138,43 +131,6 @@ public abstract class AbstractUITreeNode
     return clientId.substring(dataId.length() + 1);
   }
 
-  @Override
-  public void broadcast(FacesEvent event) throws AbortProcessingException {
-    super.broadcast(event);
-    if (event instanceof TreeExpansionEvent) {
-      FacesUtils.invokeMethodBinding(getFacesContext(), getTreeExpansionListener(), event);
-      boolean expanded = ((TreeExpansionEvent) event).isNewExpanded();
-
-      if (FacesUtils.hasValueBindingOrValueExpression(this, Attributes.EXPANDED)) {
-        try {
-          FacesUtils.setValueOfBindingOrExpression(getFacesContext(), expanded, this, Attributes.EXPANDED);
-          // after processing this, we remove the value, so we'll got the value from the model while rendering
-          ComponentUtils.findAncestor(this, AbstractUIData.class).setSubmittedExpanded(null);
-        } catch (Exception e) {
-          if (LOG.isDebugEnabled()) {
-            LOG.debug("Can't set expanded.", e);
-          }
-        }
-      }
-    }
-    if (event instanceof TreeMarkedEvent) {
-      FacesUtils.invokeMethodBinding(getFacesContext(), getTreeMarkedListener(), event);
-      boolean marked = ((TreeMarkedEvent) event).isNewMarked();
-
-      if (FacesUtils.hasValueBindingOrValueExpression(this, Attributes.MARKED)) {
-        try {
-          FacesUtils.setValueOfBindingOrExpression(getFacesContext(), marked, this, Attributes.MARKED);
-          // after processing this, we remove the value, so we'll got the value from the model while rendering
-          ComponentUtils.findAncestor(this, AbstractUIData.class).setSubmittedMarked(null);
-        } catch (Exception e) {
-          if (LOG.isDebugEnabled()) {
-            LOG.debug("Can't set marked.", e);
-          }
-        }
-      }
-    }
-  }
-
   /**
    * @deprecated since XXX 1.6.0 version???
    */
@@ -205,13 +161,8 @@ public abstract class AbstractUITreeNode
     Deprecation.LOG.error("Doesn't work anymore.");
   }
 
-  /**
-   * @deprecated since XXX 1.6.0 version???
-   */
-  @Deprecated
   public TreePath getPath() {
-    Deprecation.LOG.error("Doesn't work anymore.");
-    return new TreePath(0);
+    return new TreePath(getRowData());
   }
 
   /**
@@ -298,28 +249,4 @@ public abstract class AbstractUITreeNode
   public abstract boolean isSelected();
 
   public abstract void setSelected(boolean selected);
-
-  // XXX is introduced temporarily:
-  @Deprecated
-  public boolean isMarkedWithTemporaryState() {
-    final AbstractUIData data = ComponentUtils.findAncestor(this, AbstractUIData.class);
-    final Integer submittedMarked = data.getSubmittedMarked();
-    if (submittedMarked != null) {
-      return submittedMarked.equals(data.getRowIndex());
-    }
-    return isMarked();
-  }
-
-  // XXX is introduced temporarily:
-  @Deprecated
-  public boolean isExpandedWithTemporaryState() {
-    final AbstractUIData data = ComponentUtils.findAncestor(this, AbstractUIData.class);
-    final List<Integer> submittedExpanded = data.getSubmittedExpanded();
-    if (submittedExpanded != null) {
-      return submittedExpanded.contains(data.getRowIndex());
-    }
-    return isExpanded();
-  }
-
-
 }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeListboxTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeListboxTagDeclaration.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeListboxTagDeclaration.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeListboxTagDeclaration.java Wed Apr 18 09:04:22 2012
@@ -66,11 +66,10 @@ public interface TreeListboxTagDeclarati
   /**
    * <strong>ValueBindingExpression</strong> pointing to a object to save the
    * component's state.
-   *
-   * @deprecated since XXX 1.6.0 ???
    */
-  @Deprecated
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Object", expression = DynamicExpression.VALUE_BINDING_REQUIRED)
+  @UIComponentTagAttribute(
+      type = "org.apache.myfaces.tobago.model.TreeState",
+      expression = DynamicExpression.VALUE_BINDING_REQUIRED)
   void setState(String state);
 }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeMenuTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeMenuTagDeclaration.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeMenuTagDeclaration.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeMenuTagDeclaration.java Wed Apr 18 09:04:22 2012
@@ -27,6 +27,8 @@ import org.apache.myfaces.tobago.compone
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasCurrentMarkup;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasIdBindingAndRendered;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasMarkup;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
+import org.apache.myfaces.tobago.internal.taglib.declaration.HasVar;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsGridLayoutComponent;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsShowRoot;
 
@@ -45,18 +47,18 @@ import org.apache.myfaces.tobago.interna
         "org.apache.myfaces.tobago.TreeData"
         })
 public interface TreeMenuTagDeclaration
-    extends HasIdBindingAndRendered, IsGridLayoutComponent, HasMarkup, HasCurrentMarkup, IsShowRoot {
+    extends HasIdBindingAndRendered, HasValue, HasVar, IsGridLayoutComponent, HasMarkup, HasCurrentMarkup,
+    IsShowRoot {
 
   /**
    *
    * <strong>ValueBindingExpression</strong> pointing to a object to save the
    * component's state.
-   *
-   * @deprecated since XXX 1.6.0 ???
    */
-  @Deprecated
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Object", expression = DynamicExpression.VALUE_BINDING_REQUIRED)
+  @UIComponentTagAttribute(
+      type = "org.apache.myfaces.tobago.model.TreeState",
+      expression = DynamicExpression.VALUE_BINDING_REQUIRED)
   void setState(String state);
 
 }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeNodeTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeNodeTagDeclaration.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeNodeTagDeclaration.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeNodeTagDeclaration.java Wed Apr 18 09:04:22 2012
@@ -51,21 +51,27 @@ public interface
 
   /**
    * Flag indicating if the subnodes are to be displayed.
+   * @deprecated since XXX 1.6.0 ??? Please use the state attribute of the tree with a TreeState
    */
+  @Deprecated
   @TagAttribute()
   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setExpanded(String expanded);
 
   /**
    * Flag indicating if the node is marked, and should be displayed in a special way.
+   * @deprecated since XXX 1.6.0 ??? Please use the state attribute of the tree with a TreeState
    */
+  @Deprecated
   @TagAttribute()
   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setMarked(String marked);
 
   /**
    * Flag indicating if the node is selected (only possible, when the tree component allows it).
+   * @deprecated since XXX 1.6.0 ??? Please use <code>&lt;tc:treeSelect></code>
    */
+  @Deprecated
   @TagAttribute()
   @UIComponentTagAttribute(type = "boolean", defaultValue = "false")
   void setSelected(String selected);

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeTagDeclaration.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeTagDeclaration.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeTagDeclaration.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/internal/taglib/component/TreeTagDeclaration.java Wed Apr 18 09:04:22 2012
@@ -30,7 +30,6 @@ import org.apache.myfaces.tobago.interna
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasValue;
 import org.apache.myfaces.tobago.internal.taglib.declaration.HasVar;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsGridLayoutComponent;
-import org.apache.myfaces.tobago.internal.taglib.declaration.IsRequired;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsShowRoot;
 import org.apache.myfaces.tobago.internal.taglib.declaration.IsShowRootJunction;
 
@@ -49,7 +48,7 @@ import org.apache.myfaces.tobago.interna
         "org.apache.myfaces.tobago.TreeData"
         })
 public interface TreeTagDeclaration
-    extends HasIdBindingAndRendered, HasValue, HasVar, IsRequired, IsGridLayoutComponent, HasMarkup, HasCurrentMarkup,
+    extends HasIdBindingAndRendered, HasValue, HasVar, IsGridLayoutComponent, HasMarkup, HasCurrentMarkup,
     IsShowRoot, IsShowRootJunction {
 
   /**
@@ -74,11 +73,10 @@ public interface TreeTagDeclaration
    *
    * <strong>ValueBindingExpression</strong> pointing to a object to save the
    * component's state.
-   *
-   * @deprecated since XXX 1.6.0 ???
    */
-  @Deprecated
   @TagAttribute
-  @UIComponentTagAttribute(type = "java.lang.Object", expression = DynamicExpression.VALUE_BINDING_REQUIRED)
+  @UIComponentTagAttribute(
+      type = "org.apache.myfaces.tobago.model.TreeState",
+      expression = DynamicExpression.VALUE_BINDING_REQUIRED)
   void setState(String state);
 }

Added: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/ExpandedState.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/ExpandedState.java?rev=1327429&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/ExpandedState.java (added)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/ExpandedState.java Wed Apr 18 09:04:22 2012
@@ -0,0 +1,79 @@
+package org.apache.myfaces.tobago.model;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ExpandedState implements Serializable {
+
+  private int defaultExpandedLevels;
+  private Set<TreePath> expandedSet;
+  private Set<TreePath> collapsedSet;
+
+  public ExpandedState(int defaultExpandedLevels) {
+    this.defaultExpandedLevels = defaultExpandedLevels;
+    this.expandedSet = new HashSet<TreePath>();
+    this.collapsedSet = new HashSet<TreePath>();
+  }
+
+  private static final Logger LOG = LoggerFactory.getLogger(ExpandedState.class);
+
+  // todo: remove
+  @Deprecated
+  public boolean isExpanded(DefaultMutableTreeNode node) {
+    final TreePath path = new TreePath(node);
+    return isExpanded(path);
+  }
+
+  public boolean isExpanded(TreePath path) {
+    if (expandedSet.contains(path)) {
+      return true;
+    }
+    if (collapsedSet.contains(path)) {
+      return false;
+    }
+    return path.getLength() < defaultExpandedLevels;
+  }
+
+  // todo: remove
+  @Deprecated
+  public void expand(DefaultMutableTreeNode node) {
+    final TreePath path = new TreePath(node);
+    expand(path);
+  }
+
+  public void expand(TreePath path) {
+    if (path.getLength() >= defaultExpandedLevels) {
+      expandedSet.add(path);
+    } else {
+      collapsedSet.remove(path);
+    }
+  }
+
+  // todo: remove
+  @Deprecated
+  public void collapse(DefaultMutableTreeNode node) {
+    final TreePath path = new TreePath(node);
+    collapse(path);
+  }
+
+  public void collapse(TreePath path) {
+    if (path.getLength() < defaultExpandedLevels) {
+      collapsedSet.add(path);
+    } else {
+      expandedSet.remove(path);
+    }
+  }
+
+  public Set<TreePath> getExpandedSet() {
+    return expandedSet;
+  }
+
+  public Set<TreePath> getCollapsedSet() {
+    return collapsedSet;
+  }
+}

Added: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/MarkedState.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/MarkedState.java?rev=1327429&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/MarkedState.java (added)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/MarkedState.java Wed Apr 18 09:04:22 2012
@@ -0,0 +1,24 @@
+package org.apache.myfaces.tobago.model;
+
+import java.io.Serializable;
+
+public class MarkedState implements Serializable {
+
+  private TreePath marked;
+
+  public boolean isMarked(TreePath path) {
+    if (marked != null) {
+      return marked.equals(path);
+    } else {
+      return marked == path; // == null
+    }
+  }
+
+  public TreePath getMarked() {
+    return marked;
+  }
+
+  public void setMarked(TreePath marked) {
+    this.marked = marked;
+  }
+}

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Node.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Node.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Node.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/Node.java Wed Apr 18 09:04:22 2012
@@ -21,7 +21,10 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-
+/**
+ * @deprecated since XXX 1.6.0 ???
+ */
+@Deprecated
 public class Node {
 
   private List<Node> children;

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/SheetState.java Wed Apr 18 09:04:22 2012
@@ -27,10 +27,12 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-// TODO find a better solution for this
 public class SheetState implements Serializable {
+
   private static final long serialVersionUID = 7765536344426661777L;
+
   private static final Logger LOG = LoggerFactory.getLogger(SheetState.class);
+
   public static final String SEPARATOR = ",";
 
   private int first = -1;
@@ -39,6 +41,7 @@ public class SheetState implements Seria
   private String columnWidths;
   private List<Integer> selectedRows;
   private Integer[] scrollPosition;
+  private ExpandedState expandedState;
 
   public SheetState() {
     resetSelected();
@@ -109,6 +112,17 @@ public class SheetState implements Seria
     this.scrollPosition = scrollPosition;
   }
 
+  public ExpandedState getExpandedState() {
+    if (expandedState == null) {
+      expandedState = new ExpandedState(2);
+    }
+    return expandedState;
+  }
+
+  public void setExpandedState(ExpandedState expandedState) {
+    this.expandedState = expandedState;
+  }
+
   public static Integer[] parseScrollPosition(String value) {
     Integer[] position = null;
     if (!StringUtils.isBlank(value)) {

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeDataModel.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeDataModel.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeDataModel.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeDataModel.java Wed Apr 18 09:04:22 2012
@@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
 
 import javax.faces.model.DataModel;
 import javax.swing.tree.DefaultMutableTreeNode;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -35,24 +34,75 @@ public class TreeDataModel extends DataM
   private Map<Integer, Data> mapping;
   private Map<DefaultMutableTreeNode, Integer> back;
   private boolean showRoot;
+  private ExpandedState expandedState;
 
-  public TreeDataModel(DefaultMutableTreeNode data, boolean showRoot) {
+  /**
+   * @param data          The tree data, which shall be wrapped.
+   * @param showRoot      Is the root node visible.
+   * @param expandedState Defines which nodes are expanded, (XXX should it be so?) a value of {@code null} means all.
+   */
+  public TreeDataModel(DefaultMutableTreeNode data, boolean showRoot, ExpandedState expandedState) {
     this.data = data;
     this.showRoot = showRoot;
-    init();
+    this.mapping = new HashMap<Integer, Data>();
+    this.back = new HashMap<DefaultMutableTreeNode, Integer>();
+    this.expandedState = expandedState;
+    reset();
+  }
+
+  public void reset(/*ExpandedState expandedState*/) {
+//    this.expandedState = expandedState;
+    this.mapping.clear();
+    this.back.clear();
+    DefaultMutableTreeNode current = data;
+    for (int counter = back.size(); current != null; counter++) {
+
+      mapping.put(counter, new Data(current));
+      back.put(current, counter);
+
+      // if the node has children and is expanded, go to the children
+      if (current.getChildCount() > 0 && expandedState.isExpanded(current)) {
+        current = (DefaultMutableTreeNode) current.getChildAt(0);
+      } else {
+        current = getNextNodeButNoChild(current);
+      }
+    }
+  }
+
+  public void update(ExpandedState expandedState) {
+    this.expandedState = expandedState;
+    DefaultMutableTreeNode current = data;
+    for (int counter = back.size(); current != null; ) {
+
+      if (!back.containsKey(current)) {
+        mapping.put(counter, new Data(current));
+        back.put(current, counter);
+        counter++;
+      }
+
+      // if the node has children and is expanded, go to the children
+      if (current.getChildCount() > 0 && expandedState.isExpanded(current)) {
+        current = (DefaultMutableTreeNode) current.getChildAt(0);
+      } else {
+        current = getNextNodeButNoChild(current);
+      }
+    }
   }
 
-  private void init() {
-    mapping = new HashMap<Integer, Data>();
-    back = new HashMap<DefaultMutableTreeNode, Integer>();
-    int counter = 0;
-    final Enumeration enumeration = data.preorderEnumeration();
-    while (enumeration.hasMoreElements()) {
-      DefaultMutableTreeNode node = (DefaultMutableTreeNode) enumeration.nextElement();
-      mapping.put(counter, new Data(node));
-      back.put(node, counter);
-      counter++;
+  private DefaultMutableTreeNode getNextNodeButNoChild(DefaultMutableTreeNode node) {
+    DefaultMutableTreeNode next;
+    while (true) {
+      next = node.getNextSibling();
+      if (next != null) {
+        break;
+      }
+      node = (DefaultMutableTreeNode) node.getParent();
+      if (node == null) {
+        return null;
+      }
+
     }
+    return next;
   }
 
   @Override
@@ -70,6 +120,10 @@ public class TreeDataModel extends DataM
     return rowIndex;
   }
 
+  public TreePath getPath() {
+    return new TreePath(getRowData());
+  }
+
   @Override
   public Object getWrappedData() {
     return data;
@@ -90,14 +144,6 @@ public class TreeDataModel extends DataM
     this.data = (DefaultMutableTreeNode) data;
   }
 
-  public boolean isRowExpanded() {
-    return mapping.get(rowIndex).isExpanded();
-  }
-
-  public void setRowExpanded(boolean expanded) {
-    mapping.get(rowIndex).setExpanded(expanded);
-  }
-
   public boolean isRowVisible() {
     if (!isRowAvailable()) {
       return false;
@@ -112,7 +158,7 @@ public class TreeDataModel extends DataM
       if (data.getNode().isRoot() && !showRoot) {
         return true;
       }
-      if (!data.isExpanded()) {
+      if (!expandedState.isExpanded(new TreePath(node))) {
         return false;
       }
       node = (DefaultMutableTreeNode) node.getParent();
@@ -149,7 +195,7 @@ public class TreeDataModel extends DataM
     }
   }
 
-  
+
   /**
    * Here we cache some state information of the nodes, because we can't access the UITreeNode state of the other nodes
    * while rendering.
@@ -157,7 +203,6 @@ public class TreeDataModel extends DataM
   private static class Data {
 
     private DefaultMutableTreeNode node;
-    private boolean expanded;
     private String clientId;
 
     private Data(DefaultMutableTreeNode node) {
@@ -168,14 +213,6 @@ public class TreeDataModel extends DataM
       return node;
     }
 
-    public boolean isExpanded() {
-      return expanded;
-    }
-
-    public void setExpanded(boolean expanded) {
-      this.expanded = expanded;
-    }
-
     public String getClientId() {
       return clientId;
     }

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreePath.java Wed Apr 18 09:04:22 2012
@@ -20,44 +20,84 @@ package org.apache.myfaces.tobago.model;
 import org.apache.myfaces.tobago.internal.util.StringUtils;
 
 import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.List;
 
 /**
  * Handles a path in a tree from the root node to the position inside this tree.
- *
+ * The position of the root node is dropped in the list, because it would always be zero.
+ * The path of the root node as length 0.
+ * <p/>
+ * Example:
+ * <pre>
+ *  + Root               Path: []
+ *  |
+ *  +-+ Node             Path: [0]
+ *  | |
+ *  | +-+ Sub-Node       Path: [0, 0]
+ *  | |
+ *  | +-+ Sub-Node       Path: [0, 1]
+ *  |
+ *  +-+ Node             Path: [1]
+ *    |
+ *    +-+ Sub-Node       Path: [1, 0]
+ *    |
+ *    +-+ Sub-Node       Path: [1, 1]
+ *    |
+ *    +-+ Sub-Node       Path: [1, 2]
+ * </pre>
  * @since 1.5.0
- * @deprecated
  */
-@Deprecated
 public class TreePath implements Serializable {
 
-  private int[] path;
+  private final int[] path;
 
   public TreePath(int... path) {
-    assert path[0] == 0;
     this.path = path;
   }
 
   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);
     }
   }
 
+  /**
+   * @deprecated since XXX 1.6.0 ???
+   */
+  @Deprecated
   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;
   }
 
+  /**
+   * @deprecated since XXX 1.6.0 ???
+   */
+  @Deprecated
   public TreePath(String string) throws NumberFormatException {
     this(StringUtils.parseIntegerList(string, "_"));
   }
 
+  public TreePath(DefaultMutableTreeNode node) {
+    final TreeNode[] treeNodePath = node.getPath();
+    final int n = treeNodePath.length - 1;
+    path = new int[n];
+    int i = 0;
+    for (TreeNode t : treeNodePath) {
+      DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) t;
+      DefaultMutableTreeNode parent = (DefaultMutableTreeNode) treeNode.getParent();
+      if (parent != null) {
+        path[i] = parent.getIndex(treeNode);
+        i++;
+      }
+    }
+  }
+
   public int[] getPath() {
     return path;
   }
@@ -66,6 +106,9 @@ public class TreePath implements Seriali
     return path.length;
   }
 
+  /**
+   * @deprecated since XXX 1.6.0 ???
+   */
   public String getPathString() {
     StringBuilder builder = new StringBuilder();
     for (int item : path) {
@@ -90,7 +133,9 @@ public class TreePath implements Seriali
    * 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.
+   * @deprecated since XXX 1.6.0 ???
    */
+  @Deprecated
   public DefaultMutableTreeNode getNode(DefaultMutableTreeNode tree) {
     if (tree == null) {
       return null;
@@ -125,6 +170,6 @@ public class TreePath implements Seriali
 
   @Override
   public String toString() {
-    return getPathString();
+    return Arrays.toString(path);
   }
 }

Added: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java?rev=1327429&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java (added)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/main/java/org/apache/myfaces/tobago/model/TreeState.java Wed Apr 18 09:04:22 2012
@@ -0,0 +1,22 @@
+package org.apache.myfaces.tobago.model;
+
+import java.io.Serializable;
+
+public class TreeState implements Serializable {
+  
+  private ExpandedState expandedState;
+  private MarkedState markedState;
+
+  public TreeState(ExpandedState expandedState, MarkedState markedState) {
+    this.expandedState = expandedState;
+    this.markedState = markedState;
+  }
+
+  public ExpandedState getExpandedState() {
+    return expandedState;
+  }
+
+  public MarkedState getMarkedState() {
+    return markedState;
+  }
+}

Added: myfaces/tobago/branches/tobago-tree-table/tobago-core/src/test/java/org/apache/myfaces/tobago/model/ExpandedStateUnitTest.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-core/src/test/java/org/apache/myfaces/tobago/model/ExpandedStateUnitTest.java?rev=1327429&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-core/src/test/java/org/apache/myfaces/tobago/model/ExpandedStateUnitTest.java (added)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-core/src/test/java/org/apache/myfaces/tobago/model/ExpandedStateUnitTest.java Wed Apr 18 09:04:22 2012
@@ -0,0 +1,134 @@
+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 org.junit.Assert;
+import org.junit.Test;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+public class ExpandedStateUnitTest {
+
+  /**
+   * <pre>
+   *  + root
+   *  |
+   *  +-+ a
+   *  | |
+   *  | +-+ a1
+   *  | |
+   *  | +-+ a2
+   *  | |
+   *  | +-+ a3
+   *  |
+   *  +-+ b
+   *  | |
+   *  | +-+ b1
+   *  | |
+   *  | +-+ b2
+   *  | |
+   *  | +-+ b3
+   *  |
+   *  +-+ c
+   *    |
+   *    +-+ c1
+   *    |
+   *    +-+ c2
+   *    |
+   *    +-+ c3
+   *
+   * </pre>
+   */
+  @Test
+  public void test() {
+
+    DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
+
+    DefaultMutableTreeNode a = new DefaultMutableTreeNode("a");
+    DefaultMutableTreeNode b = new DefaultMutableTreeNode("b");
+    DefaultMutableTreeNode c = new DefaultMutableTreeNode("c");
+    root.add(a);
+    root.add(b);
+    root.add(c);
+
+    DefaultMutableTreeNode a1 = new DefaultMutableTreeNode("a1");
+    DefaultMutableTreeNode a2 = new DefaultMutableTreeNode("a2");
+    DefaultMutableTreeNode a3 = new DefaultMutableTreeNode("a3");
+    DefaultMutableTreeNode b1 = new DefaultMutableTreeNode("b1");
+    DefaultMutableTreeNode b2 = new DefaultMutableTreeNode("b2");
+    DefaultMutableTreeNode b3 = new DefaultMutableTreeNode("b3");
+    DefaultMutableTreeNode c1 = new DefaultMutableTreeNode("c1");
+    DefaultMutableTreeNode c2 = new DefaultMutableTreeNode("c2");
+    DefaultMutableTreeNode c3 = new DefaultMutableTreeNode("c3");
+
+    a.add(a1);
+    a.add(a2);
+    a.add(a3);
+    b.add(b1);
+    b.add(b2);
+    b.add(b3);
+    c.add(c1);
+    c.add(c2);
+    c.add(c3);
+
+    ExpandedState state = new ExpandedState(2);
+
+    Assert.assertTrue(state.isExpanded(root));
+    Assert.assertTrue(state.isExpanded(a));
+    Assert.assertTrue(state.isExpanded(b));
+    Assert.assertTrue(state.isExpanded(c));
+    Assert.assertFalse(state.isExpanded(a1));
+    Assert.assertFalse(state.isExpanded(a2));
+    Assert.assertFalse(state.isExpanded(a3));
+    Assert.assertFalse(state.isExpanded(b1));
+    Assert.assertFalse(state.isExpanded(b2));
+    Assert.assertFalse(state.isExpanded(b3));
+    Assert.assertFalse(state.isExpanded(c1));
+    Assert.assertFalse(state.isExpanded(c2));
+    Assert.assertFalse(state.isExpanded(c3));
+
+    state.expand(a);
+    state.expand(a1);
+    state.expand(a2);
+    state.expand(c);
+
+    state.collapse(root);
+    state.collapse(b);
+    state.collapse(b3);
+    state.collapse(a2);
+    state.collapse(c);
+
+    Assert.assertFalse(state.isExpanded(root));
+    Assert.assertTrue(state.isExpanded(a));
+    Assert.assertFalse(state.isExpanded(b));
+    Assert.assertFalse(state.isExpanded(c));
+    Assert.assertTrue(state.isExpanded(a1));
+    Assert.assertFalse(state.isExpanded(a2));
+    Assert.assertFalse(state.isExpanded(a3));
+    Assert.assertFalse(state.isExpanded(b1));
+    Assert.assertFalse(state.isExpanded(b2));
+    Assert.assertFalse(state.isExpanded(b3));
+    Assert.assertFalse(state.isExpanded(c1));
+    Assert.assertFalse(state.isExpanded(c2));
+    Assert.assertFalse(state.isExpanded(c3));
+
+    Assert.assertEquals(1, state.getExpandedSet().size());
+    Assert.assertEquals(3, state.getCollapsedSet().size());
+
+  }
+}

Added: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-data/src/main/java/org/apache/myfaces/tobago/example/data/CantorInterval.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-data/src/main/java/org/apache/myfaces/tobago/example/data/CantorInterval.java?rev=1327429&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-data/src/main/java/org/apache/myfaces/tobago/example/data/CantorInterval.java (added)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-data/src/main/java/org/apache/myfaces/tobago/example/data/CantorInterval.java Wed Apr 18 09:04:22 2012
@@ -0,0 +1,148 @@
+package org.apache.myfaces.tobago.example.data;
+
+/*
+ * 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 javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.TreeNode;
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+/**
+ * Builds a tree with the iterations of the <a href="http://en.wikipedia.org/wiki/Cantor_set">Cantor set</a>.
+ * The tree is infinitive, so it will be created on the fly.
+ */
+public class CantorInterval extends DefaultMutableTreeNode {
+
+  private Fraction begin;
+  private Fraction end;
+  private boolean initialized;
+
+  public CantorInterval() {
+    begin = Fraction.ZERO;
+    end = Fraction.ONE;
+  }
+
+  private CantorInterval(Fraction begin, Fraction end) {
+    this.begin = begin;
+    this.end = end;
+  }
+
+  // init must be lazy, because the tree is infinite
+  private void init() {
+    if (!initialized) {
+      initialized = true; // add() will call getChildCount()!
+      final Fraction subtract = end.subtract(begin);
+      final Fraction multiply = subtract.multiply(Fraction.ONE_THIRD);
+      final Fraction oneThird = multiply.add(begin);
+      add(new CantorInterval(begin, oneThird));
+
+      Fraction twoThird = end.subtract(begin).multiply(Fraction.TWO_THIRDS).add(begin);
+      add(new CantorInterval(twoThird, end));
+    }
+  }
+
+  @Override
+  public int getChildCount() {
+    init();
+    return super.getChildCount();
+  }
+
+  @Override
+  public TreeNode getChildAt(int i) {
+    init();
+    return super.getChildAt(i);
+  }
+
+  @Override
+  public Enumeration children() {
+    init();
+    return super.children();
+  }
+
+  public String getLabel() {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    builder.append(begin);
+    builder.append(", ");
+    builder.append(end);
+    builder.append("]");
+    return builder.toString();
+  }
+
+  public String toString() {
+    return getLabel();
+  }
+
+  public static final class Fraction {
+
+    private final BigInteger numerator;
+    private final BigInteger denominator;
+
+    public static final Fraction ZERO = new Fraction(0);
+    public static final Fraction ONE = new Fraction(1);
+    public static final BigInteger THREE = BigInteger.valueOf(3);
+    public static final Fraction ONE_THIRD = new Fraction(BigInteger.ONE, THREE);
+    public static final Fraction TWO_THIRDS = new Fraction(BigInteger.valueOf(2), THREE);
+
+    private Fraction(long i) {
+      numerator = BigInteger.valueOf(i);
+      denominator = BigInteger.ONE;
+    }
+
+    private Fraction(BigInteger numerator, BigInteger denominator) {
+      while (numerator.remainder(THREE).equals(BigInteger.ZERO)
+          && denominator.remainder(THREE).equals(BigInteger.ZERO)) {
+        numerator = numerator.divide(THREE);
+        denominator = denominator.divide(THREE);
+      }
+      this.numerator = numerator;
+      this.denominator = denominator;
+    }
+
+    public Fraction add(Fraction value) {
+      return new Fraction(
+          numerator.multiply(value.denominator).add(denominator.multiply(value.numerator)),
+          denominator.multiply(value.denominator));
+    }
+
+    public Fraction subtract(Fraction value) {
+      return new Fraction(
+          numerator.multiply(value.denominator).subtract(denominator.multiply(value.numerator)),
+          denominator.multiply(value.denominator));
+    }
+
+    public Fraction multiply(Fraction value) {
+      return new Fraction(
+          numerator.multiply(value.numerator),
+          denominator.multiply(value.denominator));
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder builder = new StringBuilder();
+      if (denominator.equals(BigInteger.ONE)) {
+        builder.append(numerator);
+      } else {
+        builder.append(numerator);
+        builder.append("/");
+        builder.append(denominator);
+      }
+      return builder.toString();
+    }
+  }
+}

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Navigation.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Navigation.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Navigation.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/java/org/apache/myfaces/tobago/example/demo/Navigation.java Wed Apr 18 09:04:22 2012
@@ -20,6 +20,9 @@ package org.apache.myfaces.tobago.exampl
 import org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowScoped;
 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
 import org.apache.myfaces.tobago.example.demo.jsp.JspFormatter;
+import org.apache.myfaces.tobago.model.ExpandedState;
+import org.apache.myfaces.tobago.model.MarkedState;
+import org.apache.myfaces.tobago.model.TreeState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -53,6 +56,7 @@ public class Navigation implements Seria
   private Node tree;
 
   private Node currentNode;
+  private TreeState state = new TreeState(new ExpandedState(1), new MarkedState());
 
   public Navigation() {
       final ServletContext servletContext
@@ -206,6 +210,10 @@ public class Navigation implements Seria
     return null;
   }
 
+  public Object getState() {
+    return state;
+  }
+
 
   public class Node extends DefaultMutableTreeNode implements Comparable {
 

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/webapp/navigation.xhtml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/webapp/navigation.xhtml?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/webapp/navigation.xhtml (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-demo/src/main/webapp/navigation.xhtml Wed Apr 18 09:04:22 2012
@@ -20,8 +20,8 @@
 <f:subview id="navigator"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:tc="http://myfaces.apache.org/tobago/component">
-  <tc:treeMenu id="nav" value="#{navigation.tree}" var="node">
-    <tc:treeNode expanded="#{node.expanded}" marked="#{node.marked}" id="node">
+  <tc:treeMenu id="nav" value="#{navigation.tree}" var="node" state="#{navigation.state}">
+    <tc:treeNode id="node">
       <tc:treeCommand
           id="cmd"
           label="#{node.title}"

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TestPageFilter.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TestPageFilter.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TestPageFilter.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TestPageFilter.java Wed Apr 18 09:04:22 2012
@@ -75,6 +75,7 @@ public class TestPageFilter {
       "/tc/gridLayout/tabGroup-.*", // todo: measurement problem with firefox?
       "/tc/gridLayout/transparent-for-layout.jspx", // uses facelets templating
       "/tc/mediator/tomahawk-inputHtml.*", // todo
+      "/tc/treeListbox/*", // todo
       "/tx/label/label.xhtml", // todo
       "/type/.*" // todo
   ));

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TreeController.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TreeController.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TreeController.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/java/org/apache/myfaces/tobago/example/test/TreeController.java Wed Apr 18 09:04:22 2012
@@ -17,10 +17,14 @@ package org.apache.myfaces.tobago.exampl
  * limitations under the License.
  */
 
+import org.apache.myfaces.tobago.example.data.CantorInterval;
 import org.apache.myfaces.tobago.example.data.CategoryTree;
 import org.apache.myfaces.tobago.example.data.Node;
 import org.apache.myfaces.tobago.example.data.SmallTree;
+import org.apache.myfaces.tobago.model.ExpandedState;
+import org.apache.myfaces.tobago.model.MarkedState;
 import org.apache.myfaces.tobago.model.TreeDataModel;
+import org.apache.myfaces.tobago.model.TreeState;
 
 import javax.swing.tree.DefaultMutableTreeNode;
 
@@ -29,8 +33,16 @@ public class TreeController {
   private DefaultMutableTreeNode tree = CategoryTree.createSample();
 
   private DefaultMutableTreeNode small = SmallTree.createSample();
+  
+  private TreeState state = new TreeState(new ExpandedState(1), new MarkedState());
 
-  private TreeDataModel treeInSheet = new TreeDataModel(tree, false);
+  private TreeDataModel treeInSheet = new TreeDataModel(tree, false, state.getExpandedState());
+
+  private CantorInterval infinite = new CantorInterval();
+
+  public TreeController() {
+    state.getExpandedState().expand(tree);
+  }
 
   public DefaultMutableTreeNode getTree() {
     return tree;
@@ -44,6 +56,10 @@ public class TreeController {
     return treeInSheet;
   }
 
+  public TreeState getState() {
+    return state;
+  }
+
   public String openAll() {
     openAll(tree);
     return null;
@@ -55,4 +71,8 @@ public class TreeController {
       openAll((DefaultMutableTreeNode)node.getChildAt(i));
     }
   }
+
+  public CantorInterval getInfinite() {
+    return infinite;
+  }
 }

Copied: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-infinite.xhtml (from r1324674, myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml)
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-infinite.xhtml?p2=myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-infinite.xhtml&p1=myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml&r1=1324674&r2=1327429&rev=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-infinite.xhtml Wed Apr 18 09:04:22 2012
@@ -18,22 +18,26 @@
 
 <f:view
     xmlns:tc="http://myfaces.apache.org/tobago/component"
-    xmlns:tx="http://myfaces.apache.org/tobago/extension"
-    xmlns:ui="http://java.sun.com/jsf/facelets"
     xmlns:f="http://java.sun.com/jsf/core">
 
   <tc:page id="page">
-    <tc:gridLayoutConstraint width="600px" height="300px"/>
+    <tc:gridLayoutConstraint width="600px" height="600px"/>
     <f:facet name="layout">
-      <tc:gridLayout rows="auto;*"/>
+      <tc:gridLayout rows="20px;*"/>
     </f:facet>
 
-    <tc:out value="Simple tree:"/>
+    <tc:panel>
+      <f:facet name="layout">
+        <tc:flowLayout/>
+      </f:facet>
+      <tc:out value="Infinite tree, showing the "/>
+      <tc:link label="Cantor set" link="http://en.wikipedia.org/wiki/Cantor_set"/>
+    </tc:panel>
 
-    <tc:tree id="tree" value="#{tree.tree}" var="node" showRoot="true" showRootJunction="true">
-      <tc:treeNode id="node" expanded="#{node.level ne 1}">
+    <tc:tree id="tree" value="#{tree.infinite}" var="interval" showRoot="true" showRootJunction="true">
+      <tc:treeNode id="node">
         <tc:treeIndent/>
-        <tc:treeLabel value="#{node.userObject.name}"/>
+        <tc:treeLabel value="#{interval.label}"/>
       </tc:treeNode>
     </tc:tree>
 

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-example/tobago-example-test/src/main/webapp/tc/tree/tree-simple.xhtml Wed Apr 18 09:04:22 2012
@@ -18,8 +18,6 @@
 
 <f:view
     xmlns:tc="http://myfaces.apache.org/tobago/component"
-    xmlns:tx="http://myfaces.apache.org/tobago/extension"
-    xmlns:ui="http://java.sun.com/jsf/facelets"
     xmlns:f="http://java.sun.com/jsf/core">
 
   <tc:page id="page">
@@ -30,7 +28,8 @@
 
     <tc:out value="Simple tree:"/>
 
-    <tc:tree id="tree" value="#{tree.tree}" var="node" showRoot="true" showRootJunction="true">
+    <tc:tree id="tree" value="#{tree.tree}" var="node" showRoot="true" showRootJunction="true"
+             state="#{tree.state}">
       <tc:treeNode id="node" expanded="#{node.level ne 1}">
         <tc:treeIndent/>
         <tc:treeLabel value="#{node.userObject.name}"/>

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/SheetRenderer.java Wed Apr 18 09:04:22 2012
@@ -223,9 +223,7 @@ public class SheetRenderer extends Layou
       writer.writeNameAttribute(expandedId);
       writer.writeIdAttribute(expandedId);
       writer.writeClassAttribute(Classes.create(sheet, AbstractUIData.SUFFIX_EXPANDED));
-      final List<Integer> value = sheet.getSubmittedExpanded();
-      writer.writeAttribute(
-          HtmlAttributes.VALUE, value != null ? StringUtils.joinWithSurroundingSeparator(value) : "", false);
+      writer.writeAttribute(HtmlAttributes.VALUE, ",", false);
       writer.endElement(HtmlElements.INPUT);
     }
 
@@ -604,17 +602,7 @@ public class SheetRenderer extends Layou
       }
     }
 
-    if (sheet.isTreeModel()) {
-      // expanded
-      String expanded = (String) facesContext.getExternalContext().getRequestParameterMap()
-          .get(sheet.getClientId(facesContext) + ComponentUtils.SUB_SEPARATOR + AbstractUIData.SUFFIX_EXPANDED);
-      try {
-        sheet.setSubmittedExpanded(expanded != null ? StringUtils.parseIntegerList(expanded) : null);
-      } catch (NumberFormatException e) {
-        // should not happen
-        LOG.warn("Can't parse expanded: + " + expanded + "'", e);
-      }
-    }
+    RenderUtils.decodedStateOfTreeData(facesContext, sheet);
   }
 
   private Measure getHeaderHeight(FacesContext facesContext, UISheet sheet) {

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIconRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIconRenderer.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIconRenderer.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIconRenderer.java Wed Apr 18 09:04:22 2012
@@ -22,6 +22,7 @@ import org.apache.myfaces.tobago.compone
 import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
 import org.apache.myfaces.tobago.context.ResourceUtils;
+import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -48,9 +49,10 @@ public class TreeIconRenderer extends La
   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
 
     final UITreeIcon image = (UITreeIcon) component;
+    final AbstractUIData data = ComponentUtils.findAncestor(image, AbstractUIData.class);
     final UITreeNode node = ComponentUtils.findAncestor(image, UITreeNode.class);
     final boolean folder = node.isFolder();
-    final boolean expanded = folder && node.isExpandedWithTemporaryState();
+    final boolean expanded = folder && data.getExpandedState().isExpanded(node.getPath());
 
     String source;
     final String openSource;

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIndentRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIndentRenderer.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIndentRenderer.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeIndentRenderer.java Wed Apr 18 09:04:22 2012
@@ -53,7 +53,7 @@ public class TreeIndentRenderer extends 
     final boolean showRoot = data.isShowRoot();
     final boolean showJunctions = indent.isShowJunctions();
     final boolean showRootJunction = data.isShowRootJunction();
-    final boolean expanded = folder && node.isExpandedWithTemporaryState();
+    final boolean expanded = folder && data.getExpandedState().isExpanded(node.getPath());
     final boolean showLines = showJunctions && data instanceof UITree; // sheet should not show lines
     final boolean showIcons = showJunctions;
 

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeMenuNodeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeMenuNodeRenderer.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeMenuNodeRenderer.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeMenuNodeRenderer.java Wed Apr 18 09:04:22 2012
@@ -18,14 +18,10 @@ package org.apache.myfaces.tobago.render
  */
 
 import org.apache.myfaces.tobago.component.UITreeNode;
-import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.context.ResourceManagerUtils;
 import org.apache.myfaces.tobago.context.UserAgent;
-import org.apache.myfaces.tobago.event.TreeExpansionEvent;
-import org.apache.myfaces.tobago.event.TreeMarkedEvent;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.layout.Display;
-import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.Style;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -35,68 +31,12 @@ import org.apache.myfaces.tobago.renderk
 import org.apache.myfaces.tobago.util.ComponentUtils;
 import org.apache.myfaces.tobago.util.VariableResolverUtils;
 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import java.io.IOException;
-import java.util.List;
 
-public class TreeMenuNodeRenderer extends LayoutComponentRendererBase {
-
-  private static final Logger LOG = LoggerFactory.getLogger(TreeMenuNodeRenderer.class);
-
-  @Override
-  public void decode(FacesContext facesContext, UIComponent component) {
-
-    UITreeNode node = (UITreeNode) component;
-
-    super.decode(facesContext, node);
-
-    if (ComponentUtils.isOutputOnly(node)) {
-      return;
-    }
-
-    final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
-    // we need the client id without the iterated row index here
-    final int rowIndex = data.getRowIndex();
-
-    // expanded
-//    if (folder) { XXX this value seems to be not restored...
-      final List<Integer> submittedExpanded = data.getSubmittedExpanded();
-      if (submittedExpanded != null && submittedExpanded.contains(rowIndex) != node.isExpanded()) {
-        new TreeExpansionEvent(node, node.isExpanded(), submittedExpanded.contains(rowIndex)).queue();
-    }
-//    }
-
-    // marked
-    Integer marked = data.getSubmittedMarked();
-    if (marked != null) {
-      boolean markedValue = marked.equals(rowIndex);
-      if (node.isMarked() != markedValue) {
-        new TreeMarkedEvent(node, node.isMarked(), markedValue).queue();
-      }
-    } else {
-      LOG.warn("This log message is help clarifying the occurrence of this else case.");
-    }
-  }
-
-  @Override
-  public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
-    super.prepareRender(facesContext, component);
-
-    final UITreeNode node = (UITreeNode) component;
-    if (node.isMarkedWithTemporaryState()) {
-      node.setCurrentMarkup(Markup.MARKED.add(node.getCurrentMarkup()));
-    }
-    if (node.isFolder()) {
-      node.setCurrentMarkup(Markup.FOLDER.add(node.getCurrentMarkup()));
-      if (node.isExpandedWithTemporaryState()) {
-        node.setCurrentMarkup(Markup.EXPANDED.add(node.getCurrentMarkup()));
-      }
-    }
-  }
+public class TreeMenuNodeRenderer extends TreeNodeRendererBase {
 
   @Override
   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
@@ -143,9 +83,10 @@ public class TreeMenuNodeRenderer extend
   @Override
   public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
     final UITreeNode node = (UITreeNode) component;
+    final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
     final int level = node.getLevel();
     final boolean folder = node.isFolder();
-    final boolean expanded = folder && node.isExpandedWithTemporaryState() || level == 0;
+    final boolean expanded = folder && data.getExpandedState().isExpanded(node.getPath()) || level == 0;
 
     final TobagoResponseWriter writer = HtmlRendererUtils.getTobagoResponseWriter(facesContext);
 

Modified: myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java?rev=1327429&r1=1327428&r2=1327429&view=diff
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java (original)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRenderer.java Wed Apr 18 09:04:22 2012
@@ -18,14 +18,10 @@ package org.apache.myfaces.tobago.render
  */
 
 import org.apache.myfaces.tobago.component.UITreeNode;
-import org.apache.myfaces.tobago.context.Markup;
 import org.apache.myfaces.tobago.context.ResourceUtils;
-import org.apache.myfaces.tobago.event.TreeExpansionEvent;
-import org.apache.myfaces.tobago.event.TreeMarkedEvent;
 import org.apache.myfaces.tobago.internal.component.AbstractUIData;
 import org.apache.myfaces.tobago.layout.Display;
 import org.apache.myfaces.tobago.layout.LayoutBase;
-import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
 import org.apache.myfaces.tobago.renderkit.css.Classes;
 import org.apache.myfaces.tobago.renderkit.css.Style;
 import org.apache.myfaces.tobago.renderkit.html.DataAttributes;
@@ -39,9 +35,8 @@ import org.slf4j.LoggerFactory;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import java.io.IOException;
-import java.util.List;
 
-public class TreeNodeRenderer extends LayoutComponentRendererBase {
+public class TreeNodeRenderer extends TreeNodeRendererBase {
 
   private static final Logger LOG = LoggerFactory.getLogger(TreeNodeRenderer.class);
 
@@ -53,58 +48,6 @@ public class TreeNodeRenderer extends La
       = ResourceUtils.createString("image", "treeNode", "icon", "leaf", ResourceUtils.GIF);
 
   @Override
-  public void decode(FacesContext facesContext, UIComponent component) {
-
-    UITreeNode node = (UITreeNode) component;
-
-    super.decode(facesContext, node);
-
-    if (ComponentUtils.isOutputOnly(node)) {
-      return;
-    }
-
-    final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
-    // we need the client id without the iterated row index here
-    final int rowIndex = data.getRowIndex();
-    final boolean folder = node.isFolder();
-
-    // expanded
-    if (folder) {
-      final List<Integer> submittedExpanded = data.getSubmittedExpanded();
-      if (submittedExpanded != null && submittedExpanded.contains(rowIndex) != node.isExpanded()) {
-        new TreeExpansionEvent(node, node.isExpanded(), submittedExpanded.contains(rowIndex)).queue();
-      }
-    }
-
-    // marked
-    Integer marked = data.getSubmittedMarked();
-    if (marked != null) {
-      boolean markedValue = marked.equals(rowIndex);
-      if (node.isMarked() != markedValue) {
-        new TreeMarkedEvent(node, node.isMarked(), markedValue).queue();
-      }
-    } else {
-      LOG.warn("This log message is help clarifying the occurrence of this else case.");
-    }
-  }
-
-  @Override
-  public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
-    super.prepareRender(facesContext, component);
-
-    final UITreeNode node = (UITreeNode) component;
-    if (node.isMarkedWithTemporaryState()) {
-      node.setCurrentMarkup(Markup.MARKED.add(node.getCurrentMarkup()));
-    }
-    if (node.isFolder()) {
-      node.setCurrentMarkup(Markup.FOLDER.add(node.getCurrentMarkup()));
-      if (node.isExpandedWithTemporaryState()) {
-        node.setCurrentMarkup(Markup.EXPANDED.add(node.getCurrentMarkup()));
-      }
-    }
-  }
-  
-  @Override
   public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
 
     final UITreeNode node = (UITreeNode) component;

Added: myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRendererBase.java?rev=1327429&view=auto
==============================================================================
--- myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRendererBase.java (added)
+++ myfaces/tobago/branches/tobago-tree-table/tobago-theme/tobago-theme-scarborough/src/main/java/org/apache/myfaces/tobago/renderkit/html/scarborough/standard/tag/TreeNodeRendererBase.java Wed Apr 18 09:04:22 2012
@@ -0,0 +1,50 @@
+package org.apache.myfaces.tobago.renderkit.html.scarborough.standard.tag;
+
+/*
+* 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 org.apache.myfaces.tobago.component.UITreeNode;
+import org.apache.myfaces.tobago.context.Markup;
+import org.apache.myfaces.tobago.internal.component.AbstractUIData;
+import org.apache.myfaces.tobago.internal.component.AbstractUITree;
+import org.apache.myfaces.tobago.renderkit.LayoutComponentRendererBase;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+
+public class TreeNodeRendererBase extends LayoutComponentRendererBase {
+
+  @Override
+  public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
+    super.prepareRender(facesContext, component);
+
+    final UITreeNode node = (UITreeNode) component;
+    final AbstractUIData data = ComponentUtils.findAncestor(node, AbstractUIData.class);
+    if (data instanceof AbstractUITree && ((AbstractUITree) data).getMarkedState().isMarked(node.getPath())) {
+      ComponentUtils.addCurrentMarkup(node, Markup.MARKED);
+    }
+    if (node.isFolder()) {
+      ComponentUtils.addCurrentMarkup(node, Markup.FOLDER);
+      if (data.getExpandedState().isExpanded(node.getPath())) {
+        ComponentUtils.addCurrentMarkup(node, Markup.EXPANDED);
+      }
+    }
+  }
+
+}