Pages

Monday, December 21, 2009

JSF PhaseListeners With Annotations

Although JSF 2 moved most of it's configuration to annotations still some must be made on xml's, like the phase listeners.
The most straight forward way to implement a mechanism that would enable defining them with annotations are treating phase listeners as singletons. Than we could simply annotate static methods with after phase, before phase annotations.
A second and more elegant/useful way would be to treat phases as cdi events and observe these events.
Annotating static methods
I have created @BeforePhase and @ActionPhase annotations that take phase id as parameter and mark static methods with that :
1:  public class ActionContext extends AbstractThreadLocalMapContext {
2:
3: private static ActionContext instance = new ActionContext();
4: ...
5: @BeforePhase(CycleId.RESTORE_VIEW)
6: public static void activate() {
7: instance.setActive(true);
8: instance.setBeanStore(new ConcurrentHashMapBeanStore());
9: }
10:
11: @AfterPhase(CycleId.RENDER_RESPONSE)
12: public static void deActivate() {
13: instance.destroy();
14: instance.setActive(false);
15: instance.setBeanStore(null);
16: }
17:
18: @AfterPhase(CycleId.INVOKE_APPLICATION)
19: public static void reActivate() {
20: instance.deActivate();
21: instance.activate();
22: }
23:
24: }
Now we need a phase listener that would scan for these annotations and act as a proxy for these methods. I used the Scannotation to scan for the annotations and proxy phase listener still must be defined in faces-config.xml:
1:  public class ProxyPhaseListener
2: implements PhaseListener {
3:
4: private Map<Integer, Set<Target>> afterregistry;
5: private Map<Integer, Set<Target>> beforeregistry;
6:
7: public ProxyPhaseListener() {
8: try {
9: URL ucp = new URL(ClasspathUrlFinder.findClassBase(getClass()).toString().replaceAll("%20", " "));
10: AnnotationDB db = new AnnotationDB();
11: db.setScanClassAnnotations(false);
12: db.setScanFieldAnnotations(false);
13: db.setScanParameterAnnotations(false);
14: db.scanArchives(ucp);
15: afterregistry = new HashMap<Integer, Set<Target>>();
16: beforeregistry = new HashMap<Integer, Set<Target>>();
17: Map<String, Set<String>> map = db.getAnnotationIndex();
18: registerMethods(map, afterregistry, new AfterPhaseRegisterer());
19: registerMethods(map, beforeregistry, new BeforePhaseRegisterer());
20: } catch (Exception ex) {
21: throw new RuntimeException(ex);
22: }
23: }
24:
25: public void afterPhase(PhaseEvent event) {
26: invoke(event, afterregistry);
27: }
28:
29: private void invoke(PhaseEvent event,Map<Integer, Set<Target>> registry) {
30: Set<Target> targets = registry.get(event.getPhaseId().getOrdinal());
31: if (targets != null) {
32: for (Target target : targets) {
33: target.invoke();
34: }
35: }
36: }
37:
38: public void beforePhase(PhaseEvent event) {
39: invoke(event, beforeregistry);
40: }
41:
42: public PhaseId getPhaseId() {
43: return PhaseId.ANY_PHASE;
44: }
45:
46: private void registerMethods(Map<String, Set<String>> annotationIndex,
47: Map<Integer, Set<Target>> registry,
48: PhaseRegisterer phaseRegisterer) throws ClassNotFoundException, SecurityException {
49: Set<String> classes = annotationIndex.get(phaseRegisterer.getPhaseMetaData().getName());
50: if(classes != null) {
51: for (String c : classes) {
52: Class clazz = Class.forName(c);
53: Method[] ms = clazz.getDeclaredMethods();
54: for (Method m : ms) {
55: for (Annotation an : m.getDeclaredAnnotations()) {
56: Class antype = an.annotationType();
57: if (antype.equals(phaseRegisterer.getPhaseMetaData())) {
58: phaseRegisterer.register(an, registry, m, clazz);
59: }
60: }
61: }
62: }
63: }
64:
65: }
66:
67: protected class AfterPhaseRegisterer implements PhaseRegisterer {
68: public void register(Annotation an, Map<Integer, Set<Target>> registry, Method m, Class clazz) {
69: AfterPhase ap = (AfterPhase) an;
70: Integer key = ap.value().ordinal();
71: Set<Target> value = registry.get(key);
72: if (value == null) {
73: value = new HashSet<Target>();
74: }
75: value.add(new Target(m, clazz));
76: registry.put(key, value);
77: }
78:
79: public Class<? extends Annotation> getPhaseMetaData() {
80: return AfterPhase.class;
81: }
82: }
83:
84: protected class BeforePhaseRegisterer implements PhaseRegisterer {
85: ...
86: }
87:
88: interface PhaseRegisterer {
89: void register(Annotation an, Map<Integer, Set<Target>> registry, Method m, Class clazz);
90: public Class<? extends Annotation> getPhaseMetaData();
91: }
92:
93: protected class Target {
94: private Method method;
95: private Class clazz;
96:
97: public Target(Method method, Class clazz) {
98: this.method = method;
99: this.clazz = clazz;
100: }
101:
102: private void invoke() {
103: try {
104: method.invoke(null);
105: } catch (Exception ex) {
106: throw new RuntimeException(ex);
107: }
108: }
109: ...
110: }
111:
112: }
113:
I believe this may improved, so that it could use singleton beans instead of static methods. Also more work has to be done to pass the phase event as a parameter.
An easier way to implement this with non-static methods would be using the CDIs event producer/observer api.
Producer/Observer
Here is my client bean looks like :
1:  @ApplicationScoped
2: @Named
3: public class TestBean implements Serializable {
4:
5: public void afterRestoreView(@Observes
6: @PhaseEventDefinition(value=CycleId.RESTORE_VIEW, when=AfterBeforeEnum.AFTER)
7: PhaseEventHolder holder) {
8: System.out.println("after restore view : " + holder.getEvent().getPhaseId());
9: }
10:
11: }
@Observers annotation states that this bean will observe events and the @PhaseEventDefinition tells which phase we will listen to. PhaseEventHolder object holds the PhaseEvent parameters that's missing on the previous example. Again we will need a phase listener that would listen to all phases and forward them as events, wrapping a jsf PhaseEvent with our PhaseEventHolder.
1:  public class ProxyPhaseListener
2: implements PhaseListener {
3:
4: private PhaseProducer phaseProducer;
5:
6: public void afterPhase(PhaseEvent event) {
7: fireEvent(event,AfterBeforeEnum.AFTER);
8: }
9:
10:
11: public void beforePhase(PhaseEvent event) {
12: fireEvent(event,AfterBeforeEnum.BEFORE);
13: }
14:
15: private void fireEvent(PhaseEvent event, AfterBeforeEnum when) {
16: final int ordinal = event.getPhaseId().getOrdinal();
17: final CycleId[] cycles = CycleId.values();
18: PhaseEventHolder phaseEventHolder = new PhaseEventHolder(event);
19: AnnotationLiteral<PhaseEventDefinition> annotationLiteral =
20: new PhaseLiteral(cycles[ordinal], when);
21: getPhaseProducer().fireEvent(phaseEventHolder,annotationLiteral);
22: }
23:
24: private PhaseProducer getPhaseProducer() {
25: if(phaseProducer == null) {
26: FacesContext context = FacesContext.getCurrentInstance();
27: phaseProducer = (PhaseProducer) context.getApplication()
28: .getELResolver().getValue(context.getELContext(),null,"phaseProducer");
29: }
30: return phaseProducer;
31: }
32:
33: public PhaseId getPhaseId() {
34: return PhaseId.ANY_PHASE;
35: }
36: }
37:
PhaseProducer is the bean that fires the phase holders as events:
1:  @ApplicationScoped
2: @Named
3: public class PhaseProducer implements Serializable {
4:
5: @Inject @Any
6: private Event<PhaseEventHolder> phaseEvent;
7:
8:
9: public void fireEvent(PhaseEventHolder phaseEventHolder, AnnotationLiteral<PhaseEventDefinition> annotationLiteral) {
10: phaseEvent.select(annotationLiteral).fire(phaseEventHolder);
11: }
12: }
This approach is much simpler, usefull and clearer than the first one. Only thing I am not happy with it is that I had use EL to access the phaseProducer object.
I keep the source here so, chek it out. It should run in a glassfish-v3 environment.

