Sunday, July 29, 2007

RENDER_RESPONSE Phase

The RENDER_RESPONSE phase is also responsible for saving the state of the component.
When I first read this, I thought, should not the method that invokes this save the state of the component? However, this will not allow us to implement saving the state on the client. Because when we save the state on the client, the state must be saved before the response stream is closed (actually before the response is totally rendered).

Be careful to not delete/modify any components in the saveState method.
If we change the state of components in the saveState method, we risk jeopardizing the integrity of the component.

Should all HTTP requests always be to the component that was last rendered?
I am not sure... need to think about it???

Wednesday, June 27, 2007

Reading the JSF spec

Application.getDefaultRenderKit() should (in my opinion) never return null. [pg 231]

Monday, June 25, 2007

JSF component id and clientId

JSF components have a clientId as well as an id.

The id of a component is the id that it chooses to give itself. This may be specified or can also be auto generated by the JSF framework.

The clientId is the id that is transmitted to the web client. For a component, it's clientId is the clientId of the closest parent that implements NamingContainer followed by the JSF seperator char followed by the clientId of this component.

A little code snippet that implements getClientId().



click on the image to get a better view

Monday, June 11, 2007

JSF phase events

The phaseId property of ActionEvent indicates which phase of the request processing lifecycle, this event should be processed.

The broadcast method is called after each phase (where events can be processed). By default it processes all events that have the same phaseId as that of the current phase.

Hence, if we want an event to be processed in a particular phase, we should set the phaseId of the event to the appropriate value, so that the broadcast() method will process it at the correct time.

Do we invoke broadcast manually, or is it invoked when we call super.whatever() in the appropriate phase?

JSF rendererType

The rendererType to use for rendering a JSF component really exists as a property in the component itself. We can call setRendererType(String rendererType); to set the rendererType.

When the component is being rendered, the appropriate renderer will be selected based on the rendererType. The runtime knows which renderer is mapped to a rendererType, because we map it in faces-config.xml. However, it can also be set in code, I believe.

When we use JSP tags to represent JSF components, then the tag handler class can also have a method getRendererType(); which returns the rendererType for that component. This is convenient because the JSF runtime will query the tag handler for the rendererType and will set it in the corresponding JSF component.

Tuesday, May 22, 2007

Some common component properties

Most components support a certain common set of properties. Among them are 'value', and 'binding'.

value - The component's current local value. Can be literal text or a value binding expression
binding - A value binding expression that associates this component to a backing bean property

If the 'value' property is a value binding expression, the value entered by the user in an input component will also be updated in the appropriate backing bean property, if the value passes all validations.

On first glance, the difference between 'value', and 'binding' is not very clear. I think (need to verify), 'value' (when used with a value binding expr) is used to transfer the user's input into a backing bean property, whereas 'binding' is used to associate a component with a backing bean property so that the backing bean can manipulate the component within code (Hence the type of the backing bean property must be the same as the type of the component).

Wednesday, May 16, 2007

JSF Request Processing Lifecycle

The JSF request processing lifecycle has 6 phases. Each events are generated after some of the phases. The listeners that handle these events can either skip the remaining phases and proceed strsight to the last phase "Render Response" or they can render the response themselves.

Tuesday, May 15, 2007

Validation in JSF

Validation in JSF can happen at three levels: in the component, in the backing bean, or in a custom validator.

Component Level - For simple 'required/not required' type of validations. Also the code is very component specific. It is within the component and cannot be reused by other components.

Backing Bean Level - This should be used for business requirement type of validations. The validations are specific to the particular business requirements within which the component is being used. These validations also cannot be reused by other components.

Validators - These are reusable validators for validating field sizes, value ranges, etc. We can reuse these validators accross components. JSF comes bundled with some default validators, and we can also create our own custom validators.

RenderKit

Renderers are organized into RenderKits. Each RenderKit focusses on a specific type of output. For example the default RenderKit in JSF produces output for HTML 4.x

If we want to change this to output for say WML, all we need to do is change the RenderKit.

Typically a RenderKit will have renderers for all base level UIComponents, and renderers for higher level components as required.

Monday, May 14, 2007

JSF component development - StateHolder Interface

JSF components are rendered upon client request. Clients may make several requests for multiple views. Since the components are statefull, we must save the state of the previous component before rendering another component.

The state of a component can be saved on the server as well as the client. When saved on the server, most likely it is saved in the client's session and nothing special needs to be done by the component developer to enable state saving and restoring. However, when the state is saved on the client, we must implement the methods saveState() and restoreState() defined in the StateHolder Interface.

The saveState() method should return a serializable object (usually Object[]) with all the properties of the component and it's superclass, as well as any state that needs to be saved from the renderers, converters, etc.

