I apologize, the link I sent is to an internal Oracle server. The Trinidad javadoc is still not up, so I am using an internally generated copy of the doc. Sorry about that!

Thanks,

Gab

Gabrielle Crawford wrote:

Pavitra Subramaniam wrote:
Come to think of it, we do not require getParentTrain() and getSubTrain(). Because if the user wants to navigate to the parentTrain, they are most likely going to hit a command outside of the train (or even the parent icon), that will simply position whatever datastructure that stores the train data, to the right level (based of the focusRowKey). I am assuming that this data structure is page-flow or session scoped. Same goes for the navigating to the subTrain. 

This way the model will only have to be list and the model implementor, can store their complicated train metadata in their own structures. I see no reason to load the entire tree of data into the model. A list can be served up whenever it's needed by a managed bean. 
  
It's possible to create a treeModel from a list, for example I believe you can use ModelUtils to do this:
http://bali.us.oracle.com:2020/releases/adf.faces/jm7/multiproject/adf-faces-api/apidocs/org/apache/myfaces/trinidad/model/ModelUtils.html#toTreeModel(java.lang.Object)

The underlying data the model is built on is often shared, even if the model is not, so I'm not sure how big a concern this is.
Anyway, I would think whether you pull all the data at once has to do with the tree implementation, not the tree model api.


public abstract class TrainModel extends CollectionModel 
{
  // True if the current train has a child train
  public abstract boolean isSubTrain();

  // gets the parent train label if I am a subTrain
  public abstract String getParentTrainLabel ()

  // (I meant to write focusRowKey not viewId)
  public abstract Object getFocusRowKey (); 
}

Isn't this much simpler? What do you think?
  
It's a bit simpler, but with the design above the methods you're saving are now down to the tree methods, and getDepth can be used to determine if it's a subtrain.

I guess my overall concern is that although the current train design only shows a single level, I have seen train designs in the past that show parent and subtrains at once, in a vertical tree structure that goes on the side of the page. Or someone might want to make the icon that goes up to the parent train a link, or maybe even render something for all the parent levels in that spot. Having a tree model supports these designs.

However
I don't know that the train is built to support this now, meaning I'm not sure decoding nodes that aren't siblings with the focus row key node would work. If it doesn't maybe it should.

For the train label, I assume you mean something more general than the text attribute on the parent node. Really even if you have a flat list you might want an overall name for the group of nodes. Like "Checkout" for an app where the nodes are "billing address", "shipping address", etc. So with an api like "getGroupName", the implementation can get the name from wherever it wants, from the parent or not. I'm not sure I love this, but it seems more general than forcing a parent node. To get the parents group name you'd do exitContainer() and then getGroupName(). You could use this to render the names of all the parent groups, not just up a single level.

Thanks,

Gab
- Pavitra
 

  
-----Original Message-----
From: Pavitra Subramaniam [mailto:[EMAIL PROTECTED]] 
Sent: Thursday, September 28, 2006 9:09 PM
To: [email protected]
Subject: RE: [Proposal] ProcessModel changes

Let me make it clear. I cleaned up the TrainModel API. In 
fact I don't think we need methods like enterSubTrain, 
exitSubtrain. All we need is a way to get to the parent level 
and the child level. 

The essential difference between a tree component and the 
train is that tree always (or most often) shows multiple 
levels of data at the same time, but the train will not. It 
only shows one level (or a list of nodes) at a time. Any time 
the user wants to go up or down one level, the model simply 
returns a new list. Most often users may have only one level 
in the train, in which case using a TreeModel is an overkill 
as most methods will be a no-op. 

public abstract class TrainModel extends CollectionModel {
  // True if the current train has a child train
  public abstract boolean hasSubTrain();

  // True if the current train has a parent train
  public abstract boolean hasParent();

  // Returns the subTrain if the current train is a container 
of another train
  public abstract TrainModel getSubTrain();

  // Returns the parent train and possibly sets the focusRowKey
  public abstract TrainModel getParentTrain();

  // (I meant to write focusRowKey not viewId)
  public abstract Object getFocusRowKey (); }

 
 
- Pavitra 
 


________________________________

	From: Gabrielle Crawford [mailto:[EMAIL PROTECTED]] 
	Sent: Thursday, September 28, 2006 7:51 PM
	To: [email protected]
	Subject: Re: [Proposal] ProcessModel changes
	
	
	Hi,
	
	Pavitra Subramaniam wrote: 

			Can you explain
			1] What this new api you are proposing 
looks like?
			    

		
		- (This is just an idea and I have not thought 
through this completely. So read on.)
		- It probably will be very close to the list of 
all abstract methods defined in MenuModel -> TreeModel -> 
CollectionModel -> DataModel  (and interface RowKeyIndex). 
But it will be simpler and specific to the train and makes no 
assumptions about the underlying data structure that backs the model.
		
		- Currently, if a consumer of train defines 
