July 6th, 2011
5:27 pm
Facelets – using <f:subview> to create a naming container

Posted under JSF
Tags , , ,

<f:subview> creates a naming container and so may be used to avoid ID collisions on a facelets page. It says in CoreJSF, 3rd edition, that this is not needed for facelets, but as it turns out, I have found a significant use for this.

One of my custom tags is a complex multi table tree browser component, which has lots of optionally included/defined markup. It therefore needs to be a custom tag rather than a composite component, as the latter would not give the required flexibility.

The issue I hit with this is that I use multiple variants of this tree browser on the same page, to browser different tree structured data within my application. The trees are all polymorphic, and indeed share and subclass the same base JSF controller class, as well as re-using the same base custom tag. As there is more than one on a page, I have potential ID collisions, and so to avoid this, using <f:subview> to define a naming container in the custom tag is ideal in this case.

This is helped by the fact that in JSF 2 you can actually pass an ID to a custom tag and define it in the tag in <f:subview> using an EL expression. Whilst this is normally unorthodox and not encouraged, in this case it makes perfect sense – the value does not come from a bean, but is a constant string passed via the attribute.

No Comments »

July 6th, 2011
5:16 pm
Facelets–using a custom tag interchangeably instead of a Decorator

Posted under JSF
Tags , , ,

Update 26/7/2011

Some more points that were omitted or incorrect in the first posting:-

  • A handy feature with templates/custom tags is that you can render children of the template/tag at the call site simply by using a <ui:insert> without a name. You therefore do not need to use a <ui:define> tag in this case, and all children which are not contained in other <ui:define> or <ui:param> tags will be rendered as part of this default <ui:insert>
  • The statement below that it is not possibly to insert a number of different markup variants in a composite component is incorrect. A composite component can have a number of named facets just like a ‘real’ JSF component, and these allow markup to be inserted in the same way as <ui:insert>/<ui:define> does for a template or custom tag.

Original Post

I had a complex decorator which was used for tree browsing. It had a number of ui:inserts for custom markup, plus also a large number of <ui:params> to define EL parameters used within it.

This all worked fine, and even looked quite tidy as all the <ui:params> were listed one per line below each other. However, it was all rather verbose compared to using a custom tag where you would use attributes instead to pass the EL parameters.

It turns out that you can convert a decorator to be a custom tag with no effort as they operate similarly. You merely need to register the xhtml file in a taglib as with any custom tag, and you can then call exactly the same code as a custom tag instead of a decorator.

The neat tricks here are that:-

  • <ui:params> become attributes which are less verbose, but the tag itself does not know any difference and needs no changes.
  • <ui:insert>/<ui:define> work perfectly with a custom tag exactly as they do with a decorator.

 

Another nice point on this is you can develop custom tags that include pseudo ‘child markup’ in similar fashion to composite components, by using the <ui:define>s. Providing you do not need the other features of composite components such as retargeting, Ajax etc., custom tags can be very useful where you have a need to insert a number of different markup variants for different flavours of the tag, as you cannot do this so flexibly with a composite component.

The technique of using <ui:inserts> in a custom tag is hinted at somewhat obliquely in Core Javaserver Faces, 3rd Edition, on P196 in the listing of the planet custom tag, which contains a <ui:insert> called content1.

No Comments »

July 6th, 2011
5:01 pm
Facelets–using <ui:param> for temporary in-page variables

Posted under JSF
Tags , , ,

I have sometimes had a need to define temporary variables for use on a facelets page.

When I tried using <c:set> for this it failed to work when used within a decorator.

However, <ui:param> fulfills the need admirably. Whilst it is normally used to pass EL parameters to a template from its client, it can also be used to hold data for use elsewhere in the same decorator for example. Bear in mind that there are scoping issues which as yet I have not fully bottomed out – the variable is probably visible anywhere else in other templates/xhtml files on the same page and so care is needed with naming.

A good example of this was when I wanted to define a couple of size parameters (which could not be done with CSS) at the top of a decorator/custom tag where they were clearly visible, and then re-use them multiple times further down in tag attribtutes to called tags.

