Kiss My App

Sunday, May 13, 2007

More JSF 2 Ideas

While sitting in the concurrency pitfalls session at javaone (nothing new and I totally disagreed with his use of annotations as pure documentation)-- anyways, my mind wandered and I started thinking about Seam, WebBeans, and some of the byte code stuff the JPA is using. So why can't we do the same with JSF 2?



A while back, I wrote a bit on some initial ideas for JSF 2, but was stuck on how to propagate state changes between components without explicit assignment. Swing suffers from this same issue and the bean binding spec blows in its current state. Anyways, two things are going for JSF on this front in the current specs:



  1. All components must be created by some factory-- yay, we can byte code enhance them. Since 98.4% of all JSF UIComponents in apps today come from templates (Facelets, JSP, Shale, etc), the factory creation hook really isn't an issue

  2. The current idea behind UIComponent has tons of metadata which can be hidden from the end user in JSF 2


Where I think we can differ from something like Seam/JPA, is that all you want to do in your code is say, "This field is injectable, and leave the 'what' is injected up to some other resource." I actually appreciate this separation a bit as I believe both Tapestry 5 and Google Guice promotes this to some extent, but here's an example:



@Attribute
private Iterable value;

In the above example, all I want to say is that this field is an attribute, leaving a separate set of metadata as provided by a template to dictate what is actually bound:


<h:dataTable value="#{dept.employees}"/>


Where things get difficult is now in marrying the two parts: the developer's object and the metadata from the template. Often this is done with byte-code enhancements in common ORM frameworks, but to do this better, we take a feather from Seam's ideas around bijection-- such that:



@Attribute
private Iterable value;

Is two way-- set it and the value propagates back into the variable-scope while fetching it pulls the value from some variable-scope. Here's a more elaborate example:


<h:dataTable value="#{dept.employees}" var="emp">
<h:column>#{emp}</h:column>
</h:dataTable>

The Java code for the HtmlDataTable would look something like:


public class HtmlDataTable extends UIComponent {
@Attribute
private Object var;

@Attribute
private Iterable value;

@Children
private Collection<UIColumn> columns;

public void onEncode(FacesContext faces) {
for (Object i : value) {
this.var = i;
for (UIColumn c : columns) {
c.onEncode(faces)
}
}
}
}


The conundrum is that we'd like to preserve the evaluation flexibility from JSF 1.x, but how does the child UIColumn able to resolve the variable "emp" when we move to an annotated binding solution? Since bindings are two ways, doing this.var = i, actually is byte-code enhanced to push whatever i is back out into the variable-scope as "emp". So when you turn around and call c.onEncode(faces), the UIColumn will inject-on-invoke any possible state required for resolution, in this case, "emp".



If we weren't going to do byte-code enhancement and just look at an EJB 3 interceptor, the pseudo code for lifecycle methods would look something like:



public Object intercept(InvocationContext ctx) {
// exit if already on stack for eval

if (is lifecycle method) {
Object component = ctx.getBean();
UIComponentMetaModel meta = // resolve metadata from template

StateManager stateMngr = // get threadlocal statemanager
for (Stateful state : // find stateful members) {
Object value = stateMngr.restore(clientId, component, state.getName());
setState(component, state.getName(), value);
}


for (Attributes attr : // find attributes) {
Object value = meta.getValue(attr.getName(), attr.getType());
setState(component, attr.getName(), value);
}

Object result = ctx.proceed();

for (Stateful state : // find stateful members) {
Object value = getState(component, state.getName());
stateMngr.save(clientId, component, state.getName(), value);
}
}
}


I threw in stateful crap, because we need to handle it-- but no longer mess with saving state for everything when in reality, only in niche cases would you ever have to save state-- like some kind of counter component or preferences, but we could be looking at only a couple primitive values for a very large view-- making things much more performant.



Going back to the marriage of the UIComponentMetaModel and the class that the end developer wrote, I think you'd have a single JSF byte-code enhanced class per type-- which gets the metamodel pre-assigned before returning back to the client of the factory. It could be more efficient if we did byte-code per USE of the class such that each invocation wouldn't have to 'ask' the metamodel for information, it could just have everything explicitly scripted out for it without little iterations/for-loops. At that point, things would be a pure performance implementation.