Wednesday, December 16, 2009

Developing Custom Scopes/Contexts For Weld

This one came up while developing an example JEE6 project, which I'll add it up here in the future. The case is I had a textbox bound to a request scoped bean. When user triggers the paint action the value in the textbox is to be added to the list below and the textbox should be empty. I thought marking the component request scoped should have been enough to empty its values but it didn't.Apparently to empty the value;
1. I might set the value of the field at the action method. Use a clone for the list.
2. Use a JSF component that doesn't redisplay value after post back like the inputSecret.
3. Develop a custom scope that recreates it self after actions are invoked.
Anyway maybe I am missed a simpler solution but I chose number 3 :) .
To do that first thing is to create a new scope type. I called my scope the "ActionScoped":
1:  @NormalScope(passivating=false)
2: @Retention(RUNTIME)
3: @Target({TYPE, METHOD})
4: @Inherited
5: public @interface ActionScoped {
6: }
@NormalScope annotations marks an annotation as a scope-type. Next we need a context that would define when these action scoped objects exist like the request scope exist while there is a http request... This is the action context :
1:  import org.jboss.weld.context.AbstractThreadLocalMapContext;
2: import org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore;
3:
4: public class ActionContext extends AbstractThreadLocalMapContext {
5:
6: private static ActionContext instance = new ActionContext();
7:
8: private ActionContext() {
9: super(ActionScoped.class);
10: }
11:
12: public static ActionContext getInstance() {
13: return instance;
14: }
15:
16: @Override
17: protected boolean isCreationLockRequired() {
18: return false;
19: }
20:
21: public void activate() {
22: setActive(true);
23: setBeanStore(new ConcurrentHashMapBeanStore());
24: }
25:
26: public void deActivate() {
27: destroy();
28: setActive(false);
29: setBeanStore(null);
30: }
31:
32: public void reActivate() {
33: deActivate();
34: activate();
35: }
36: }
It's backed with an thread local object which is handled by the weld parent class. Bean store is where we are going to store the scoped beans. Plus I added some methods to activate (set a new bean store) /deactivate (destroy the bean store) the context. Now this context has to be activated with the start of the restore view.Deactivated and reactivated after the invoke application phase. Here is a phase listener that does that :
1:  public class ActionScopedPhaseListener implements PhaseListener {
2:
3: public void beforePhase(PhaseEvent event) {
4: if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW)) {
5: ActionContext.getInstance().activate();
6: }
7: }
8:
9: public void afterPhase(PhaseEvent event) {
10: if (event.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
11: ActionContext.getInstance().deActivate();
12: } else if (event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION)) {
13: ActionContext.getInstance().reActivate();
14: }
15: }
16:
17:
18: public PhaseId getPhaseId() {
19: return PhaseId.ANY_PHASE;
20: }
21: }
22:
Now last thing we have to do is register our context object. In order to do that we need to define an 'extension'. There is a nice example here about extensions, spi... Without an extension we are not able listen to events fired from the weld container which we could use to add our new context object. To define an new context we need the META-INF/services/javax.enterprise.inject.spi.Extension file which contains the qualified name of our extensions class. In this case it's 'org.mca.ewall.extensions.Extensions'. Here is what the class looks like :
1:  public class Extensions implements Extension, Service{
2:
3: public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
4: event.addContext(ActionContext.getInstance());
5: }
6:
7: public void cleanup() {
8: }
9: }
It simply registers the context object after the application starts up (after the beans are discovered by the weld container). Now the beans could be annotated as @ActionScoped.