No Comments »

March 22nd, 2011
8:42 pm
Facelets executes EL expressions in HTML comments by default

Posted under JSF
Tags , , , ,

This one caught me out when I was relying on <!– –> to comment out debug code when developing a facelets page. I found that methods in my Java code were being called seemingly from nowhere!

According to the specification, Facelets should honour (i.e. skip) comments by default, but in my case it did not appear to do so.

This can be enforced by adding the following context parameter to web.xml. Once done, you can safely rely on the use of commenting out when debugging. You can also use ui:remove to tell facelets to ignore sections of markup. This post here gives the details.

Note that the linked post from the above post uses the deprecated parameter name facelets.SKIP_COMMENTS. The correct parameter is as below, as you will be warned about in your server log file if you use the deprecated one!

 

<context-param>
  <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
  <param-value>true</param-value>
</context-param> 

No Comments »

March 22nd, 2011
8:35 pm
JSF rendered attribute calls the getter multiple times

Posted under JSF
Tags , , ,

Initially when I saw this I thought it was a strange bug – the getter for the value expression referenced in a rendered attribute on a JSF2.0 facelets page was called 7 (yes seven) times when I would have expected one call only!

There are logical and historical reasons for this which are detailed in this post here.

The moral of the tale would seem to be that you should not make any assumptions about how often getters for value expressions are called, nor when exactly they are called. If you are doing for example database access you should never do this in a getter, but should use system events (JSF2) or Phase events (JSF1) for the database access as these give fully predictable behaviour as to when the calls happen and give you full control.

No Comments »

March 8th, 2011
6:47 pm
JSF – changing input component values in a value change listener

Posted under JSF
Tags , , , , ,

My requirement on this one was to have some linked logic between select checkboxes on table rows and a ‘select all’ checkbox in the column header. Checking ‘select all’ should check all the row boxes. Then, unchecking one or more of the row boxes should uncheck ‘select all’ as the rows are no longer all checked.

Initially I had decided to get a whole test form working without Ajax, then apply the desired Ajax to all of it consistently. I had previously hit event timing issues due to mixing Ajax and HTTP submits on the same form. This gave rise to strange behaviour such as old queued events seeming to fire from nowhere, and events containing null arguments in method expressions. The basic wisdom on this is don’t mix Ajax and traditional HTTP submits on the same form – bad things will happen! I therefore decided to get the code logic working first with plain submits, by adding “onclick=’submit();’” to the checkboxes to force submits temporarily. The idea behind this was to avoid getting a mix of problems due to Ajax and problems due to other coding bugs, by eliminating the other coding bugs first.

The approach when doing this kind of thing is typically to set the components to immediate=”true” and call FacesContext.getCurrentInstance().renderResponse(); at the end of the value change listener to force an immediate rendering.

The problem I hit however, was that although I was correctly setting bean values for other checkboxes from the listener, the values were not being read again prior to renderResponse(),so the new values were not being displayed on the page. This is in fact standard behaviour. The way to update the values being rendered is to call setValue()  on the actual UIInput Component as well as writing the backing bean. To do this you need to get at the component instance, and the best way to achieve this is to use the binding attribute in the JSF page. For example, the following code fragments could be used in the JSF page and the managed bean:-

 

JSF Page

<h:selectBooleanCheckbox value=”#{mainBean.selectedB}”
                         valueChangeListener=”#{mainBean.selectedListenerB}”
                         binding=”#{mainBean.selectBoxBBinding}”
                         id=”chkSelectB” immediate=”true” onclick=”submit();”>
</h:selectBooleanCheckbox>

 

Managed Bean

private UIInput selectBoxBBinding;

public UIInput getSelectBoxBBinding() {
    return selectBoxBBinding;
}
public void setSelectBoxBBinding(UIInput selectBoxBBinding) {
    this.selectBoxBBinding = selectBoxBBinding;
}

 

Value Change Listener

