Wednesday, July 06, 2011

GWT 2.3 and IncompatibleRemoteServiceException: This application is out of date

Behavior:

After the first GWT-RPC-Call, the Tomcat logs an IncompatibleRemoteServiceException.

Cause:

Tomcat starts with a wrong version of gwt-servlet.jar (other than the compiled JavaScript expects)

Solution:

Delete all wrong versions of gwt-servlet.jar

Friday, February 02, 2007

Eclipse Plugin to test Regular Expressions

QuickRex is a nice little plugin for eclipse to check if your fantastic little regexp works as you expect. It even has a live evaluation and higlights the matching text elements in green. Wonderful!

Update Site: http://bastian-bergerhoff.com/eclipse/features/

Screenshot:

Wednesday, January 31, 2007

Loop over a list of model elements with an iterator faclet tag in JSF

What about and ? Why do one need another loop tag?

  1. If your container component has specific requirements on the type of its child component you can't go with the known tags because they put there own components as child-components on the container.

  2. Both of them cannot be used if you need a dynamic evaluation of model elements

You can use the tag as follows to iterator over a list of employees to print out there names:

<my:iterator value="#{bean.employees}" var="employee" > <<tr:outputText value="#{employee.name}" /> </my:iterator>

The Tag assumes a value of type List.

The Java Code of the Facelets Tag Handler:

public class IteratorTag extends TagHandler

{

private final TagAttribute _value;

private final TagAttribute _var;

public IteratorTag(TagConfig p_arg0)

{

super(p_arg0);

_value = getRequiredAttribute("value");

_var = getRequiredAttribute("var");

}

public void apply(FaceletContext p_facelets,

UIComponent p_parentComponent) throws IOException, FacesException, FaceletException, ELException

{

// get the value binding behind attr "value"

List list = (List) _value.getObject(p_facelets, List.class);

int idIndex = 0;

for (Object object : list)

{

// get the name of the variable

String varName = _var.getValue(p_facelets);

// set new variable into faclets attribute map

p_facelets.setAttribute(varName, object);

nextHandler.apply(p_facelets, p_parentComponent);

// update ID of last created component from nextHandler

String clientId = p_parentComponent.getClientId(p_facelets.getFacesContext()) + "_dynamicChild"+idIndex;

List children = p_parentComponent.getChildren();

children.get(children.size()-1).setId(clientId);

idIndex++;

}

}

}

Friday, January 26, 2007

Good Agile Karma

Leif hat mir folgenden, Artikel ├╝ber Aigle Software Entwicklung zukommen lassen:

Abstract:

This article will focus on behavior patterns that enable teams to realize the most benefits of Agile rollout and sustain the experience. This article assumes that you have already implemented Agile process in your organization.

URL:

http://www.infoq.com/articles/agile-karma


Tuesday, October 17, 2006

HowTo work with ADF Faces TreeModel

The ADF tree component (af:tree) uses instances of class TreeModel as model to render its content.

Unfortunately the TreeModel works quick different as common java tree models. Nodes of the tree and aspecialy their children cannot be accessed throw a getter like "getChildren()" which makes navigation and mangement of the tree a bit tricky.

HowTo create a Adf TreeModel

The simples way to create a adf TreeModel instance is to define you own tree node class first:

public class TreeNode
{
  String _text;
  List _children;
 
  public TreeNode(){}
  public TreeNode(String p_text) {_text = p_text};
  public String getText() {return _text;}
  public List getChildren() {return _children;}
}
Afterward you can setup a tree with it and convert it to an adf TreeModel
TreeNode rootNode = new TreeNode();
TreeNode firstLevel = new TreeNode("FirstLevelNode");
rootNode.getChildren.add( firstLevel );
firstLevel.getChildren.add( new TreeNode("SecondLevelNode") );
...
TreeModel _treeModel = new ChildPropertyModel(rootNode.getChildren(), "children");
Note, that the children of the rootNode itself is not displayed but their children. In your Jsp or Xhtml page, this TreeModel instance can be bound to the af:tree component as follows:
<af:tree value="#{myJsfBean.treeModel}" var="node">...</af:tree>

How the ADF TreeModel works

An ADF TreeModel instance always has a "current row" with one can "work" with. The current row can be a any (sub-) node of the tree.

The "current row" can be accessed throw treeModel.getRowKey() which returns an Object (debugging uncovered it to be a list of Object).
The "current row data", which is your TreeNode behind the "currentRow" is accessable as shown in the following line:

TreeNode treeNode = (TreeNode) treeModel.getRowData();
If you want to traverse throw the tree, you have to set the "current row" to a new value and use "enterContainer" and "leaveContainer" to go down or up the tree hierarchy. Let's look at an example on how to find the rowKey for on of you TreeNode's.

Your implementation consists of two methods.
One get's called by the client an manages tree state saving/restoring and uses the second method to do the "real work":

public Object getRowKey(TreeNode p_treeNode)
{
    Object oldRowKey = _treeModel.getRowKey();      // remember old state
    _treeModel.setRowIndex(-1);                     // navigate to "root" node
    Object searchedRowKey = _getRowKey(p_treeNode); // do the job
    _treeModel.setRowKey(oldRowKey);                // restore old state
    return searchedRowKey;
}
The second method iterates over the children of the "current row" by setting the rowIndex with treeModel.setRowIndex(i)in a loop. It compares each "rowData" with p_treeNode and return it on success. If it gets to a row which is not an empty container, it "enters" the container and calls itself recursively.
private Object _getRowKey(ITreeNode p_treeNode)
{
    Object rowKey = null;
    for (int i = 0; i < _treeModel.getRowCount(); i++)
    {
      _treeModel.setRowIndex(i);
      ITreeNode node = (ITreeNode) _treeModel.getRowData();
      if (node.equals(p_menuNode))
      {
        rowKey = _treeModel.getRowKey();
      }
      else
      {
        if (!_treeModel.isContainerEmpty())
        {
        _treeModel.enterContainer();
        rowKey = _getRowKey(p_treeNode);
        _treeModel.exitContainer();
        }
      }
      if (rowKey != null)
        return rowKey;
    }
    return null;
}
The opposite direction, to get your TreeNode for a valid rowKey is simple:
public ITreeNode getTreeNode(Object p_rowKey)
{
  Object oldRowKey = _treeModel.getRowKey();
  _treeModel.setRowKey(p_rowKey);
  ITreeNode treeNode = (ITreeNode) _treeModel.getRowData();
  _treeModel.setRowKey(oldRowKey);
  return treeNode;
}

HowTo set a node expanded

The adf tree component has an attribute "treeState" (an instance of PathSet) which contains a set of "rowKeys". All rowKeys in this pathSet are rendered "expanded".

The best way to set nodes expanded is first to manage the treeState on your own. The PathSet needs a reference to the treeModel so when even you set a new treeModel make sure to update the pathSet of expanded nodes. Here, we do it in the setter:

private PathSet _expandedNodes = new PathSet();
prviate TreeModel _treeModel = null;

protected void setTreeModel(TreeModel model)
{
  _treeModel = model;
  _expandedNodes.clear();
  _expandedNodes.setTreeModel(_treeModel);
}
public PathSet getExpandedNodes() {return _expandedNodes;}
Bind your "expanded" attribut to the tree component, the component will only read the attribut.
<af:tree
  value="#{myJsfBean.treeModel}"
  var="node"
  treeState="#{myJsfBean.expandedNodes}">
  ...
</af:tree>
To set your node expanded, you have to put the rowKey of your node in the set of expanded nodes.
public void setExpanded(ITreeNode p_treeNode, boolean p_expanded)
{
    Object rowKey = getRowKey(p_treeNode);
    if (p_expanded)
    {
      _expandedNodes.getKeySet().add(rowKey);
      List anchestorsOfCurrentNode =
           _treeModel.getAllAncestorContainerRowKeys(rowKey);
      _expandedNodes.getKeySet().addAll(anchestorsOfCurrentNode);
    }
    else
    {
      _expandedNodes.getKeySet().remove(rowKey);
    }
}
Watch out that if the implementation above does not close the complete hierarchy of nodes if one node is set not not expanded.

Put it all Together

Write your self a "TreeModelFacade" which does the dirty jobs and bind your af:tree's only to this facade. Your managed bean can create the tree of TreeNode's and instantiate the TreeModelFacade.

Take this as food for your thoughts:

public class TreeModelFacade
{
  public void setRootTreeNode(TreeNode p_rootNode) {...}
  public TreeModel getTreeModel() {//create ChildPropertyTreeModel form rootNode..}
  public ITreeNode getTreeNode(Object p_rowKey) {...}
  public Object getRowKey(TreeNode p_treeNode) {...}
  public void setExpanded(ITreeNode p_treeNode, boolean p_expanded) {...}
  public void refreshTreeModel() {//after changes in TreeNode tree ...}
  protected void setTreeModel(TreeModel model) {...}
}
References

af:tree (tag documentation)
TreeModel (java doc)
PathSet (java doc)