Alexander Smirnov’s personal Weblog

April 6, 2011

RichFaces CDK – how to create JSF component

Filed under: Java, Java server faces — alexsmirnov @ 3:48 pm
JSF component if pretty complicated beast. In the worst case, you have to create UIComponent class, with a lot of attributes with special getter’s and setters that interacts with StateHelper,  renderer-specific class that contains similar attributes for html-related parameters ( even worse, they require special code if you wish to use attributes access optimization in Renderer ) and defines JSF Behavior events for them, create Renderer class that generates html code using spaghetti of startElement/writeAttribute/writeText/endElement calls, describe these classes in the faces-config.xml, create Facelets taglib.xml to define component as VDL tag, write TagHandler class. If your component fires FacesEvents for some listeners, you also need Listener interface and listener TagHandler with default ListenerWrapper.
Similar work required for the ClientBehavior, except renderer-specific implementation.
Faces Converters and Validators a little bit simple because they don’t require separate renderers and cannot broadcast events.
RichFaces uses special Component Development Kit ( CDK ) that takes rid for most of these tasks and lets developers to concentrate on component functionality only.
In the best case, developer has to only create abstract component class, with functional code only, and Renderer template that describes generated Html with Facelets-like syntax. Everything else generated by the tool.

Define Java Package as Components Library

By default, all components in the same projects included to the same library. Developer can provide package-level annotation to define library for all components which belong to that package
package-info.java:
@TagLibrary(uri=”http://richfaces.org/test”,shortName=”testLib”)
package org.richfaces.cdk.test.component;
import org.richfaces.cdk.annotations.TagLibrary;

Abstract Component Class

Most JSF components contains only a few lines of functional code. With cdk, developer can only create java class with such functionality and lets boilerplate to be generated.

Base Class

The base class can be abstract if it need references to generated methods. That class should be annotated with @JsfComponent annotation that describes generation details:
@JsfComponent(type = “foo.Bar”,
family=”foo.Bar”,
description=@Description(displayName=”Bar Component”,
largeIcon=”large.gif”,
smallIcon=”spall.png”),
generate=”foo.component.UIBar”,
facets=@Facet(name=”caption”,
generate=true,
description=@Description(“Caption Facet”)),
fires={@Event(FooEvent.class),
@Event(value=BarEvent.class,listener=BarListener.class)},
interfaces=Ext.class,         tag=@Tag(name=”abbr”,generate=true,handler=”foo.facelets.barHandler”),
attributes={“core-props.xml”,
“events-props.xml”,
“i18n-props.xml”},
renderer=@JsfRenderer(type=”foo.HtmlBarRenderer”)),
)
public abstract class AbstractBarComponent extends UIComponentBase

For type-safe definition, optional annotations defined as @JsfComponent attributes, so Java compoler can check their usage and code competition available in modern editors. All annotation attributes are optional and can be inferred by CDK:

  • type() defines JSF component type, used as key when framework creates component instance. Its value can be also defined by public constant COMPONENT_TYPE or inferred from the class name by Naming Conventions#.
  • family() defines component family, common for the group of similar components ( for example, UICommand, HtmlCommandButton and HtmlCommandLink all share “javax.faces.Command” family ).
  • description() defines optional description of component, used by JSF tools and documentation generator. Full description comes from the class JavaDoc comment or can be defined by value() attribute.
  • generate() defines the fully qualified name for concrete component class. There are two options for default value of that attribute. If @JsfAnnotation applied to the abstract class, the name of generated class will be inferred from Naming Conventions. Otherwise, if annotated class is concrete, CDK will not generate concrete component class and use annotated class as component implementation.
  • facets()  defines component facets. It’s array of @Facet annotations. Facet#generate() attribute tells CDK to generate getter and setter for facet.
  • fires() is array of @Event annotations which define JSF events fired by components. It defines FacesEvent class for event, listener and source interface. For each event, CDK generates add/remove/get<Event>Listener methods defined by the source interface, creates eventListener tag handler and creates listener instance that can be binded to EL-expression.
  • tag() is array of @Tag annotations. Using multiply tags for single component is necessary to define tags for different VDL ( View Description Language ), or make aliases. Tag links JSF component and its renderer. If no tag defined for component, but there is Renderer associated with component, Facelets tag will be generated. Tag name, handler class and library will be inferred.
  • attributes() contains array of strings, each contains the name of faces-config.xml fragment with attributes definitions, that lets CDK to reuse attributes definition in different components. CDK looks for these files in project classpath META-INF/cdk/attributes folder, and provides set of such files for the most html elements and standard components.
  • renderer() associates component with Renderer implementation. There are two options to link component with renderer#: by the renderer type or by the template name. For type, CDK doesn’t check existence of the target renderer, because it would be defined in another module. For template name, CDK enforces both renderer and component to share the same renderer type and family.
  • interfaces() attribute contains array of Java interface classes that should be implemented by generated component, that provides another way to reuse attributes definitions in different components, similar to ‘attributes()’ option. That’s preferred method for user attributes, because it allows type-safe check. The result is the same as including these interfaces in ‘implements’ keyword for component class, but it does not enforce component class to be abstract, and can be used to define interfaces implemented by the renderer-specific components ( see late ).