public void selectedListenerA(ValueChangeEvent event) {
    boolean newValue = (Boolean)event.getNewValue();
    setSelectedA(newValue);

   //SelectedB is set to the same value as selectedA
    setSelectedB(newValue);
    selectBoxBBinding.setValue(newValue);
    FacesContext.getCurrentInstance().renderResponse();
}

This causes the new value to be displayed in the updated checkbox.  Binding to a component allows access to a number of other properties and methods as well, so gives a lot of flexibility. However, in most normal cases straightforward value binding is enough.

 

Using Ajax to achieve the same result

Ironically, if I had used Ajax on this issue, I would not have hit the problem. When Ajax is used, setting the new values in the managed bean is enough to allow them to be displayed directly on screen. The following JSF fragment shows how to use Ajax in check box SelectA in order to directly update check box SelectB without using a form submit. execute=@this causes the server side processing for SelectA to be performed (@this means the current component and is the default). render=”chkSelectB” causes the rendering to be peformed for SelectB, which displays the new value. Both execute and render take a space delimited list of client Ids, or special keywords such as @this, @form, @all, @non etc. The Ids can be prefixed with “:” to force Id scanning from the root where there are naming container issues etc. I am not covering any of this here. 

<h:outputText value=”Select Box A”/>
    <h:selectBooleanCheckbox value=”#{mainBean.selectedA}”
                             valueChangeListener=”#{mainBean.selectedListenerA}”
                             id=”chkSelectA”>
    <f:ajax execute=”@this” render=”chkSelectB”/>
    </h:selectBooleanCheckbox>
<br/><br/>
<h:outputText value=”Select Box B”/>
    <h:selectBooleanCheckbox value=”#{mainBean.selectedB}”
                             valueChangeListener=”#{mainBean.selectedListenerB}”
                             binding=”#{mainBean.selectBoxBBinding}”
                             id=”chkSelectB”>
    </h:selectBooleanCheckbox>

No Comments »

March 6th, 2011
7:47 pm
Adding jsf view state to domain objects–part II

Posted under JSF
Tags , , , , , , ,

My original post on this is here.  It links to an Icefaces post which discusses using a decorator to do this. The fundamental problem is that you often want view state such as (but certainly not limited to) a selected flag on objects e.g. in tables. However, you do not want to pollute domain classes with view state, so it would not be desirable to add a selected flag to your domain objects as this blurs the layers (especially as you may have multiple different UI layers on the same domain, such as JSF browser clients, smart phone web clients, web services etc. all with different needs). Other examples of view state might be style classes to be used on different table rows in response to use actions etc.

Since my original post I have looked at other ways of achieving this, and summarize various approaches below which could be used to add view state to rows of a table.

In each case, assume initially we have a JSF table of the form <h:dataTable var=”row” value=”#{mainBean.rows}”>, where each row object has the properties firstName and surname, plus the need for a selected boolean flag to be maintained separately from the row.

 

1/ Using a row decorator

My original post discusses using a decorator to add the extra state, as per the icefaces post. This involves wrapping every row, but is transparent to the code. The downside of the decorator is that each domain class requiring the extra state needs its own decorator even though each case might require the same extra state. This potentially means a lot of extra classes just to add a selected flag.

 

2/ Using a generic row wrapper class composed with the row

A second alternative which is similar to the decorator would be just to use a wrapper class which holds the extra state plus the domain class instance, and explicitly make the calls to the domain class methods and properties. Thus, the following code might be used to read our table row properties and the selected flag (all the examples use direct instantiation for simplicity) :-

//wrap a row. rowWrappers is the list containing the wrapped rows
rowWrappers.add(new RowWrapper<Row>(row));

// read properties on a facelets page – note that the table now contains wrapped rows:-

<h:dataTable var=”rowWrapper” value=”#{mainBean.rowWrappers}”>,
<h:outputText value=”#{rowWrapper.row.firstName}”>
<h:outputText value=”#{rowWrapper.row.surname}”>

//read the selected flag on a facelets page
<h:outputText styleClass=”#{rowWrapper.selected ? ‘style1’ : ‘style2’}” value=”…”/>