Wednesday, December 9, 2009

State of the 'Dependecy Injection'

"Dependecy Injection" is one of the most popular design patterns on the Java platform. It was suggested by Martin Fowler, here, instead of the term "Inversion of control". Article was published on 2004.
What it brings to a application is a way to create, compose, use and destroy any java object, which are called beans.
The leading framework that first used this approach was the "the Spring Framework". The approach emerged as a alternative to EJB's. The applications built with it are easier to test and offered a easy way to integrate to most of the other frameworks and technologies out there. If you check out the api packages you can see the support for other frameworks like jsf, hibernate etc.
Today "Dependecy Injection" is part of JEE6 named CDI, JSR-299. Reference implementation is called Weld. Here are some of the highlights of CDI:
XML vs. Annotations
CDI dumps the xml approach. However there are still some use for xml's. Every bean archive must have a META-INF/beans.xml even if its empty. This file marks the jar archive as a bean archive and is scanned for beans. 'beans.xml' is also where you enable and define the ordering of 'alternative' beans and interceptors.
Qualifiers
First thing that CDI takes to account while trying to inject a bean is the type of the bean. If however there are more than one bean that could qualify CDI requires a Qualifier meta-data to resolve the ambiguity. CDI has a way to define this meta-data as an annotation, thus making our app. strong typed apposed to the usual string based qualifier approach.
Events
By defining a few annotations we could implement the Observer pattern without any boilerplate code.
Decorators
Again with annotations we could implement the decorator pattern.
Part of JEE6
Now we could inject our beans to servlets and filters like we do to any other class.
Overall as far as I could tell CDI looks like it could improve an applications code quality making it decoupled and strong-typed. JEE6 still needs some time though, best implementation out there seems to be JBoss 6 Milestone 1.

