You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mc...@apache.org on 2010/08/26 23:40:41 UTC

svn commit: r989944 - in /myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main: java-templates/org/apache/myfaces/trinidad/component/ java/org/apache/myfaces/trinidad/component/

Author: mcooper
Date: Thu Aug 26 21:40:40 2010
New Revision: 989944

URL: http://svn.apache.org/viewvc?rev=989944&view=rev
Log:
TRINIDAD-1889 Issue with Trinidad UIXCollection class 'createCollectionModel' method

The Trinidad UIXCollection class contains an abstract method called 'createCollectionModel'. Subclasses are supposed to override this method and use it to create a CollectionModel instance for use by the component.

Currently subclasses like UIXTable and UIXTree use 'createCollectionModel' to get the component's 'value' attribute and wrap the object in the 'value' attribute in a CollectionModel/TreeModel instance (if necessary) .

UIXTable and UIXTree also perform other initializations in 'createCollectionModel. For example, SelectedRowKeys and DisclosedRowKeys sets are initialized in 'createCollectionModel'.

The issue with the current design is that the component's reference to the CollectionModel is not fully initialized until 'createCollectionModel' returns a CollectionModel instance and the resulting model is stored in the component's state by UIXCollection.

So for example, UIXTable and UIXTree should not be performing initialization of component's attribute that depend on a fully initialized CollectionModel reference inside the 'createCollectionModel'.

The SelectedRowKeys and DisclosedRowKeys sets require a fully initialized CollectionModel before they should be referenced. Otherwise if these attributes are EL-bound and a backing bean logic references the CollectionModel in the getter method for SelectedRowKeys and DisclosedRowKeys, the backing bean may get an uninitialized CollectionModel reference.


The proposal is to add the following method to UIXCollection:

  /**
   * Called after <code>createCollectionModel</code> when the model is fully initialized
   * Subclasses can use this method to perform initialization of component attributes
   * that should occur only after the CollectionModel is fully initialized in
   * <code>createCollectionModel</code>
   * This is a do nothing implementation to avoid breaking existing code
   * * @see #createCollectionModel
   * @param model
   */
  protected void postCreateCollectionModel(CollectionModel model)
  {
    // do nothing
  }


This method will be called by UIXCollection after 'createCollectionModel' returns and the component's reference to the CollectionModel is fully initialized. Any initialization of model-dependent attributes can then occur in 'postCreateCollectionModel'

Thanks to Kamran Kashanian for the patch.

Modified:
    myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTableTemplate.java
    myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
    myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java

Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTableTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTableTemplate.java?rev=989944&r1=989943&r2=989944&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTableTemplate.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTableTemplate.java Thu Aug 26 21:40:40 2010
@@ -379,8 +379,12 @@ abstract public class UIXTableTemplate e
     CollectionModel current,
     Object value)
   {
-    CollectionModel model = super.createCollectionModel(current, value);
-
+    return super.createCollectionModel(current, value);
+  }
+  
+  @Override
+  protected void postCreateCollectionModel(CollectionModel model)
+  {
     RowKeySet selectedRowKeys = getSelectedRowKeys();
 
     if (selectedRowKeys == null)
@@ -404,9 +408,7 @@ abstract public class UIXTableTemplate e
     if (_sortCriteria != null)
     {
       model.setSortCriteria(_sortCriteria);
-    }
-
-    return model;
+    }    
   }
 
   /**

Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java?rev=989944&r1=989943&r2=989944&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXTreeTemplate.java Thu Aug 26 21:40:40 2010
@@ -103,12 +103,8 @@ abstract public class UIXTreeTemplate ex
   }
 
   @Override
-  public CollectionModel createCollectionModel(CollectionModel current, Object value)
+  protected void postCreateCollectionModel(CollectionModel model)
   {
-
-    TreeModel model = ModelUtils.toTreeModel(value);
-    model.setRowKey(null);
-
     RowKeySet selectedRowKeys = getSelectedRowKeys();
 
     if (selectedRowKeys == null)
@@ -126,8 +122,14 @@ abstract public class UIXTreeTemplate ex
     }
 
     selectedRowKeys.setCollectionModel(model);
-    disclosedRowKeys.setCollectionModel(model);
+    disclosedRowKeys.setCollectionModel(model);    
+  }
 
+  @Override
+  public CollectionModel createCollectionModel(CollectionModel current, Object value)
+  {
+    TreeModel model = ModelUtils.toTreeModel(value);
+    model.setRowKey(null);
     return model;
   }
 

Modified: myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java?rev=989944&r1=989943&r2=989944&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java (original)
+++ myfaces/trinidad/branches/1.2.12.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java Thu Aug 26 21:40:40 2010
@@ -1112,6 +1112,7 @@ public abstract class UIXCollection exte
 
       iState._value = getValue();
       iState._model = createCollectionModel(null, iState._value);
+      postCreateCollectionModel(iState._model);
       assert iState._model != null;
     }
     // model might not have been created if createIfNull is false:
@@ -1130,12 +1131,32 @@ public abstract class UIXCollection exte
 
   /**
    * Creates the CollectionModel to use with this component.
+   * The state of the UIComponent with the new model instance is not fully initialized until
+   * after this method returns. As a result,  other component attributes that need
+   * a fully initialized model should not be initialized in this method.  Instead,
+   * model-dependent initialization should be done in <code>postCreateCollectionModel</code>
+   * @see #postCreateCollectionModel
    * @param current the current CollectionModel, or null if there is none.
    * @param value this is the value returned from {@link #getValue()}
    */
   protected abstract CollectionModel createCollectionModel(
     CollectionModel current,
     Object value);
+  
+  /**
+    * Hook called with the result of <code>createCollectionModel</code>.
+    * Subclasses can use this method to perform initialization after the CollectionModel
+    * is fully initialized.
+    * Subclassers should call super before accessing any component state to ensure
+    * that superclass initialization has been performed.
+    * @see #createCollectionModel
+    * @param model The model instance returned by<code><createCollectionModel</code>
+    */
+  protected void postCreateCollectionModel(CollectionModel model)
+  {
+    // do nothing
+  }
+ 
 
   /**
    * Gets the value that must be converted into a CollectionModel
@@ -1178,7 +1199,7 @@ public abstract class UIXCollection exte
       }
     };
   }
-
+  
   
   //
   // LocalRowKeyIndex implementation
@@ -1367,6 +1388,7 @@ public abstract class UIXCollection exte
     {
       iState._value = value;
       iState._model = createCollectionModel(iState._model, value);
+      postCreateCollectionModel(iState._model);
     }
   }