The pros and cons of this approach are:-

  • All the rows need to be wrapped as before.
  • All the ‘delegation’ to access row properties is explicit in all the expressions.
  • The upside however is that to add a given set of view state properties, only a single class is needed and this can wrap any number of domain classes generically, which can be a significant advantage.

 

3/ Using a Map to hold the additional row state objects

A third approach makes use of the fact that JSF EL value expressions can transparently read Map entries just like properties. Therefore where object m is a map or object that implements java.util.Map, the equivalent expressions m.property1 and m[‘property1’] when reading a value (i.e. on the right hand side of an expression, or rvalue mode) both result in

m.get(‘property1’)

being executed. When writing a value (i.e. on the left hand side of an expression, or in lvalue mode), as in m.property1 = rhsexpression, the statement

m.put(‘property1’, rhsexpression)

will be executed, assigning rhsexpression as the value of property1.

This technique allows us to use the row object itself as a key to the map containing the additional row state:-

//add row state object to map
rowFlagsMap.add(row, new RowFlags());

// read properties on a facelets page :-

<h:dataTable var=”row” value=”#{mainBean.rows}”>,
<h:outputText value=”#{row.firstName}”>
<h:outputText value=”#{row.surname}”>

//read the selected flag on a facelets page using the current row as a map key
<h:outputText styleClass=”#{mainBean.rowFlagsMap[row].selected ? ‘style1’ : ‘style2’}” value=”…”/>

Note that the nested expression evaluation works correctly with the map as the ‘man in the middle’ and that the expression mainBean.rowFlagsMap[row].selected could be used equally to fetch any other property from the rowflags object instead of the selected  property. The expression works as we would expect in both lvalue and rvalue modes, such that if for example the above property value was written to as true from the jsf page (e.g. from the value property of an updated check box we had just ticked), the expression would execute correctly as

mainBean.rowFlagsMap.get(row).selected=true;

The pros and cons of this approach are:-

  • We need an extra map access to get the row state, but for typical table sizes a hashmap would give very efficient access and should not be an issue.
  • We need to use the more complex expression mainBean.rowFlagsMap[row].selected  to fetch the additional row state. However, the plus is that we do not have to wrap each row in the code, and assuming that there are more table properties than additional state, we do not have to explicitly use a nested expression for them as we would in the previous approach.
  • When using this approach, it must be born in mind that you are using an object as a Map key. This should not be an issue, but if you override the hashCode function such that the hash value could change during the lifetime of a row object (for example if a row property changed) you would need to take account of this. Note also that rows in the map will only correctly match the exact same objects. If you refetch the same domain objects again from your entity manager you cannot expect them to match any existing objects in the map. Again, this should not normally be an issue as you would expect to rebuild the map from scratch when refetching domain objects from persistent storage.

 

4/ Using a Smart Map Interface to implement a selected property by storing the selected row objects

This approach is similar to the previous one, in that it uses a Map interface to hold a selected flag. The difference is that we implement our own class implementing  the Map interface and hide a map behind it. Our Map class simply stores each selected row in a ‘real’ map. When the caller reads the selected flag for a row by calling map.get on our map class, we perform a contains call on the ‘real’ map and return true if the row is present, or false if it is not. Similarly, when asked to set selected =true for a row, we just add the row to the ‘real’ map. When asked to set selected=false for a row, we remove it from the ‘real’ map. The pros and cons of this approach are:-

  • We only need to store the selected rows in the map, so we are storing less map entries.
  • The expressions to check the selected flag are a bit simpler, requiring something of the form mainBean.selectedMap[row]
  • Conversely, we need to implement the smart map – this needs quite a number of dummy methods when implementing the Map interface. When implementing this, I typically create an abstract base class which dummies out most of the java.util.Map methods which I don’t need, and then extend this for a desired implementation. This project in the repository makes use of this technique – see the classes uk.co.salientsoft.view.JSFValueMap and uk.co.salientsoft.view.SelectedMap.
  • The other downside is that this method only allows storage of a simple boolean based on the presence or absence of a row. If we need more additional row state, we need to look to one of the other methods.
  • As with the previous method, we are using a row object itself as a map key, so the same caveats apply as in the previous case.

 