Thursday, November 19, 2009

Sinek, spreadsheet component, for JSF 2

Here are some notes on developing a spreadsheet component for JSF. Here is how it looks like :Cells contents are being updated with ajax, user is able to add rows/columns by clicking the buttons on the bottom-right corner. I am calling this component 'sinek'. Probably I will rename it later. To check the source code click here.
Here are the parts that make up the component :
  • org.mca.sinek.jsf
This package has 3 files that make up the main component. UISinek, SinekRenderer and WorkSheet.
  • WorkSheet is the datamodel. Its basically a two dimensioned array of Strings:
 public class WorkSheet {
List<List<String>> sheet;
public Integer getNumOfColumns() {
...
public int getNumOfRows() {
...
public List<String> addEmptyRow() {
...
public void addEmptyCol() {
...
}
It also has methods that return the number of rows, add rows/cols.
  • UISinek is the component that holds the state values. After its added to view it adds the sheet cells as its children. Cells are made up of inputtext components :
 @FacesComponent(value = "sinek")
@ListenerFor(systemEventClass = PostAddToViewEvent.class)
@ResourceDependency(name = "jsf.js", library = "javax.faces", target = "body")
public class UISinek extends UIInput {
...
@Override
public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
Map<String, String> requestParameterMap = getFacesContext().getExternalContext()
.getRequestParameterMap();
String exec = requestParameterMap.get("javax.faces.source");
if((getClientId()+ "_addr").equals(exec)) {
getWorkSheet().addEmptyRow();
} else if((getClientId()+ "_addc").equals(exec)) {
getWorkSheet().addEmptyCol();
}
int count = getChildCount();
createRows();
}
...
private void createRow(List<String> row, int rindex) {
ValueExpression ve = this.getValueExpression("value");
String exp = ve.getExpressionString();
exp = exp.substring(0, exp.length() - 1);
int cl = 0;
for (String cell : row) {
String id = getId() + "_" + rindex + "_" + cl;
if(findComponent(id) != null) {
continue;
}
HtmlInputText in = new HtmlInputText();
ValueExpression el = ELUtils.createValueExpression(exp + ".sheet[" + rindex + "][" + cl + "]}");
in.setId(id);
in.setValueExpression("value", el);
in.setLocalValueSet(true);
in.setOnkeyup("jsf.ajax.request(this,event);");
getChildren().add(in);
cl++;
}
}
}
We are annotating it with the @FaceComponent annotation. It listens for the PostAddToViewEvent with the @ListenFor annotation. When the event fires processEvent method will be fired. Process events creates HtmlInputText components whose values are backed up with the datamodel. Also sets up the ajax call which will update the component values. Because we will be using ajax we have to define it with the @ResourceDependency annotation. The "javax.faces.source" will be used to identify the add col/row events.
  • SinekRenderer is the renderer. It renders our cells into the cells of a table:
 @FacesRenderer(rendererType = "sinek", componentFamily = "javax.faces.Input")
@ResourceDependencies({
@ResourceDependency(name = "sinek.css", library = "org.mca", target = "head"),
@ResourceDependency(name = "jsf.js", library = "javax.faces", target = "body")})
public class SinekRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext facesContext, UIComponent comp) throws IOException {
UISinek sinek = (UISinek) comp;
ResponseWriter writer = facesContext.getResponseWriter();
writer.write("<table id=\"" +sinek.getClientId()+"\" class=\"mctable\">");
int R = sinek.getWorkSheet().getNumOfColumns();
renderFooter(writer, R, sinek);
renderColumnHeaders(writer, R);
renderCells(facesContext, writer, sinek);
writer.write("</table>");
}
private void renderCells(FacesContext facesContext, ResponseWriter writer, UISinek sinek) throws IOException {
int i = 0;
int rno = 1;
int r = sinek.getWorkSheet().getNumOfColumns();
List<UIComponent> rows = sinek.getChildren();
for (UIComponent c : rows) {
if (i % r == 0) {
if (i % 2 == 1) {
writer.write("<tr class=\"altrow\">");
} else {
writer.write("<tr>");
}
rno = renderRowHeader(writer, rno);
}
writer.write("<td>");
c.encodeAll(facesContext);
c.setRendered(true);
writer.write("</td>");
if (i % r == (r - 1)) {
writer.write("</tr>");
}
i++;
}
}
@Override
public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
}
@Override
public boolean getRendersChildren() {
return true;
}
}
Renderers are defined with the @FacesRenderer annotation and again @ResourceDependecy annotation is used for the css and ajax scripts. It renderers the children (cells) so we need to override the encodeChildren and getRendersChildren methods.
  • mca.taglib.xml : Defines the namespace and components.
  • sinek.css : Style sheet for our project.