The restoreState() method accepts that same serialized object and restores the state of the component by getting property values from it.

Since we take the responsibility of saving and restoring state, these methods should be mirror images.

Note: It is important to test the component with STATE_SAVING_MATHOD=client and server.

JSF component development

JSF components typically subclass UIComponentBase or one of it's subclasses depending on the functionality they provide.

Some of the properties and methods they must implement are:

getClientId() - returns the clientId

This is the type attribute through which we refer to the component in faces-config.xml
public static final String COMPONENT_TYPE = "";

This is the component family attribute used to associate renderers with the component.

public static final String COMPONENT_FAMILY="";

The purpose of this property is to help renderers determine if they can handle a particular component. Now if we implement the rendering in encodeBegin(), then will this property still be used?


The encodeBegin() method contains all the logic for rendering the component.

public void encodeBegin(FacesContext context) throws IOException

The encodeBegin() method must render output only is the method isRendered() returns true. This attribute tells us if the component must be rendered (something like isVisible).

The encoding process starts with a call to encodeBegin(). After it complete's, encodechildren() is called if the method getRendersChildren() returns true. By default it returns false.

public void encodeChildren(FacesContext context) throws IOException

After this the encodeEnd() method is called. It is important to implement this method only if the component has children. Otherwise th entire rendering logic can be put in encodeBegin().

public void encodeEnd(FacesContext context) throws IOException

If you want to delegate rendering to a renderer, then call the renderer instead of implementing the display logic in the encodeXXX() methods. UIComponent base invokes the default renderer. This can be achieved in a custom component by not overriding encodeBegin(). Renderers are usually needed if we want to support output in multiple markup languages.

The decode methd is used to interpret client input.

public void decode(FacesContext context)

The decode method should proceed only if the component is not disabled. Check by calling the isDisabled() method.

UIComponentBase also has methods for event handling. However we can rely on the superclass' implementation if we are not introducing any new events. [TODO: Add the methods...]

Thursday, May 10, 2007

Inserting styles

We can insert styles with html elements in three ways.

Define the styles in an external stylesheet and associate the stylesheet with the html page like this. (This is the preffered way of defining stylesheets)

<head>
<link rel="stylesheet" type="text/css" href="images/adaptive-stylesheet.css" >
</head>

Define the style in the html page like this. (We would usually do this only if we want to associate a style with a particular web page)

<head>
<style type="text/css">
p
{
color: blue
}
</style>
</head>

Define it in the element like this. (This is the least preffered way, which is used only if we want to associate the style with a particular element)

<p style="margin-left: 20px; color: red">

Cascading Style Sheets - Basic intro

