Reference Manual for Gracelets - 2.0.0.RC2SourceForge.net Logo
5.5 - Framework : Gracelet View Factories
Normal gracelet views and tag files usually use groovy scripts and builders to construct a Facelets/JSF view. However, this does not mean it is the only type of views that Gracelets can support. The Graclets system uses an API to create an application level GraceletHandlerFactory (gracelets.api.facelets.GraceletsHandlerFactory) that is responsible for creating an appropriate GraceletHandler (gracelets.api.facelets.GraceletHandler) to handle a particular type of compiled class, generally from a groovy source file (but it could be a compiled java class for instance). The handler factory is defined as follows:

GraceletHandlerFactory.java
Toggle Line Numbers
1 package gracelets.api.facelets; 
2  
3 import gracelets.api.resource.GraceletSource; 
4 import gracelets.api.spi.GraceletsImplementation; 
5 import groovy.lang.GroovyObject; 
6  
7 import java.util.ArrayList; 
8 import java.util.List; 
9  
10 /** 
11  * This is the basic interface/contract for {@link GraceletHandler} factories, responsible for managing 
12  * the registration of multiple {@link GraceletHandlerInitializer}'s. {@link GraceletsImplementation} must 
13  * provide a concrete implementation of this class that will setup at least one default {@link GraceletHandlerInitializer}.  
14  *  
15  * @author ponder 
16  * @author $Author: ponderator $ 
17  * @version $Id: GraceletsHandlerFactory.java 1710 2009-07-10 18:18:28Z ponderator $ 
18  */ 
19 public abstract class GraceletsHandlerFactory { 
20      
21     protected List<GraceletHandlerInitializer> initializers = new ArrayList<GraceletHandlerInitializer>(); 
22  
23     /** 
24      * It is generally expected that sub classes will loop through the registered initializers until one 
25      * returns positive that it can handled the generated class. 
26      *  
27      * @param src The gracelet source for the handler 
28      * @param alias The alias, a view id for views otherwise a valid path 
29      * @param precompiled The precompiled class, or null if the source was empty 
30      * @return An implementation specific handler for the gracelet source, or null if no initializers could generate a handler for the class 
31      */ 
32     public abstract GraceletHandler createHandler (GraceletSource src, String alias, Class<? extends GroovyObject> precompiled); 
33      
34     /** 
35      * Register/add a handler initializer to the current application. 
36      *  
37      * @param initializer The initializer to be registered 
38      */ 
39     public void register (GraceletHandlerInitializer initializer) { initializers.add(initializer); } 
40      
41     /** 
42      * Unregister/remove a handler initializer from the current application. 
43      *  
44      * @param initializer The initializer to be unregistered 
45      */ 
46     public void unregister (GraceletHandlerInitializer initializer) { initializers.remove(initializer); } 
47      
48 } 
As can be seen above, the factory can register GraceletHandlerInitializer's. The default implementation automatically registers the org.ponder.gracelets.impl.DefaultScriptHandlerInitializer and inside the createHandler() method simply loops through the registered initializers and if one can produce a handler for the given compiled class it will then allow that initializer to generate the GraceletHandler.

The DefaultScriptHandlerInitializer (that comes withthe default implementation) is defined as follows:

DefaultScriptHandlerInitializer.java
Toggle Line Numbers
1 package org.ponder.gracelets.impl; 
2  
3 import gracelets.api.facelets.GraceletHandlerBase; 
4 import gracelets.api.facelets.GraceletHandlerInitializer; 
5 import gracelets.api.resource.GraceletSource; 
6 import groovy.lang.GroovyObject; 
7 import groovy.lang.Script; 
8  
9 /** 
10  * @author ponder 
11  * @version $Revision$ 
12  */ 
13 public class DefaultScriptHandlerInitializer implements GraceletHandlerInitializer { 
14  
15     public GraceletHandlerBase create(GraceletSource src, String alias, Class<? extends GroovyObject> clazz) { 
16       return new DefaultGraceletHandler(src, alias, clazz); 
17   } 
18  
19     public boolean handles(Class<? extends GroovyObject> clazz) { 
20       return clazz == null || Script.class.isAssignableFrom(clazz); 
21   } 
22  
23 } 
As can be see here the initializer simply says that if the compiled class is simply a groovy Script instance, then this initializer can create a GraceletHandler to handle it.

The Apache Wicket extension uses this API to handle wicket classes defined in a groovy script. The wicket initializer is defined as follows:

WicketHandlerInitializer.java
Toggle Line Numbers
1 package gracelets.api.extension.wicket; 
2  
3  
4 import gracelets.api.facelets.GraceletHandler; 
5 import gracelets.api.facelets.GraceletHandlerInitializer; 
6 import gracelets.api.resource.GraceletSource; 
7 import groovy.lang.GroovyObject; 
8  
9 /** 
10  * @author ponder 
11  * @version $Revision$ 
12  */ 
13 public class WicketHandlerInitializer implements GraceletHandlerInitializer { 
14  
15     public GraceletHandler create(GraceletSource src, String alias, Class<? extends GroovyObject> clazz) { 
16       return new WicketHandler(src, alias, clazz); 
17   } 
18  
19     public boolean handles(Class<? extends GroovyObject> clazz) { 
20       return GraceletPage.class.isAssignableFrom(clazz); 
21   } 
22  
23 } 
Thus, if the compiled groovy source happens to be a subclass of the GraceletPage class (a sub class of WebPage) then it will be handled by this initializer.

In conclusion, this API allows gracelets to have somewhat of an endless possibility to handle classes of a given type with a particular implementation of a GraceletHandler.
Gracelets 2008 ©Generated by Gracelets Documentation Generator - 08/27/2009 08:28PM CDT