My example also contains Hello class which is a example bean used on page index.xhtml.
Thats all for now drop me a line if you need more info and be sure to check-out the source.

Tuesday, November 10, 2009

JSF2 Notes

These are the notes I derived from blogs on JSF 2 :
  • Composite Components
Ed Burn's have a number of articles on developing 'composite components'. CC's are for creating true components that we can attach converters, listeners etc. Previously you could do the similar things with the help of the facelets, which was somewhat limited. Rick Hightower has an excelent series of articles about this, called 'Facelets fits JSF like glove'. Here is what a CC looks like in JSF2 :
 <cc:interface
name="inputtext"
displayName="label plus text"
expert="true"
hidden="false"
preferred="true">
<cc:attribute name="label" required="true" />
<cc:attribute name="id" required="true" />
<cc:attribute name="value" required="true" />
</cc:interface>
<cc:implementation>
<h:outputLabel id="lbl_#{cc.attrs.id}" for="#{cc.attrs.id}"
value="#{cc.attrs.label}" />
<h:inputText id="#{cc.attrs.id}" value="#{cc.attrs.value}" />
</cc:implementation>
This forms a common element with an inputtext and its label. Apparently there are many tricks to learn here. Its formed of two parts, first is the interface. As far as I can tell this is the UIComponent part. We define valueholders, attributes, actionsources that our CC will respond to. Second part is the implementation. This is like the renderer part. We glue the components together here.
One thing that I didn't like while trying out these was, with the facelets way I could use the CC with panelGrid component and the components forming the CC would be on different grids. This way I could easily align the components. Now on jsf2, CC truely acts like one component and all the sub components fit into the same grid.
  • We can define exception handlers on faces-config.
From Ryan Lubke's blog, http://blogs.sun.com/rlubke/
  • There is a javax.faces.PROJECT_STAGE context parameter we can play with which will make our application behave differently in different stages. Like on 'development' stage certain components will be added to the view root automatically like perhaps facestrace. We are able to access it through Application.getProjectStage()
  • There is a new Resource handling architecture. By default resources are searched under (webapp_root)/resource or (webapp_root)/META-INF/resources and there is a EL support to load them from the pages. #{resource['lion.jpg']} will generate a url to a image under these locations I mentioned. Spec also enables that different versions of the same resource be available to application.
  • Components can be annotated with @ResourceDependency annotation and provide the list of resources (css, js, images...) they need inorder to work. These resources might be rendered on different parts of the page with the help of h:body and h:head tags.
  • There is 'View Scope' which as long as the view is not changed. It's accessible using UIViewRoot.getViewMap and #{viewScope} through EL.
  • There is a system event listener api where you could listen to events like 'configuration complete'.
  • Now we have control over request parameters. We can validate convert them if needed.

Looks like JSF2 has more nice stuff in it like the 'View Declaration Language'. Spec it self seems to be the best resource at the moment though.

Tuesday, October 27, 2009

ICEFaces

Nice people at 'Packt Publishing' are sending me a copy of their new ICEfaces book, 'ICEfaces 1.8: Next Generation Enterprise Web Development', for me to review. You can check it out here.