their train metadata in a structure (other than an 
XmlMenuModel or MenuModel), like their own XML metadata, they 
would have to implement the following methods to get a model 
that the train expects. The methods below are very treeModel 
specific, as one can argue that the train ultimately is a 
tree. Although in reality it is most likely to be a graph.
		
		abstract class MenuModel extends TreeModel
		{
		  public abstract Object getFocusRowKey();
		 
		  // from TreeModel extends CollectionModel
		  public abstract boolean isContainer();
		  public abstract void enterContainer();
		  public abstract void exitContainer();
		  public abstract Object 
getContainerRowKey(Object childRowKey);
		
		  // from CollectionModel extends DataModel
		  public abstract Object getRowKey();
		  public abstract void setRowKey(Object key);
		 
		  // from RowKeyIndex
		  - methods from RowKeyIndex as well
		
		  // from DataModel
		  public abstract int getRowCount() { }
		  public abstract java.lang.Object getRowData() { }
		  public abstract int getRowIndex() { }
		  public abstract java.lang.Object getWrappedData() { }
		  public abstract boolean isRowAvailable() { }
		  public abstract void setRowIndex(int p1) { }
		  public abstract void 
setWrappedData(java.lang.Object p1) { }
		}
		
		- Moreover the current TreeModel does not 
provide us a way to associate a label to a collection of 
nodes at the root level (or for that matter at every 
sub-level). For instance, we need to display a label of the 
train or parent train as we go deeper into the train 
hierarchy. It would be nice if the model can support this, 
especially if the train metadata already has a way to define this.
		  

	Agreed that this data isn't currently available anywhere. 
	

		- Having a TrainModel that makes no assumptions 
about the underlying data structure of the train data, makes 
it convenient for consumers that don't necessarily use the 
TreeModel. For instance, if I represent my train metadata 
using DataSets (or SDO for that matter) or some XML metadata 
structure, then all the consumer of the TrainModel needs to 
do is provide a list a train nodes for every level, and 
ability to go the parent or sublevel of the train, get the 
current node (or focusRowKey).
		  

	Getting the parents and children sounds like a 
treeModel to me, so I'm not sure I understand why they can't 
just be implementations of the treeModel. Why can't you 
implement a treeModel if you're using xml, etc? I don't know 
about DataSets, but when I look at your proposal below it 
looks a lot like the treeModel api, so I'm not sure why it's 
an improvement. 
	

		For instance, if I had a TrainModel like below, 
the consumer who uses MenuModel to define their train 
metadata would create a MenuTrainModel implementation that 
internally uses the ProcessMenuModel. And the consumer who 
uses a custom XML structure or a DataObject to represent 
their train metadata, will define a XmlTrainModel, or 
DataSetTrainModel and internally use their own data 
structures to serve up information to the train.
		  

	I think in the end they are going to end up with 
something suspiciously like the tree model. 
	

		The APIs below are by no means complete, it's 
just an example.
		  


	You are extending DataModel below, so you have to 
implement all of:
	
	  public abstract int getRowCount() { }
	  public abstract java.lang.Object getRowData() { }
	  public abstract int getRowIndex() { }
	  public abstract java.lang.Object getWrappedData() { }
	  public abstract boolean isRowAvailable() { }
	  public abstract void setRowIndex(int p1) { }
	  public abstract void setWrappedData(java.lang.Object p1) { }
	As for the rest you've swapped the word "Node" for 
"Row", but you've basically renamed many of the methods on 
TreeModel and collectionModel. 
	
	

		public abstract class TrainModel extends DataModel
		{
		  // True if the current train has a child train
		  public abstract boolean hasSubTrain();
		  

	isn't this just like isContainer on TreeModel?
	

		  // Enter the subTrain if the current train is 
a container of another train
		  public abstract void enterSubTrain();
		  

	isn't this just like enterContainer on TreeModel?
	

		  // Leave the subTrain to return to the parent 
train level
		  public abstract void exitSubTrain();
		  

	isn't this just like exitContainer on TreeModel?
	

		  //
		  public abstract Object getParentNode(Object 
childNode);
		  

	isn't this just like getContainerRowKey(Object 
childRowKey) on TreeModel 

		  // gets the number of nodes at a level
		  public abstract int getNodeCount();
		  

	isn't this just like getRowCount on DataModel, which 
you're already extending?
	

		  // gets the rowData
		  public abstract Object getNode(Object key);
		  

	isn't this just like getRowData() on DataModel, which 
you're already extending? 

		  // gets the node key. Key identifies a node uniquely
		  public abstract Object getNodeKey ();
		  

	isn't this just like getRowKey() on CollectionModel?
	

		  public abstract Object getViewId ();
		  

	There's nothing in the current model that says anything 
about view id's and I don't think there should be. You should 
be able to write a train without navigating to a different 
viewId. But I'm confused why viewId is on here? Aren't you 
still using a command child, outcomes, and jsf navigation?
	
	Is there a focusPath method?
	Is there a setRowKey method?
	

		}
		
		- Finally, in combination with the rowData 
interface or the autoBind feature, they can provide custom 
implementations for behavior of states 
(visited/selected/disabled) etc.
		- What do you think?


	So maybe I'm not understanding this, but in general so 
far it seems like it's renaming methods, plus one viewId 
method that I don't understand. So I would assume you're 
going to say it has fewer methods, can you point to specific 
methods on menuModel that are a burden to implement? In some 
cases, like isSortable, or getSortCriteria it's kinda weird, 
but it seems like you're reinventing tree model for the most 
part, which doesn't seem all that useful.  
	
	Again, maybe I'm not understanding the problem....
	
	Thanks,
	
	Gab
	



    

  

Reply via email to