Renderer Specific Components

In JSF, the single component can have more then one renderer, to allow different client-side representations of the same functionality. For example, base command UICommand component can be rendered as html button ( <input> element ) or link ( <a> element ). Because these representations can have different attributes and ClientBehavior events, JSR best practices recomment to have renderer-specific component that contains bean attributes for specific implementation. CDK follows that structure and lets developer to define renderer-specific components in the base class using @JsfComponent#components() attribute.
This attribute contains array of @RendererSpecificComponents annotations which have the same set of attributes as @JsfComponent, except the family() that should be shared by all components. These annotations lets to define third level of generated classes, specific to the particular renderer.

Define Attributes

JSF component attributes not are plain bean getters and setters, they can contains code to evaluate EL-expressions, and to persist value in the View state. Also, some attributes can be associated with ClientBehavior events. CDK generates all code to make attributes compatible with JSF spec.
To define component attribute, developer can annotate class field or getter method with @Attribute annotation. The method can be abstract, that allows to use that annotation in the interfaces or abstract classes:
@Attribute(
aliases={@Alias(“getAction”)},
defaultValue=”null”,
description=@Description(),
events={@EventName(value=”click”,defaultEvent=true)},
hidden=false,
literal=false,
passThrough=false,
readOnly=true,
required=false,
generate=true,
suggestedValue=”#{foo}”,
signature = @Signature(parameters = {String.class},
returnType = Boolean.class))
public abstract MethodExpression getMethodExpression();
Same as for the @JsfComponent, all annotation attributes are optional.

  • aliases() lets to define different names for the single attribute. In the example above, CDK will generate public MethodExpression getAction(){ return getMethodExpression();}
  • defaultValue() should contain valid Java expression evaluated to the default attribute value.
  • description() contains attribute description for IDE and documentation, the same annotation used elsewhere in CDK. By default, CDK uses method JavaDoc comment to generate description.
  • events() contains array of ClientBehavior events definition. The value of EventName annotation is name itself, and defaultEvent defines marks event as component default#.
  • hidden() attribute tells CDK to remove attribute from tag.
  • literal() disables EL- expressions for attribute.
  • passThrough() defines attribute to be rendered as html attribute without conversion. Attributes with ClientBehavior events always threated as passed through.
  • readOnly disables generation for the setter method.
  • requires() enforces tag handler to check what developer provided explicit value for that attribute.
  • geterate() enforces CDK to generate getter and setter methods for attribute, even if concrete method already exist. If omitted, CDK checks ‘abstract’ modifier for getter and setter methods and generate implementation for abstract methods only.
  • suggestedValue can be used in tools for code competition.
  • signature() only used for attributes with MethodExpression type to define signature of the target method.

Define Facets