Also, for this to work, returned component trees would have to be constructed from the bottom up like Facelets does such that metamodel data passed to parents is already child aware. BTW, what if Swing was able to work this way-- no more listeners and propertychange blah blah blah. Much of these use cases in Java in general would be so much simpler if properties were actual first class citizens instead of the bean 'hack/convention' everyone is accustomed to.



Where this differs from Tapestry 5 is that we must retain the direct parent/child operability-- that programatic freedom that's allowed in JSF over other component frameworks. While Tapestry 5 is a huge step forward and a new benchmark to shoot for, I think we can do a little better with JSF 2 in retaining the flexability it provides from a component composition standpoint. To many, this is probably a niche case for them, but extremely important in producing a commodity solution.

Wednesday, January 24, 2007

JavaOne 2007 - "In Case You Missed Last Year!"

I'm beginning to wonder if there's going to be anything exciting this year, or if it's going to be a series of repeat sessions from last year? JEE 5 was exciting, but many of the new innovations and JSRs are intelligently waiting on baited breath for what's coming in JSE 7-- closures and properties? Innovations like that can dramatically change the way APIs are presented, the same thing happened with JSE 5 and annotations. Unfortunately some of our favorite specs (*cough* JSF *cough*) never jumped on the annotation bandwagon with a pure maintenance release for JEE 5. I'd like to see some ramp up in the JCP before JavaOne-- maybe have JSE 7 'finalize' its feature set so the stagnant JCP can pick up in activity again.

Wednesday, January 10, 2007

Properties as Extensions of Member Variables

There's a great debate on where to go with properties in Java SE 7, largely impart to the fact that the original suggestion at Javaopolis was so-- blah. I, myself, went back and forth a bit on ideas, but found the C# syntax to be the most promising. The reason being is ease of refactoring. All Java programmers are familiar and seem to want only dot notation for property accessors:

public class Department {
public Company company;
}

Company mck = new Company();
Department hr = new Department();
hr.company = mck;

Department appDev = new Department();
appDev.company = hr.company;


Well, that's the way normal public field accessors work today. But, what about encapsulation, being able to decorate or protect field assignment and access?

public class Department {

private Company _company;

public Company company {
get { return this._company; }
set(Company c) { this._company = c; }
}
}


Ah, very C#-ish :-) But, notice that our original code doesn't change:

Company mck = new Company();
Department hr = new Department();
hr.company = mck;

Department appDev = new Department();
appDev.company = hr.company;


This allows for easy encapsulation, while making it okay to do simple 'property' declarations such as public Company company;. We already have seen lots of field level injections within EJB3, JPA, JAXB2, etc.

I think one of the struggles with the JavaBean spec is that the syntax changes dramatically when your object decides to encapsulate some behavior or make internal changes. This is why I wouldn't mind seeing the JavaBean spec kind of fall to the wayside. You should be able to refactor introvertantly instead of extrovertantly (I made those words up).

Now the Pie in the Sky Stuff



To be able to provide better refactoring without basically declaring two 'fields': a member variable, and public property, we can imply a super behavior of a member variable, such that we just have:

public class Department {

public Company company {
get { return super.get(); }
set(Company c) { super.set(c); }
}
}


The issue though is how to do a public, read-only property, if the set is implied as protected or what not. Interfaces over properties would be allowed just like C#:

public interface IDepartment {
public Company company {
get;
set;
}
}


If Sun did want to add a new accessor, then use it for accessing meta/type information:

Binding b = new Binding(uitext#value, myDept.company#name);


Which would be read as bind the uitext's value to my department's company's name. Possibly the return type of company#name has methods on it such that you could add a change listener or get the read/write methods:

Property p = company#name;
Method rm = p.getReadMethod();
Method wm = p.getWriteMethod();
Class type = p.getType();
p.addChangeListener(new PropertyChangeListener() {
public boolean onChange(PropertyChangeEvent ev) {
if ("foo".equals(ev.getNewValue()) {
// stop propagation
return true;
}
return false;
}
});

Friday, November 10, 2006

JSF Facelets Resurrected!

After a long hiatus away from open source with the wedding/work, I've started to working on Facelets again!

Contrary to what I said last spring/summer around Avatar, I've decided to continue on the 1.2 release of Facelets which has Avatar fully integrated for alternate/partial communication with JSF from JavaScript. The DynaFaces stuff isn't picking up in popularity and the code base has grown way too foreign to me from the original development done (losing/changing things included with Avatar).

Some of the new features include:

  • A JavaScript library for sending Faces events up to the server for partial views and supplementing AJAX JS widgets

  • Listener/Observer JS functionality with Faces events

  • The ability to define static resources within your taglib.xml to supplement your components

  • The simple convention of exposing FACES-INF on your ClassLoader to the public web. This means you can drop in simple JS/GIF/JPG/PNG images and reference them from within your HTML files

  • A ClientWriter to supplement GUI changes from backing beans or UIComponents, details here.



Configuration wise, one of the biggest changes was that it now requires a Filter to be mounted in your web.xml to supplement AJAX requests, including static resources. I've also peeled out the configuration stuff from FaceletViewHandler for the most part such that it can be lazily instantiated by the FaceletViewHandler or the FaceletFilter.

Anyways, here's a link to download. I've tested with the J1 demo and the Hangman demo. Note, the 1.2 release branch will only work with JSF 1.2-- which is fine by me because the RI 1.2 is gotten crazy fast compared to older releases. It's worth upgrading to the nightlies if you are running JSF 1.2.

Sunday, October 29, 2006

Extending EL Syntax Part 2

This evening, I got much of the parser updated to handle method invocation and projections. One thing I found tricky was handling embeded '{' ... '}' since my original syntax said, "whenever you hit '}', exit the expression token set and go back to literal for composite expressions" (value="Hello #{user.name}" as an example).

To get around embeded '}', I first tried to isolate a separate token set, which was dumb because it only corrected a single nesting of curly braces. Instead I added a simple stack counter such that only when we've reached more end braces than we've created, to jump back out of the expression.


| < LBRACE : "{" > { this.subExpressionCount++; }
| < RBRACE : "}" > { if (--this.subExpressionCount < 0) SwitchTo(DEFAULT); }


Anyways, here's some examples of the new parser. Some of the examples are overly complex, but only prove that the parser is working the way it should.


#{foo.a.b}
Value
Identifier[foo]
PropertySuffix[a]
PropertySuffix[b]

#{foo.a['b']}
Value
Identifier[foo]
PropertySuffix[a]
BracketSuffix
String['b']

#{3 * foo.a.b(e,c,d)}
Mult
Integer[3]
Value
Identifier[foo]
PropertySuffix[a]
MethodSuffix[b]
Identifier[e]
Identifier[c]
Identifier[d]

#{'foo'.length().food}
Value
String['foo']
MethodSuffix[length]
PropertySuffix[food]

#{foo}
Identifier[foo]

#{company.employees@name}
Value
Identifier[company]
PropertySuffix[employees]
ProjectProperty
PropertySuffix[name]

#{company.employees@getName()}
Value
Identifier[company]
PropertySuffix[employees]
ProjectMethod
MethodSuffix[getName]

#{company.employees@each{x|x.salary}}
Value
Identifier[company]
PropertySuffix[employees]
ProjectClosure[each{ x | ... }]
Value
Identifier[x]
PropertySuffix[salary]

#{company.employees@each{x|x.hashCode()}}
Value
Identifier[company]
PropertySuffix[employees]
ProjectClosure[each{ x | ... }]
Value
Identifier[x]
MethodSuffix[hashCode]

#{company.employees@each{x|x@max{y|y.salary}}} is complex
Value
Identifier[company]
PropertySuffix[employees]
ProjectClosure[each{ x | ... }]
Value
Identifier[x]
ProjectClosure[max{ y | ... }]
Value
Identifier[y]
PropertySuffix[salary]
LiteralExpression[ is complex]

Saturday, October 28, 2006

Extending EL Syntax

I've dabbled a bit with EL in the past for both Glassfish and Tomcat. Performance wise, no one's said the 'larger' feature set has caused performance problems (ELResolvers, ELContext, VariableMapper, etc). What I have seen, is people complaining about performance with OGNL. So what I want to see happen is for an EL implementation to fill in the necessary pieces to migrate OGNL users over to the EL API.

First, we of course need to support method invocation. This is pretty straight forward and will be considered a Value clause, just as a.b == a.getB().

Secondly, we would want to support projections/transformations/predicates within the language. I'm thinking that introducing '@' into the syntax would be the most readable solution as opposed to using dot notation with reserved literals. In addition, you don't always require a literal declaration of the projection and we could reduce expressions to something like:

#{company.employees@name} a collection of Employee names
#{company.employees@hashCode()} a collection of Employee hashCodes

If you wanted to specify the projection, then these two are equivalent:

#{company.employees@salary}
#{company.employees@each{x|x.salary}}

Also, we could have some reserved projections for selection/sorting/etc:

sort by name
#{company.employees@asc{x|x.name}}

employee with the most salary
#{company.employees@max{x|x.salary}}

only employees with a 6 figure salary
#{company.employees@only{x|x.salary > 100000}}

highest salary only
#{company.employees@max{x|x.salary}.salary}

the first employee found with the name of 'Bob'
#{company.employees@first{x|x.name == 'Bob'}}

Also, the EL-API has MethodExpressions where the expression represents a pointer to a method: #{employee.addAddress} and you could invoke the MethodExpression with an Address object. If we used this in combination with projections, we could do some neat stuff like:

Invoke on each ActionListener
#{bean.listeners@onAction}

Thursday, October 26, 2006

JSF 2.0 Ideas

We've reached the age of annotations, you are seeing tons of APIs revised and nouns/assets being refactored into compact metadata. The first API to really take this leap with EJB3, followed by an extension from JBoss, called Seam. I saw this coming a couple years ago in my article for OnJava ;-)

Now many other APIs are following suit in various degrees, replacing interfaces and abstract class declarations with type annotations and avoiding the traditional getter/setters with annotated fields, declaring injection or outjection (props to Gavin King-- see what ideas you come up with when you don't own a TV?).

Anyways, I was talking with the great Matthias and others (including HLS), on some ideas for JSF 2.0 and I thought I'd throw them up on the 'ole blog. I should also note that I think JSF and JSP should consolidate into one presentation spec instead of trying to continue to integrate the two. While the existing APIs would continue to exist, much of application development could be deferred to one unified API for the presentation tier.


  • @Attribute(required=true)
    One of the most obvious enhancements to the JSF API is to dump the use of an AttributeMap and ValueBindingMap to resolve dynamic state. Instead, we would automate this resolution with the annotation: @Attribute. This would allow both type-safety and remove the need to deal with the EL-API directly at all.

  • @UIComponent(name="dataTable")
    This is an obvious one. I strongly believe that much of the issues with the JSF API deals with maintaining each and every execution concern within the JSF 1.x UIComponent code. This has caused problems in multiple fronts because the more you put into the end developer's hands, the less your can predict and consequently: optimize. I'm still on the ropes about going back and possibly using an abstract class or an interface, but I haven't found a reason to yet.

  • @SaveState(Scope.View)
    State saving sucks and is the bane of the JSF API, but could be corrected in future revisions. With JSF 1.x, a component developer must manage saving the state of all its children and any properties they may have declared on the component. In addition, there's no room for transient parent/stateful child because of this hierarchical evaluation of state saving. From the JSF implementation perspective, there's really no room to optimize since the UIComponent tree just returns an 'Object'. Transient parents will prune their children, forcing you to save large chunks of data between requests. If we move to an annotation, we remove the state saving logic out of the component developer's hands and we can start saving data in a flat/normalized manner, allowing for stateful and stateless components to intermix with each other.

  • @Facet(name="header")
    Again, lets get rid of all of the Maps in the JSF UIComponent API. Following other injection logic found in existing frameworks, you could type-safely inject Facets declared in the UI or assigned directly to the object. If the name is not specified, it will default to the field name.

  • @Children(UIColumn.class)
    I don't think it's healthy to have component's be required to work directly with their children unless specifically required. In the cases where it is required, you can specify this annotation on a member variable of type Collection. In the case of a UIDataTable, you can say, only populate my member Collection with children of type UIColumn. The annotation defaults to Object (everything), but could be an array of Classes to take any amount of filtered children.

  • Templating
    This is probably the most up in the air, but given where JSF has gone with this so far, it would have to be extremely pluggable. The only idea I can throw out here is possibly using package names for the namespace such that the package, in combination with the @UIComponent annotation, you can dynamically load components without needing to cross reference them in XML.

  • Everything is a Component
    One of the things I found difficult in working on Avatar was that I wanted to have the 'div' and 'span' elements to be refreshable without ever declaring them as a special component. When we get into things like AJAX and callback, ideally we should be able to also callback on a normal HTML div or span for re-rendering.

  • public class PhaseEvent
    First, we should drop phase execution that mimics JSP with separate before, after, and children methods. This could be reduced to an evaluation style like Facelets which follows the CoR pattern. This greatly simplifies wrapping child content and doing logical predicates or iteration. Some other examples out there of this style of execution is the EJB Interceptor API. So you can do things like PhaseEvent.propagate(); or PhaseEvent.propagate(component); to evaluate or re-evaluate children. This style of execution will also encapsulate clientId generation and incrementing other state and pre/post injection and initializing of children for each propagation.

  • public void onEvent(PhaseEvent)
    Martin Marinscheck proposed the idea of generic phases in JSF whereas we currently only have the 5 specific ones that components know about or can 'walk' on. If we come up with a generic event handling convention, we can accomplish this by defaulting to 'onEvent', but if you were propagating an Encode event and wanted to handle it, you would declare a 'onEncode' method. If you were creating a generic repeater component or predicate component for all phases, you would just declare the 'onEvent' since the logic would be the same for all others.

  • EncodeEvent and DecodeEvent
    I think JSF should move to two default phases and queue the other events on a per component basis. While walking the component tree isn't that expensive, it does add up. Walking the component model 3 or 4 times within each request seems unnecessary to me. You encode/render the response and on postback, you have all the information you need to queue up changes to the model. Things like validation, updating, and invocation can be handled like Swing and all queued during the decode phase. During decode, not only are you processing request information, but you also have the 5th Employee object from your Company Object, so why not queue that assignment with an anonymous class?



Here's an example of UIDataTable (probably the ugliest implementation) if written with the above suggestions:

@UIComponent(name="column")
public class UIColumn {

@Facet
private Object header;

@Facet
private Object footer;

@Children
private Collection<?> children;

public Collection<?> getChildren() {
return children;
}

public void setChildren(Collection<?> children) {
this.children = children;
}

public Object getFooter() {
return footer;
}

public void setFooter(Object footer) {
this.footer = footer;
}

public Object getHeader() {
return header;
}

public void setHeader(Object header) {
this.header = header;
}

}

@UIComponent(name="dataTable")
public class UIDataTable {

@Attribute(required=true)
private Object var;

@Attribute(required=true)
private Iterable<?> value;

@Children(UIColumn.class)
private Collection<UIColumn> columns;

public void onEncode(PhaseEvent event) {
ResponseWriter writer = event.getWriter();
Object facet;

writer.start("table");

// header
writer.start("thead");
for (UIColumn c : this.columns) {
writer.start("tr");
facet = c.getHeader();
event.propagate(facet);
writer.end();
}
writer.end();

// footer
writer.start("tfooter");
for (UIColumn c : this.columns) {
writer.start("tr");
facet = c.getFooter();
event.propagate(facet);
writer.end();
}
writer.end();

// body
writer.start("tbody");
for (Object i : this.value) {
this.var = i;
writer.start("tr");
for (UIColumn c : this.columns) {
writer.start("td");
event.propagate(c);
writer.end();
}
writer.end();
}
writer.end();

writer.end();
}

}


@UIComponent(name="repeat")
public class UIRepeat {

@Attribute(required=true)
private Iterable<?> value;

@Attribute(required=true)
private Object var;

@Attribute
private int index;

public void onEvent(PhaseEvent event) {
if (value != null) {
this.index = 0;
for (Object obj : value) {
this.var = obj;
this.index++;
event.propagate();
}
}
}

}