Conclusion

As is often the case, there is no clear winner – you take your pick depending on individual requirements and the various pros and cons. Overall, my current favourite in general is to use the additional Map. It is simple to implement (you don’t need to dummy a load of Map methods like you do with the smart Map). Unlike the smart Map, you can add any number of additional properties to a row. The domain row properties can be accessed exactly as before, and you don’t need to wrap every row (however you do need to create the row state object and add it to the map for every row). Whilst the access to the additional state requires a slightly more complex expression, this is likely to be needed less often than expressions to read the domain properties.

No Comments »

March 4th, 2011
5:48 pm
Breadcrumb Composite Component using ui:repeat

Posted under JSF
Tags , , , , , , ,

Update 16/1/2012

A bug was found in the crumb styling. max-width was correctly set on the crumbs to truncate them, but when white space is present in a crumb, the default is to wrap at the max-width. This causes the breadcrumb to increase in height and add a second line. The fix was to turn off the wrapping by setting “white-space:nowrap” in the css for the crumb anchor tags (see Mantis issue 99 for details) :-

.ss-breadcrumb ul li,
.ss-breadcrumb ul li a {
    overflow:hidden!important;
    display:inline-block;
    white-space:nowrap;
    text-decoration: none;
}

 

Original Post

This follows on from my previous posts on the Primefaces breadcrumb here  and here.

I found a couple of further important issues I hit when using the standard breadcrumb:-

  1. In order to add and remove crumbs dynamically, it uses the Primefaces MenuModel. Methods of the MenuItem class are used to add actions and listeners.
  2. The mechanism seems somewhat cumbersome. In particular, it does not appear to be easy to pass a particular target object as an argument to an action or listener method, as the binding appears to be created as a string. Ideally what I would want is for the breadcrumb entries to be created by iterating a list using a var attribute like a table, and then to pass the var object containing the current crumb in the list as an argument in a method call to an action when that crumb was clicked.
  3. The only way I could see to do it involved passing an identifier for an object (such as the primary key for an entity). Whilst I certainly did not bottom it out completely, the mechanism seemed somewhat complex to use and lacking in flexibility.

Adding these issues to the ones already highlighted in the other posts (in particular the slowness of the jQuery operations when initially collapsing a breadcrumb in preview mode), I decided to take the step of rolling my own custom breadcrumb. The following approach was taken:-

  1. I decided to use a composite component rather than create a full blown custom component in code, as this looked more straightforward, and I had experience of composite component creation.
  2. The key factor which made this possible was that I could use ui:repeat to build the breadcrumbs dynamically from a list.
  3. Conditionally rendered xhtml tags could be handled using ui:fragment within the ui:repeat loop. This allowed the use of the rendered attribute on ui:fragment to optionally render sections even when standard non-jsf html tags such as <li> were used. For example, the root crumb of the component is rendered differently to the others, using an icon only. Also, full width crumbs are rendered differently to truncated crumbs (when truncating the component to fit a target width)