Component facets can be defined in the two ways: in the facets() attribute of component annotations ( described above ) or by the getter method @Facet annotation:
@Facet(generate=true,
description=@Description())
public abstract UIComponent getHeader();
The ‘name()’ attribute is optional in this case, CDK uses bean attribute name instead. Same as for the attribute, it uses JavaDoc comment to generate description and generate implementation for abstract methods.

March 25, 2011

Testing client-side part of JSF applications with HtmlUnit

Filed under: Java, Java server faces — alexsmirnov @ 3:54 pm

There are couple tools that can be used to test generated html and client-side scripts. The most accurate tools are  these that run test in the real browser ( for example, Selenium framework ), but, in the some cases, they cannot be used – machine that runs tests has to have GUI ( rare available on continuous integration servers ), preconfigured instances of target browsers, and these tests can take too much time because you have to start new browser instance for each test to eliminate dependencies between them.

Another option is client emulator, that only simulates target browser. Although it’s less accurate then the real browser, the advantages are: no additional software required, it runs faster, and test code has full control on test client configuration. For developer tests in RichFaces, we use HtmlUnit library, integrated with our embedded FacesEnvironment.

Usage

Dependencies

HtmlUnit teste require these dependencies :
Test Project
+- org.jboss.test-jsf:jsf-test-stage
+- org.jboss.test-jsf:jsf-test-jetty ( optional )
+- org.jboss.test-jsf:htmlunit-client
+- javax.servlet:servlet-api
+- javax.servlet.jsp:jsp-api
+- javax.el:el-api
+- javax.servlet:jstl
+- junit:junit
+- com.sun.faces:jsf-api
\- com.sun.faces:jsf-impl ( or any other you want to test with ).
htmlunit-client does not contain dependencies for servlet or JSF because it can be used with different versions and implementations.

HtmlUnitEnvironment