The primary motivation for CSS was to seperate presentation and content. It also promoted the DRY (don't repeat yourself) principle. Once we define styles for elements in the stylesheet, they do not need to be defined everywhere the element is used. We just need to ensure that the link to the stylesheet is maintained. If we need to change the style, we have to change only the definition in the stylesheet, instead of the elements. This is good, because for a change request we have to make fewer changes.

The CSS syntax is made up of 3 parts.
selector {property: value}
h1, h2, p
{
color: black;
font-family: "sans serif"
}
Note that the above example has multiple properties (that are seperated with a ; and one property has a value which comprises of multiple words), and it also has multiple (grouped) selectors.

The selector is usually the html element, the property is usually an attribute of the element, and the value is the value. So if I understand this correctly, CSS helps us factor the attributes of various html elements into style sheets, rather than defining them in the document with the element. Hmm, well this may not always be true, for example, the input element has an attribute called type, and I do not think we can or should define such attributes in a CSS. However, the concept is true for formatting related attributes of elements.

What if we want to support different styles for different elements at various places. We cannot rely only on selectors, because that will allow only one style. For such a requirement we must define a logical selector (also called a class) and map an actual selector to this logical selector. Using this reasoning, we can define multiple logical selectors or classes, and then map our actual html elements to these classes. The mapping is defined in the html file along with the definition of the element.

Classes can be created for an element, like this:
p.style1 {color: red}
p.style2 {color: blue}
p.style3 {font-family: "sans serif"}

<p class="style1 style3">Note that I have combined 2 styles</p>

or at a generic level

.style1 {color: blue}
.style2 {color: green}

<p class="style1 style2">What color will this text be displayed in?</p>

What will be dispalyed if there is a conflict as in the above case?

TIP: Do not start a class name with a number, because it will not work in Mozilla.
.1style {color: red}
will not work


We can also ensure that certain styles are associated only with elements that have certain attribute values.

input[type=text]
{
color: red
}

The above style can be used only for the text input html element.
<input type="text">

Styles can also be defined to work only with those elements that have a particular id.

/* This style def is for elements that have an id g120 */
#g120
{
color: green;
font-family: "sans serif"
}

will work only with those elements that have the id g120 (Note the comment at the top of the style definiton).

<p id="g120">
Some text
</p>

and if we want the style to work only with <p> elements that have an id of g120, then we use p#g120 instead of #g120.

TIP: Do not start the id name with a number, because it will not work with Mozilla. What this really means is that we should not define any id's in our html page that start with a number. If we do, then we will not be able to associate style definitions that work specifically with them.

Monday, May 7, 2007

Configuring a JSF application for logging with log4j

Log4j self initializes itself automatically in Tomcat, by locating a log4j.properties file from the context classpath to configure the log4j system.

I configured logging for a JSF application in which the log4j configuration file initially had the rootLogger set to a logging level of DEBUG. This resulted in a lot of debug statements being generated from the JSF classes. So I changed the root logger's log level to INFO and set the log level of our application classes to DEBUG.

log4j.rootLogger=INFO, A1
log4j.com.logicblox=DEBUG

However, the automatic configuration works only for Tomcat, I believe. I am not sure if it will work in other application servers as well. The log4j system can also be configured by setting the Java system property:

log4j.configuration

John Seely Brown on learning ad web 2.0

Here's a link to a summary of the talk by Steve Hargadon.

People are inveterate learners when put in social groups. The current educational system does not consider the importance of collaboration and social learning.

Study groups faciliate conversations, which is a very good way to internalize knowledge. We participate, therefore we are. We internalize our own understanding by participating (and doing).

Learning comes from playing with ideas and engaging in productice inquiry.

Google helps us try things that we do not completely understand. Web 2.0 facilitates and encourages participation.

JSB has a very interesting thought on developing the edge and letting the edge influence the core... very powerful concept.

Students need help with next steps, and the faculty must help them with taking the next step and discovering and constructing knowledge themselves, and solving their doubts as they go along.

Learning by enculturation is very important and useful. Students must learn to be and not just learn about something. So, specifically for software, students must learn to be software developers, rather than learn about software development.

Thursday, May 3, 2007

Making a simple JSF application

Here's how we build a simple JSF application:

  1. Configure web.xml for FacesServlvet
  2. Create faces-context.xml (This is the file from where FacesServlet reads navigation rules, details of managed beans and other JSF specific configuration details)
  3. Create a controller or controllers for the application. Here is where JSF differs from Struts. Struts had a front controller, the ActioServlet which delegated requests to Action classes. JSF does not have the notion of a front controller. A JSF application uses an event model. The UI is tied to the backend with events. Controller classes (also known as backing beans in JSF) accept these events and also hold properties that accept user supplied values from a form. These properties will also be used to display data on pages. For example if we have a simple application that allows employees to put in a leave request, a backing bean will have properties that will be populated with the request that the user enters on the form. The same backing bean may also be responsible for displaying the leave status to the user. Essentially we will have one backing bean class for a related set of UI views. The view pages for adding, editing, viewing, and deleting "leave requests" will be mnaged by the same backing bean class. A JSF application can have many backing beans, thus resulting in many controllers. Even though we can code business logic in these backing beans, we should desist from doing so. The business logic must in other application classes which are invoked from the backing bean. This way the backing bean acts as a glue between the view and the model (which is what a controller should be doing anyways).
  4. Create the view (JSP) files.
    1. All the JSF tags should be put within an f:view tag. Components placed within this tag are managed by the JSF system. If we not use f:view, then the JSF system will remain oblivious of the components.
    2. Fields in a JSF form can be associated with beacking bean properties using JSF - EL. For example #{BeanName.PropertyName}. JSF-EL is similar to JSTL-EL, however, it directly associates a field (within which it is used) with a backing bean property (or a properties property). These properties are used to hold values submitted by users as well as hold values that will be displayed to the user on a form.
    3. We can associate commandButtons to methods in the backing beans, using JSF-EL. I believe we can associate them with events, in which case appropriate event handlers will be invoked[verify this].
    4. The JSF system can also run simple validations on the form fields automatically. Things like required fields, or fields that represent numbers can be validated automatically. More complex validations can be defined in custom validators.

JSF MVC Implementation

Still reading Rick Hightower's article on JSF.


This image has been referenced from Rick Hightower's article.

The JSP page (essentially the tags) is bound to a server side view_root that maintains the state of the UI components. The view root is a composite just like Swing components. Any changes a user makes in their browser's view get reflected in the state of the view root. The view is also linked to properties (or nested properties) of a backing bean. It is recommended that we do not put business logic in the backing bean, they are meant to mediate between the view and the model. At first I thought, why do we need these backing beans? The properties can be set in the View Root objects, and they can handle the events as well, but I think there is a good reason for them. The View Root components are written by the component provider. We do not have control on them. However our application needs to have event handlers, and maybe transfer objects. These are bound to the view through the backing beans. So the backing beans act as the glue between the view and the model. Is there a cleaner way to do this? Maybe not.

How do the values from the front end actually get set in the backing bean? I think the components in the view root will invoke the setters when they are updated. Then exactly what role does the faces Servlet play?

Update:
The FacesServlet handles the JSF lifesycle.

Learning Java Server Faces

Resources:
  • Marty Hall has a good JSF tutorial here.
  • Rick Hightower has a very good 4 part series on JSF here.

Reading the first part of Rick's tutorial.

JSF provides component tags for every input field available in standard HTML. [Ref]

Well I guess, JSTL also did this.

JSF components are stateful. The statefulness of the components is provided through the JSF framework. JSF uses components to produce HTML responses.
Were JSP tags also stateful? No. Assuming we are using Struts, let's say we change the state of a form, the state change is transmitted to the backend as an HTTP request. This causes some bean properties to be set. The original form can now be displayed again, using the form bean as a a source for the state of the form. This form will reflect the new change as long as form bean is accessible to the JSP tag. So the state is saved in the form bean, and the fact that the form bean is made accessible to the Tag helps us manage the state of the UI.
In JSF, I believe the state of the view is saved in a corresponding server side component [need to check this].

JSF's component set includes an event publishing model
This is a big change from Struts and the earlier frameworks. However, I remember reading somewhere, that JSF apps do not support plain old GET requests (links). Could this be because of the event based approach? [need to check this]

The JSF framework also has:
  • A lightweight IoC container
  • Server side validation
  • Data conversion

JSF and JSP:


JSF uses JSP as the UI rendering technology (not quite, but read along...)

Each JSP page contains JSF components that represent the GUI functionality. You use JSF custom tag libraries inside JSP pages to render the UI components, to register event handlers, to associate components with validators, to associate components with data converters, and more

I am not sure about the rendering part. From what I understand the JSP pages are used because they support tags. JSF tags create a representation of the component on the server. This representation saves the state of the component, and certain server side classes are responsible for rendering the component as well. So the JSP seems to be used simply because it supports tags. That said, it is possible to use other technologies for the UI, such as Facelets and xml namespaces (instead of tags). One implication of this, is that if a JSP page is changed and dropped into the server, the server will not reflect the changes if the server side component representation has already been created. This is because JSP is not used for rendedring, but simply to set up a server side component tree to represent every component coded in the view with JSF tags. Rick does go on to breifly explain this.

JSF and MVC:
The main complaint against Struts is that it can feel more procedural than object-oriented
Hmmm this may be true, but it was to accomodate the (stateless) HTTP protocol. True JSF does seem more OO because it abstracts the web behind a component based model. But it still has to be seen how well the creases are ironed out. It is still premature to say that JSF's component based model is superior (because it is less procedural... use the methodology that is best suited for the job... and it is possible that the procedural methodology might just be better suited to accomodate a stateless protocol... ).

JSF offers a richer MVC environment:

That does seem to be true. User interactions on the UI are transmitted to the backend as events, whereas in Struts they are request parameters. Are events better than request parameters? They surely are more OO. Maybe they are better, but there could be a downside. Many applications need support for link based entry points. For example when someone tries to connect to a LinkedIn member, the application sends the member links to approve the request ot reject the request. This works because we have not abstracted the underlying protocol. Would this work just as well in a JSF application? I do not think so, because a JSF backend needs events, and events cannot be generated when a user clicks on a link from their mail client. I am sure there is a workaround though.

JSF's fine-tuned event model allows your applications to be less tied to HTTP details and simplifies your development effort.
I am not sure. Maybe writing simple CRUD applications will become much simpler, but writing complex applications might become significantly more difficult.

SF also improves somewhat on the traditional Model 2 architecture by making it easier to move presentation and business logic out of your controller
I don't believe either presentation or business logic was in the controller in traditional model 2 apps. Though people did put business logic in the view (JSP pages), and I agree that JSF makes that more difficult (because the view is rendered from a server side component model, so it is difficult to mix html with tags on the view pages in the JSP's). But on the other hand, the backing bean can hold application logic, a reresentation of the component's state (through value bindings), have event handlers, and also is the controller. That's not very modularized.


Unlike a true MVC architecture it is unlikely that the JSF model tier is issuing many events that have to be resolved in more than one viewport;