The following are the key features and design points for the breadcrumb:-

  1. The component is designed specifically for dynamic use, being driven from a list much like a table. It is not possible to build it statically on the facelets page (static use is covered by the standard control so this was specifically a non-goal/non-requirement).
  2. It is rendered entirely statically, so there is no (potentially slow) javascript/jQuery stuff going on at render time or during use.
  3. Compression to fit a target width is done by passing the desired target width in to the control. This is then used to set max-width css properties on the crumbs. This allows the crumbs to take the width they need and to only be truncated when they hit the max value. The max value is calculated on the server at render time by dividing the max target width by the number of crumbs to be rendered (allowing for the root crumb as a special case).
  4. The full text for a crumb can be viewed at any time by hovering over the crumb – it is displayed using the HTML title attribute. This is one annoyance with the standard Primefaces control – it does not allow use of the title attribute. Using the title  attribute allows the control to be static on the page for speed but still allows truncated crumbs to be easily read.
  5. The component supports the concept of stale crumbs. The idea is that when moving back up the crumb path (leftwards, or navigating up a tree path), the crumbs to the right which were previously visited are not immediately removed. They are highlighted differently as non bold and italic to make them less important compared to the ‘fresh’ crumbs on the path. In addition, the current crumb is underlined in order to make it completely clear where the current position is. Without stale crumbs present, this would normally be the rightmost crumb, but this will now no longer be the case if stale crumbs are present.
  6. Stale crumbs are only removed if the user navigates down a different tree path which invalidates them, in which case they disappear. Provided the user remains on the same tree path, the crumbs will be left in place.
  7. The stale crumbs may be clicked for navigation just like the fresh ones, to allow the user to revisit old ‘stale’ locations. When a stale crumb is revisited, it changes back to a fresh crumb again (as do all other stale crumbs to its left) and it becomes the current crumb – it is therefore rendered in bold, non-italic, and is underlined. The crumbs to the right of it if any still remain stale as they were before.
  8. To assist navigation up a tree structured hierarchy, it is common to include an ‘up’ button somewhere. This is taken a step further by including both up (= left pointing) and down (=right pointing)buttons on the left hand side of the breadcrumb component. When combined with stale crumb support, this feature allows easy navigation both up and down a given tree path. The right button is only enabled when stale crumbs are present, and clicking it moves down the stale crumb list just as if the next stale crumb was clicked. Navigating to the root of the tree (leftmost crumb) disables the left button.
  9. The component is styled in a similar way to the standard Primefaces component, and uses the same CSS classes for the styling.
  10. Styling may be modified, and features such as up/down support turned on or off.
  11. The component is styled using an inner div which holds the component itself – this can be floating if desired in which case it resizes the width to hold its contents. The inner div is contained in an outer div which is typically fixed in size to suit the page, allowing the inner div to scale up to that size. The width used for crumb truncation calculation is passed separately into the control – this will normally be slightly less than the max width set for the divs.
  12. The component is backed by a controller backing bean, BreadcrumbCtrl/BreadcrumbCtrlImpl, which may be subclassed to allow further customisation. The crumbs are passed into the bean as a simple generic list, and a property name used for the crumb text display is passed as a string attribute to the composite component. The controller fields action and listener events from the component, and passes them on using a BreadcrumbEvent interface – an object implementing this interface is passed into the controller bean at init time. When the user clicks on a crumb, the actual crumb in the list plus its list index are simply passed to its action method. When multiple components are used on a page, each will have their own controller object. These will typically be injected into the page backing bean e.g. by CDI as dependent beans. When the action and listener events are called, the actual controller object is also passed. This would allow for example the page backing bean to implement BreadcrumbEvent and manage actions for a number of dependent breadcrumb controllers, using the passed controller object to determine which one was clicked.

The following are some of the key technical issues which arose during development of the component:-

  • ui:repeat is used for iterative xhtml generation of the crumbs. This uses a var attribute like a table to represent the current object (crumb) in the list. It also supports a varstatus attribute which allows access to various loop properties within the loop, such as the current loop index, first and last boolean properties and others. The index property in particular is used to determine styling for the current crumb and stale crumbs etc.
  • In addition, the varstatus object (com.sun.faces.facelets.tag.jstl.core.IterationStatus) can be accessed from the controller bean using code similar to the following, where varStatusKey is the name given in the varstatus attribute to ui:repeat:-

Map<String, Object> requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
IterationStatus varStatus = IterationStatus) requestMap.get(varStatusKey);

  • It is important to note that whilst it is tempting to cache the varstatus object in the controller bean, this does not work – a new object must be obtained each time using the above code.
  • ui:fragment can be used directly in the ui:repeat loop within the composite component implementation – it is not immediately obvious from the documentation that this is the case.
  • When declaring the attributes for the composite component using <composite:attribute>, note that the type attribute allows specification of a particular object type, the required attribute makes an attribute mandatory, and the default attribute sets a default.

The source code and a usage example of the breadcrumb control may be found in the repository here.

No Comments »

February 11th, 2011
5:49 pm
Further h:outputStylesheet issues