HtmlUnitEnvironment combines embedded JSF environment and HtmlUnit client designed to work with it. Test example:
public class FacesTest {
 private HtmlUnitEnvironment environment;
 @Before
 public void setUp() throws Exception {
 this.environment = new HtmlUnitEnvironment();
 this.environment.withWebRoot("org/jboss/test/hello.xhtml").start();
 }
 @After
 public void tearDown() throws Exception {
 this.environment.release();
 }
In this test, the new instance of HtmlUnitEnvironment created  before each test, configured with virtual web application from package ‘org/jboss/test’ content and initialized to serve requests. The tearDown() method stops environment after each test and releases its resources.

Using in tests

The simple test gets JSF page, fills input field with new value and submits form to server.
After submit, it verifies that input element set new value to the session-scope bean ant that value was rendered back by outputText component:
@Test
 public void testHelloFacelets() throws Exception {
 HtmlPage page = environment.getPage("/hello.jsf");
 HtmlForm htmlForm = page.getFormByName("helloForm");
 HtmlInput input = htmlForm.getInputByName("helloForm:username");
 input.setValueAttribute("foo");
 HtmlElement submitElement = page.getElementById("helloForm:submit");
 HtmlPage responsePage = submitElement.click();
 HttpSession session = environment.getServer().getSession(false);
 HelloBean bean = (HelloBean) session.getAttribute("HelloBean");
 assertEquals("foo", bean.getName());
 Element span = responsePage.getElementById("responseform:userLabel");
 assertEquals("foo", span.getTextContent().trim());
 }

HtmlUnitRule

In Junit 4.x, MethodRule version of environment can be used instead of setup/release it in code. This example does the same as one with @Before/@After methods:
public class FacesTest {
 @Rule
 public HtmlUnitRule environment= HtmlUnitRule.create().withWebRoot("org/jboss/test/hello.xhtml");

March 24, 2011

RichFaces JavaScript service

Filed under: Java, Java server faces — alexsmirnov @ 3:22 pm

Preface

In the modern Web interface development, inline event handlers considered as the bad practice – see article for detail.
Also, for performance reason, Web experts ( Yahoo  YSlow, Google  Page Speed and others ) recomend to load  plain html code first, and only add user interaction code at the bottom of page.
For the same reason, all JavaScript files has better to be loaded at the bottom of page too.
jQuery library makes that stile pretty easy, using $(page).ready() or just $() callbacks. But, there is a problem with JSF AJAX: jQuery knows nothing about JSF library, and code inside page.ready handler will nether be called after page update.
Another drawback for JavaScript dependencies comes from the JSF 2 component resources which cannot be changed from per-component dependencies ( useful for development stage ) to solid compact library or external CDN refferences.
RichFaces JavaScript service designed to solve problems above.

How it works

RichFaces provides JavaScriptService object ( available via ServiceTracker )  to render JavaScript defeered JavaScript code at the bottom of the page or inside jQuery page.ready handler.
Getting service instance:
JavaScriptService javaScriptService = ServiceTracker.getService(JavaScriptService.class);

The service instance created by RichFaces initialization listener, and can be replaced by different implementation by custom Module, see documentation for ServiceTracker.
Adding script to be rendered at the bottom of page:
javaScriptService.addScript(facesContext, script);

What does this method do ? It looking for special UIScripts component in the UIViewRoot.componentResources collection, or creates new if there to such component yet, and append script object to the Set of objects submitted to be rendered. To avoid rendering of the same script more then once, it checks collection for the same script ( using equals() method ). If the same object already submitted to be rendered, it returns existing object. Otherwise, new script added to the collection and returned by method. That check allows to render the same script only once, even if component that requires such code rendered many times.
For example, component that wraps jQuery widget can use special ‘class’ attribute to mark its instance on the page, and the same script can activate all widgets using that class as discriminator.
Another method lets developer to append script that will be rendered inside page.ready handler:
javaScriptService.addPageReadyScript(facesContext, script);

The only difference with addScript() method that scripts appended into separate collection that processed in the special way. UIScript component writes them inside such JavaScript code:
<script type=”text/javascript>

$(document).ready(function() {

content of the scripts collection goes here

});

</script>

See jQuery documentation for ready() function for details how it works.
For AJAX requests ( important note – only RichFaces AjaxBehavior supported ) the same scripts rendered in the <execute> part of response that processed after DOM updates. Therefore, the same code works for both page rendering and AJAX modes.
In addition, script object can implement org.richfaces.resource.ResourceLibrary interface and provide additional dependencies. These dependencies will be rendered as links to external resources before in-content <script> element.

 

Test JSF applications with staging server.

Filed under: Java, Java server faces — alexsmirnov @ 3:18 pm

Test JSF Applications with Embedded Server

Preface

JSF is very complicated framework, with a lot of tight related components, that makes testing pretty complicated. It runs inside Servlet container, and framework behavior depends from container configuration. The goal of embedded servlet container is providing flexible test environment suitable to test parts of JSF application: Composite components, view fragments and templates. The idea is very similar to Jboss Arquilian framework, with some JSF-specific extensions. The main answer to the question why to not use Arquillian to test RichFaces components is what it was introduced far before  Jboss implementation. Another answer is JSF-specific features and speed, embedded stage server runs much faster real implementations.

Features

  • Container runs in the same thread that performs client request, what allows test code to inspect request-scope objects, or even interrupt request processing for asserts.
  • Container configuration made from the java code, that lets every test has its own settings and web application content. For example, the same test can be invoked with different initialization parameters.
  • Extremely fast, container doesn’t parese any configuration files, setup network connections or instantiate multiply applications.
  • Single Java object holds container instance, therefore it can be used with any test framework.
  • Integration with HtmlUnit to simulate web client.

Limitations

  • No JSP compiler, only Facelets views can be used.
  • Ignores web.xml content. Container should be configured from Java code.
  • No network access
  • No JNDI, no injection, only base javax.servlet interfaces.
  • No transactions
  • By default, FacesServlet initialized with suffix-based mapping ‘*.jsf’.

Usage

Instantiation of FacesEnvironment

jUnit 4 test class fragment:
private FacesEnvironment environment;
@Before
public void setUp() {
environment = FacesEnvironment.createEnvironment().start();
}
@After
public void thearDown() throws Exception{
environment.release();
}
This code creates an instance of environment, initializes JSF framework and starts server instance before each test, and releases resources after test. The version of this method with ApplicationServer parameter lets create environment for different server implementation ( currently, embedded Jetty server supported ).

Configuration

FacesEnvironment class has set of configuration methods to describe web application context and setup server. all methods returns back the same instance, so they can be chained:
withContent(String,String) – define content of web resource for given path:
environment = FacesEnvironment.createEnvironment().withContent(“/test.xhtml”,
“<html xmlns=\”http://www.w3.org/1999/xhtml\”\n” +
”      xmlns:ui=\”http://java.sun.com/jsf/facelets\”\n” +
”      xmlns:h=\”http://java.sun.com/jsf/html\”>”+
“<h:form id=\”helloForm\” >”+
”    <h:outputText value=\”foo_bar\” />\n” +
“</h:form>\n” +
“</html>”).start();
withResource(String,String) – put content of classpath resource to the given path in servlet context.
withWebRoot(String) – create virtual web server context from the package containing given resource. Suitable to create web application fragment from resources stored in the jar. Another way to create vitrual servlet context is system property ‘webroot’, that should contain path to the folder with web application content.
withResourcesFromDirectory(String path, URL resource) – Add all resources from the directory to the virtual web application content. Only ‘file’ or ‘jar’ protocols are supported. If this parameter points to a file, it will be converted to a enclosing directory.
withInitParameter(String name, String value) – add ServletContext initialization parameter to value.
withFilter(String name, Filter filter) – add filter in front of FacesServlet.
Additional configuration can be performed directly on the ApplicationServer instance, see JavaDoc for details.

Performing request

To perform JSF request, call environment.createFacesRequest(String url) method:
@Test
public void testRequest() throws Exception {
FacesRequest request = environment.createFacesRequest(“http://localhost/test.jsf&#8221;);
assertNotNull(request.execute());
String contentAsString = request.getConnection().getContentAsString();
assertTrue(contentAsString.contains(ResponseStateManager.VIEW_STATE_PARAM));
}
This method gets request URL and returns FacesRequest object, that allows additional configuration ( adding request parameters, cookies, headers ). The request is not active until start() or execute() methods callled. execute() method performs whole request cycle, while start() only initialized request, created FacesContext and returns, that allows test to execute Faces Lifecycle directly inside request context.

FacesRule

FacesRule is jUnit 4 MethodRule that invoked around every test method. It automatically configures and starts converter before method and shut down it after. Using method rule allows to combine with another rules ot test runners – jsf-test MockRunner, Mockito runner, parametrised tests. There is fragment of test that creates mock instances of Jsf beans and run facelets fragment with user registration form, using mock objects for  ‘facade’ and ‘user’ beans:
@RunWith(MockitoJUnitRunner.class)
public class RegisterTest implements ServletRequestListener{

@Rule
public FacesRule rule = HtmlUnitRule.create().withResource(“/registerTest.xhtml”, “registerTest.xhtml”).withListener(this);
@Mock
Facade facade;
@Mock
User user;
@Before
public void setUp() throws Exception {
rule.setSessionAttribute(“facade”, facade);
}
public void requestInitialized(ServletRequestEvent sre) {
sre.getServletRequest().setAttribute(“user”, user);
}

registerTest.xhtml only includes registration form fragment by <ui:include> directive. Therefore, this test lets check functionality of the single fragment without having real EJB for facade, database, and without inference from other parts of application.

March 23, 2011

JSF Mocks

Filed under: Java, Java server faces — alexsmirnov @ 4:23 pm

Preface

In the Test Driven Development mocking real objects is one of fundamental parts. For low-level JSF components and extensions development, having mocking framework environment is necessary for unit testing. Unfortunately, there are some problems:

  1. Most classes from JSF API not interfaces, but abstract and concrete classes. While modern mocking libraries, Mockito, jsf class extensions, and others, allows to mock concrete classes, all of them require some bytecode manipulation library to create mocks at runtime. For example, both Jboss Seam and EasyMock class extensions require different versions of javaassist library.
  2. Libraries like Apache Shale provide stub objects for JSF api, that not so convenient for testing, and none of them had JSF 2.0 version at the Richfaces 4.0 development time.

The idea behind jsf-mock project was similar to Easymock class extension library ( create subclasses for mocked objects that delegate calls to the EasyMock  environment ), but, because we know which classes from JSF API should be wrapped, do it at compilation time and provide ready to use mock objects for tests.

Target environment

Jsf-mock objects can be used with:

  1. both Jsf 1.2 and 2.x, depends only from the jsf-api library used for tests.
  2. EasyMock 2.5.2 and late.
  3. Junit 3.x and 4.x, while we recommend to use Junit 4.8 and later for which we provide runners and method rules that takes care most of configuration jobs.
  4. TestNG.

Mock Generator Maven Plugin

All mock classes generated by the maven-mock-generator-plugin. This plugin intended for internal use to generate jsf-mock library, but can be also used to create mocks for custom JSF components. That plugin generates mock classes for all JSF objects and utility class that instantiates these objects.

Usage.

The simplest way to create mock objects for JSF is using FacesMock#createMock(Class toMock) method, or similar other from the FacesMock class. These methods have the same signatures and functionality as in the EasyMock class, but, if the class to mock beyond JSF API, it creates an instance of precompiled mock class. Otherwise, call will be delegated to corresponded EasyMock class.

There are some problem with JSF. Sometimes, it may be necessary to use FactoryFinder#findFactory or FacesConstect#getCurrentInstance static methods, that cannot be mocked.

FacesEnvironment

To solve that problem, jsf-mock project contains MockFacesEnvironment class that performs necessary configuration procedures. That class designed to use as internal field in the test class, and can be used with any test framework: Junit 3 and 4, or Testng.

Usage, with Junit 4.8:

private MockFacesEnvironment mockEnvironment;

 

@Before

public void setUp() throws Exception {

this.mockEnvironment = FacesMock.createMockEnvironment();

}

 

@After

public void tearDown() throws Exception {

// Necessary to clean up ThreadLocal variable in FacesContext.

mockEnvironment.release();

}

MockFacesEnvironment has a set of configuration methods ( having ‘with’ prefix ) that can be chained to describe requested features:

mockEnvironment.withServletRequest().withRenderKit();

Also, it contains the same set of create…Mock methods as FacesMock class. All mock objects created by environment can be resetted/replayed/verified by single call to environment instance.

Advanced usage, with Junit 4.x

Junit 4 introduced TestRunner feature that allows developer define its own extentions for test environment. Jsf-mock contains MockTestRunner class that simplifies working with mock objects:

  1. For fields in the test class and its superclasses, annotated by @Mock, @Strict, or @Stub annotations, it creates and injects ready to use mock object.
  2. It creates and initializes MockFacesEnvironment object, and injects it into field annotated with @Environment. Developer can describe requested environment features by annotation options. After a test, runner properly releases the environment.
  3. if field with type MockController exists in the test class, it injects controller instance there. That controller can be used to reset/replay/verify all mock objects created by the runner in the single method.

Mocking JSF view

Sometimes, it would be necessary to create not just mock component but fragment of JSF view. For example, to test UIData renderer, table component should contain columne and headers/footers. There is ViewBuilder class to do that:

ViewBuilder viewBuilder = ViewBuilder.createView().children(

ViewBuilder.component().id(“foo”),

ViewBuilder.component(UIInput.class).id(“input”)

).facets(

ViewBuilder.facet(“header”)

).setViewId(FOO_XML);

viewBuilder.replay();

Capturing ResponseWriter output

For custom renderers, it would be important to check generated html code. Faces-mocks allows developers to capture renderer output and analyse it with XPath-like criteria:

writer = new RecordingResponseWriter(“UTF-8″,”text/html”);

… call renderer to generate content

// verify output

assertEquals(“id1”,writer.find().element(“.*”).withAttribute(“id”).getAttribute(“id”));

 

MockFacesEnvironment creates capturing response writer if it requested by withResponseWriter() call, or Feature.RESPONSE_WRITER option in @Environment annotation.

Maven artifact for jsf-mock project available from Jboss Maven Repository, the source code repository on GitHub is git://github.com/alexsmirnov/jsf-test.git

October 16, 2009

About Benchmarking JSF libs

Filed under: Java server faces — Tags: , — alexsmirnov @ 4:58 pm

Mert Caliskan recently posted blog article about JSF libraries performance.

I’ve downloaded and run all these examples on my local machine ( That is Intel Core2 Duo 2.4 Mhz, 4GB RAM, Fedora Core Linux 11, Apache Tomcat 6.0.18 with jdk 1.6.0_18 ). Though I got a similar results for RichFaces demo and Trinidad, PrimeFaces performs AJAX requests from 23 up to 80 milliseconds, with median about 40 milliseconds. Firebug results seem adequate because they are close to request processing time shown by the eclipse TCP/IP monitor.

There is FireBug console’s scrinshot:

pprBecause even clean JSF page that contains only one form with one input field and submit button shows similar results that is about 20ms per request on the same environment, I do not see a much performance difference.

May 29, 2009

JSF component in JavaFX

Filed under: Java server faces — Tags: , , — alexsmirnov @ 3:03 pm

User-defined components in JavaFX.

Due to pure object-oriented JavaFX nature create custom component is pretty simple:

/* define the new component that contains input text field and
label for it: */
public class Input extends PanelGroup {
               public attribute value
               public attribute label:String
               override var children = [
               OutputLabel {
                    value:  bind label
                    id:"{id}:label"
                    for:"{id}:input"
               },
               InputText {
                  label:"Input"
                  value: bind input
                  id:"{id}:input"
                  valueChanged: Ajax {}
               }

That class may be used anywhere as any other component:

     .........
     Input {
        id: "baz"
        styleClass:"defaultInput"
        value: bind foo.bar
        label: "Input:"
     }
     ........

JavaFS binding and JSF AJAX

Filed under: Java server faces — Tags: , , — alexsmirnov @ 2:44 pm

Using JavaFX binding for JSF AJAX applications.

JSF 2.0 AJAX features going to the common event-driven GUI model. We could interpret Behavior as EventListener bounded to the event source on the both client and server sides. That hides and simplifies communication process for application developers, but they still have to manually define parts of page that affected by model updates and should be refreshed on the client in the same way as for old Ajax4jsf and RichFaces. But most of the modern GUI libraries, like Java Swing or JavaFX have also backward communication channels there bonded properties or models fires events on model changes which update the user interface transparently. For the JavaFX VDL implementation events from bonded properties may be used to calculate parts of page to update during AJAX request.

The manual approach, developer has to define “out1” component in the render list to update its value by AJAX. Component will be updated regardless was actual value changed or not:

        Output: <h:outputText id="out1" value="#{echo.str}"/>
        
        Input: <h:inputText id="in1" value="#{echo.str}">
            <f:ajax render="out1"/>
        </h:inputText>

Would be converted into:

               OutputText {
                  label:"Output:"
                  value:  bind echo.str
                  id:"out1"
               },
               InputText {
                  label:"Input"
                  value: echo.str
                  id:"in1"
                  valueChanged: Ajax {}
               }

Input text component fires AJAX request that updates “str” attribute on the “echo” object. That update marks outputText component to be rendered by the binding “value” attribute to the same “echo.str” value. If value was not changed, component will not be rendered.

May 28, 2009

JavaFX as JSF 2.0 VDL

Filed under: Java, Java server faces — Tags: , , — alexsmirnov @ 5:13 pm

JavaFX as JSF 2.0 view description language.

Preface

The JavaFX language has been developed for Rich Internet Applications. The project FAQ says:

“JavaFX is an expressive rich client platform for creating and delivering rich Internet experiences across all screens of your life. JavaFX 1.0 was released on December 4, 2008. As of February 1st, 2009, there had already been over 100,000 downloads of the tools and SDK. Today, JavaFX is available on over 50 million desktops.” In spite of that is really means applets or Java Web Start applications, I was a curious: Is that would be useful for web applications also ? Take look at the description from the OpenJFX compiler site:

What is JavaFX Script?

  1. automatic update (bind)

  2. list comprehensions (sequences)

  3. easy-to-use

  4. runs on JVM

  5. interacts smoothly with Java

  6. easy natural object graph creation (object literals)

  7. graphics centric

  8. single threaded

  9. focused on small to medium scale applications

  10. curly-brace language

Ok, take a look for these features :

  1. Bind. This is most attractive for me as capability for the JSF Ajax . Instead of manual definition for ‘dirty’ parts of page; as it implemented in the RichFaces, JSF 2.0 and some other projects, or analyzing differences in the rendered HTML code as the IceFaces project does, application can update these parts of page only where model values was changed. That would simplify application development on the same way as for Swing.

  2. Not sure how is that applicable for a web application.

  3. That is always necessary.

  4. I.e. in the same environment as JSF works.

  5. Good for JSF/JEE applications too.

  6. Very attractive for JSF application because of the tree-like view structure.

  7. Not web advantage.

  8. That doesn’t mean real single threaded implementation, I guess, because JavaFX GUI is based on Swing which uses threads, but hides thread manipulation from the application developer. It would be funny for web applications if we could put discrete requests processing behind developer’s concern.

  9. Really, that is a main target for JSF applications too.

  10. Not sure about that.

So, at least seven from ten JavaFX features are applicable to JSF Web. But additional advantages are pure object-oriented language, type safety …

Implementation idea

The one of the new JSF features is pluggable View Declaration Language. Chapter 7.6 of the Java Server Faces Specification says:”A View Declaration Language (VDL) is a syntax used to declare user interfaces comprised of instances of JSF UIComponents.”. The simplest way to integrate JavaFX with JSF is ViewDeclarationLanguage implementation that creates tree of JSF UIComponents from the JavaFX script. For example, if user requests page “ http://foo.com/bar/baz.fx” that implementation should execute “/bar/baz.fx” script from the web application content or load and execute pre-compiled “bar.baz” class. The script should create the tree of JSF UIComponents in the same way as any other JSF VDL does. Really, in the research prototype VDL implementation expects instance of the special “ JavaFXHandler” interface that creates UIComponent instances in the “ apply” method. That simplifies script content and allows to cache results between requests. Therefore, a simple JavaFX page would seem like this ( that is part of JSF 2.0 version of the guess number example page ):


import org.richfaces.javafx.*;

View {
  children:[
    Head {
      children:[
         Title {
              value: "GuessNumber 2.0&amp"
         },
         StyleSheet {
              value: "css/styles.css"
         }
      ]
    },
    Body {
         bgcolor:WHITE
       children:[
          Form {
              id: "helloForm&amp"
            children:[
               H2 {
                      value: "{userNumberBean.greeting}"
               },
               Image {
                  src:"{resource['images/wave.med.gif']}"
                  alt:"Hello!"
               }
               InputText {
                  label:"User Number",required:true
                  value: bind userNumberBean.userNumber
                  id:"userNo"
                  converter: NumberConverter {integerOnly:true}
                  validators: [
                                 GuessNumberValidator {
                                     min:userNumberBean.minimum
                                     max:userNumberBean.maximum
                                 }                                 

                              ]
               },
               CommandButton {
                  value: bind userNumberBean.userNumber
                  id:"submit"
                  action: Action {viewId:"response",redirect:true}
               }
          }
       ]
    }
  ]
}

Blog at WordPress.com.