Posted under JSF
Tags , , , , , , ,

I needed to load a custom style sheet for a composite component.

Primefaces has problems loading theme images correctly when using h:outputStylesheet as per here, but using a raw link tag was no good as I wanted to develop a custom component which loaded its own styles, i.e. it had no <head> section.

This post here indicates that if you don’t use the library attribute you can get h:outputStylesheet to work even with Primefaces themes.

In my case, I was not loading themes/images etc. so this was not an issue, but I still used the following directive and avoided use of the library attribute for simplicity:-

<h:outputStylesheet name=”uk.co.salientsoft/util/SSBreadcrumb.css”/>

This version worked. My initial attempts (which failed with a resource loading error) were as follows :-

<h:outputStylesheet name=”resources/uk.co.salientsoft/util/SSBreadcrumb.css”/>

<h:outputStylesheet name=”#{request.contextPath}/resources/uk.co.salientsoft/util/SSBreadcrumb.css”/>

In other words, with a css file stored in Eclipse under WebContent/resources/uk.co.salientsoft/util/SSBreadcrumb.css,  the above working example was correct, i.e. to load correctly, omit the context root and the resources level and use a relative reference without the preceding slash.

I did try to debug this by visiting the logger settings in Glassfish admin, then under the Log Levels tab, setting everything with JSF in it to finest! This did display an error when trying to load the resource:-

[#|2011-02-11T17:21:13.331+0000|FINE|glassfish3.0.1|javax.enterprise.resource.webcontainer.jsf.application|_ThreadID=31;_ThreadName=Thread-1;
ClassName=com.sun.faces.application.resource.ResourceHandlerImpl;MethodName=logMissingResource;
|JSF1064: Unable to find or serve resource, /SSBreadcrumb/resources/uk.co.salientsoft/util/SSBreadcrumb.css.|#]

However the error was not particularly informative as it just spat back to me the path I gave it to load. It would have been nice for it to tell me how it was mapping the path as then I could have seen the problem more easily.

Note however that using this page in Glassfish is a very convenient way to turn on logging in Glassfish, as it lists the common logger paths for you and gives a combo to select the level for each. You don’t have to go googling for the logger paths and edit a log properties file yourself. Note also that when you do this you must restart Glassfish for the log level changes to actually take effect.

No Comments »

November 16th, 2010
2:59 pm
JSF 2.0 Composite Components

Posted under JSF
Tags , , , , , ,

This post highlights a few lessons learned whilst experimenting with a simple composite component, in this case an experimental  Primefaces theme switcher component. The component does the following:-

  • Automatically iterates the themes directory on the server to build a list of available themes which are presented for the user to select
  • Generates a simple theme control panel with a border, consisting of a drop down combo listing the themes, with previous theme/next theme buttons to the right.
  • Also allows theme switching via ctrl/shift/left arrow and ctrl/shift/right arrow, to give a quick way of cycling through the themes when choosing one.
  • The component is used on the JSF page in two modes – the first usage is with outputStyle=”true”, themeBase and defaultTheme attributes. It is placed in the <head> section, and it defines the base path for all the theme directories, and the default starting theme (which may be programmatically overriden by setting the theme property in its backing bean, themeSwitcherBean). This mode also outputs the link directive to link the current theme stylesheet to the page. It does not result in the display of the control panel.
  • The second mode is used inside a <form> on the page, and results in the theme switcher panel being displayed.
  • A theme switch results in a form submission, so this must be acceptable to the form logic. If not, i.e. if the form is dirty, the theme switcher must be disabled. This would be done by passing a disable flag attribute to the component, which maps to a disable property of the backing bean, which results in enabling/disabling the controls. At present, a disable feature is not supported.

 

The following salient points were picked up along the way:-

  • The component does not have to be placed in a form. The examples in the Core JavaServer Faces book seemed to always show the client page with the control placed on a form, and also with <form></form> tags present in the custom component implementation. There is absolutely no requirement for the custom component implementation definition to be in its own form.
  • With JSF 2.0, it is easy to pass a value e.g. from a composite component attribute in a call, direct to a backing bean property, as JSF 2.0 now supports method expressions with parameters in EL expressions – just add the brackets and the call arguments. This used to be tricky, and many posts on technical blogs just seemed to answer ‘why on earth do you want to’. Well, perhaps it is unusual, but in this example it feels just the right thing. Normally when linking to a style sheet, one would put the path to the sheet directly on the page in the <link> tag, as one also would when referring to other resources such as images. I have therefore done exactly the same with the themeswitcher – you pass the theme base web context path (along with the default theme name) to the component just as you would do to a <link> tag. This then allows the backing bean to discover the physical theme directory location on disk and automatically iterate it to generate a list of the available themes which are present, which is then passed to the select list of the combo. Whilst the theme base context path could be set up as an injected property of the backing bean, it just does not feel right to do it that way, as normally this knowledge is encapsulated on the page. Sometimes, passing values from the page to a bean is actually the right thing to do!
  • When using an EL method expression to write to a bean property, note that you can just call a setter on the bean directly as if it was a method, giving the “set” prefix, and passing the value as an argument. You literally just plant the EL call on its own in the middle of the page. (You can of course also use another custom method if you wish, for example if you want to pass a number of properties in a single call). Furthermore, when calling for example a setter or any other method that returns void, nothing is written to the page, as you would expect. In the example code below, the EL expression #{cc.attrs.bean.setThemeBase(cc.attrs.themeBase)} does exactly this.
  • A composite component acts as a JSF naming container. Naming containers are required to ensure uniqueness of IDs on a page , by modifying Ids to add a prefix. For example a composite component could be placed many times on a page, and the Ids of all its constituent components/controls must be unique. As a test example, when the above component was placed in the <head> section (i.e. not in a form), its clientId was j_idt4. When placed on the page a second time, in the form to show the control panel , its clientId was frmTest:j_idt9. Notice that by default the clientId was automatically prefixed by the form ID. This issue becomes important when Javascript is in use to refer to controls in the component, as the Id given to a control is in turn prefixed by the clientId. For example, when on the form, a select box which was given an Id of cmbTheme actually ended up with an id of frmTest:j_idt9:cmbTheme. This needs to be taken account of in the code. Note that in the Javascript examples in Chapter 9 of Core JavaServer Faces (p369), the form is inside the composite component. This turns things around, as the form ID is then prepended by the clientId of the composite component as the latter is a naming container – our case is different.
  • By default a form’s controls have the form id prefixed to their id, as the form is also a naming container. This behaviour can be disabled if desired by adding the attribute prependId=”false” to the form tag, but I did not do this.
  • JSTL functionality can be used such as c:if, and for example you can test parameters passed to composite components (cc.attrs.attrname)– the themeswitcher example uses this with the outputStyle attribute to determine whether to output a <link> tag for the theme stylesheet and set the theme base directory/default theme, or whether to output the themeswitcher control panel. The use of c:if in this way is a powerful means of controlling exactly what a custom component renders on the page, and is a useful alternative to using the render property on a component to prevent it being rendered. In addition, it can for example conditionalise the setting of backing bean properties from the page, as is done in the themeswitcher, which could not be done via toggling the render property on components.  In this case, it seemed more convenient and clearer to give two modes to the same component, so that all the design decisions where encapsulated and visible in one place, rather than inventing another component. Other examples of where this might be useful is where a general purpose composite component might be tailorable via its call attributes. For example a table component might have adjacent up/down buttons to allow re-ordering/moving of a block of selected rows, but the re-order capability might not always be needed, so it could be conditionally selected with c:if.
  • When using JSTL, there are limitations. As an example, I tried c:set to copy an attribute containing the backing bean reference to another variable, to use later in a subsequent instance of the composite component and save passing it twice. Setting a valueChangeListener using the saved copy of the bean reference gave a run time error and is not supported. However, reading and writing properties on the bean using the saved copy of the reference worked fine.
  • Note that other JSTL functions can also be used, e.g. to return the size of a string or list, as noted here.

Comments Off on JSF 2.0 Composite Components