Blog Archives

December 10th, 2010
9:59 am
Date, time and calendar handing in Java

Posted under Java
Tags , , , , ,

This is rather a minefield for the unwary, and in general the various APIs in this area come in for a fair share of criticism.
Poor design, leaky abstractions and unhelpful idioms are variously cited.
However, the functionality available is comprehensive even though it can be tricky to use.

The following posts offer good advice in finding your way!

David Jenkov’s Java Date and Time Tutorial – an excellent tutorial with a number of articles on date, time, calendar handling etc.

O’Reilly OnJava.com – Making Sense of Java’s Dates – another very good tutorial

Sun Java Tutorials – Dates and Times – Sun’s Java tutorial on dates & times

Lavnish – Java Calendar vs Date – article on Lavnish’s blog

No Comments »

December 6th, 2010
10:45 am
Customising the Primefaces Breadcrumb control

Posted under JSF
Tags , , , , ,

This control has a preview mode which dynamically shrinks and expands the links on hover. Nice idea, but it’s rather slow to render the page on load when there are many entries, as the initial compress is done by jQuery so lots of JavaScript going on.

My preference when a lot of entries are present would be to render the control statically, and instead of dynamically expanding the entries, to have them permanently compressed but with tooltips (= html title attribute) to show the full entry on hover (as suggested here in Jenifer Tidwell’s excellent book Designing Interfaces). This would be much faster.

Unfortunately, the current control does not support that – the menu item children that make up the breadcrumb entries do have a ‘help text’ attribute which looks like it should render a title/tooltip but this does not work.

I would like at some point to make a custom version. The best way would probably be to make it a new different control, possibly in my own library but at least as an additional Primefaces control that I could easily deploy on new released without having to customise code.

Chapter 11 of Core JavaServer Faces has a good example walkthrough of a full custom component development, which helps to give a background. Customising the breadcrumb looks easy as it is just a question of enhancing existing code by adding some additional attributes and changing the encoding in the renderer to encode titles and do a static breadcrumb. The following functionality would be needed:-

ToolTipMode attribute to turn on the new mode. Other modes would possibly still be present  – no point in disabling them unless I have too. If it looks like carrying the old modes is a lot of baggage I could create a stripped down control using the old one as a framework, and only support the new modes I require. As I am keeping the existing control there is no need to duplicate its features if I don’t need to. As the rendering for the new control should be straightforward, I could even rip out all the jQuery stuff and just use some of the existing CSS techniques for rendering it, but statically. I would duplicate the classes and give my own names.

In the new mode, all entries would have a hover title.

  • ToolTipCompressThreshold attribute would be a character count for the whole breadcrumb which would trigger compression of all entries equally. This is obviously a static guess figure, but it avoids having to do any client side stuff in JavaScript and so will render fast.
  • ToolTipMaxLength attribute would be a notional maximum length in pixels for the breadcrumb (set separately from the css). When the compress threshold has been reached, this attribute would be divided by the number of breadcrumb entries to be rendered, and the resulting value used as the maximum pixel size for rendering each entry (it would be good to allow them to be shorter if they don’t use all the space, so it does not look odd). Rather than strip out characters from the entries, I would just hide the excess width via a hidden overflow in a div (as the existing control does now).

The source is all available in the source or bundled zip download. Note the following from a first look:-

  • BreadCrumb.java contains the properties for all the attributes – all driven from an enum with custom methods in it (note the technique, could use this as it enforces consistency and avoids typos etc.)
  • BreadCrumbRenderer.java renders all the html and js calls.
  • BreadCrumbTag.java – note that Primefaces 2.2M1 had this file, but 2.2RC2 does not have it. Check/compare the code – they either simplified it or it has gone missing from the latest release. I could base my version on either.
  • MenuItem.java – will probably want to look at this as each BreadCrumb item is a menu item.
  • primefaces-i.taglib.xml and primefaces-p.taglib.xml are the taglibs – I will need to define a taglib for mine (see core Javaserver faces again). Note that these are in the deployed jar but not in the sources jar.
  • faces-config.xml – defines all the component classes. As with the taglibs this is in the deployed jar but not the sources jar.

No Comments »

December 6th, 2010
8:09 am
Hosting Providers

Posted under Hosting
Tags , ,

See this post of mine on PCG technical about what I am after, with links to a number of  hosters of interest.

More recently Rapidswitch were recommended, also on PCG. They are Maidenhead based, on the cordwallis estate. They offer dedicated servers starting at £45 pm – a better option than a virtualised one. Iomart Hosting are their parent company who also host under their own name.

Here is a copy of my PCG post, the link needs a login or it won’t show:-

I’m also looking for Java hosting. I’ll need to host Glassfish V3 and MySQL (might get away with just Tomcat and MySQL at a pinch, but Glassfish preferred).
I’ve seen companies such as this JSPZone and [DE]Systems Engineering who offer this starting at roughly £25-£30pm, but not sure they are any good. 2020media might be a possible but they are Tomcat only hosting. JSPZone is also hosted in NZ which is perhaps not the most net bandwidth friendly solution for a uk project.
I would prefer having a VPS running Ubuntu or similar that I could install what I like on – quite often I’ll need to install a particular patch release of some or other component in the software stack, and want complete freedom to be able to do this, along with the ability to bounce it all at will. I can also freely add anything else I fancy. Whilst this means more work in terms of building the server image etc. and maintaining it, I feel the extra freedom would be worth it. I’m assuming I’ve understood VPS hosting correctly here and that I can run whatever I like that runs on the target Linux version – please correct me if any caveats here!
For a VPS solution, I’ve seen companies such as Switchlink, UKHost4U and BOD Host offer this for a tad more (of order £35pm) but I have no idea if they are any good.
As well as particular hosting recommendations, I would be very interested if the panel experts know of a good review site that could help. I saw WebHostingStuff here, but was somewhat dismayed to see that 2 of the companies that our good friend Openstrike was rather less than complimentary about actually got reasonable reviews here and here. Obviously I am only interested in review sites whose opinion is, well, worth taking notice of.
I do get the feeling that finding a good hosting provider is about as easy as finding a good plumber or roofer \:\(
I won’t need this for a while yet, just planning ideas well ahead of time. Until I am a lot further down the road I won’t have any figures for bandwidth and space requirements. I presume I can move up from VPS hosting to dedicated server hosting, and also presume that a cloud solution like Amazon EC2 would allow me scaling on demand if I need it (albeit at a premium price). Again, any comments welcomed.
TIA
Steve

No Comments »

December 3rd, 2010
12:17 pm
Using the Primefaces Breadcrumb Component

Posted under JSF
Tags , , , ,

I did some experimentation on the best look and feel (in my humble opinion!) for this component, and found the following points along the way:-

  • By default the component was underlining all the entries. This was because all anchor tags were being underlined. The Primefaces showcase has specific rules in default.css to turn this off, so I added them too. (You might have expected this to all be done by the themes or breadcrumb css, but not the case). I just added “a {text-decoration: none;}” and “a:hover {text-decoration: underline;}” rules, but obviously there are other ways if you want other links to be underlined.
  • I then tried to place a breadcrumb in a scrolling div, to ensure that it would still work if the content overflowed. I knew that horizontal scroll bars on a breadcrumb would not look at all sexy, but wanted at least some solution for edge cases with extreme amounts of content, as by default the component truncates to the right and content is lost/not accessible. I was unable to solve this issue – the component would not play ball. I wanted to leave an inner div containing the component at a floating size, so that the control sized itself for the content, and then add a scrollable outer div with overflow:auto so that it would scroll if needed. However, the component appears to use some jQuery magic to detect the size of any fixed ancestor outer level div of the component, and then fix the control width to that size using inline styling added to one of its own inner divs by jQuery/Javascript. The only partial solution was to have a large fixed size component in a smaller outer scrolling div, but this was not good as the scrollbars were present even if not needed as the control had a fixed size.
  • The problem could probably be solved using jQuery, perhaps by modifying the jBreadcrumb jQuery component which Primefaces uses, but I did not investigate this further.
  • In the end, I reconciled myself with the default way the component works. It does have a good solution to this issue by (optionally) dynamically collapsing the entries to a designated preview width, and then expanding an entry on mouse hover (so-called preview mode). This does save a lot of space, and I decided that I could easily have more than enough entries for my needs in say an 800 pixel wide breadcrumb. Alternatively the component can be left to float entirely and rely on the browser for scrolling, but in practice there will generally be an outer container of some kind which will set a limit and trigger the above issue. In my case, this would likely be an outer level tab for a form.
  • I also decided that in practice it would be helpful to turn the preview mode on dynamically, perhaps say when the number of entries exceeded a certain number, or better still when the total character count in the breadcrumb exceeds a certain figure, as this would give good results on average and still be easy to calculate. For normal use, when there is plenty of room left in the breadcrumb, preview mode is a nuisance, but it is obviously essential when the component fills up. Ideally, this would be done when the component is filled rather than based on an entry count, but this would be tricky to calculate. Ideally this would be done dynamically by the component itself. Best of all might be a dynamic preview mode which shrinks the entries only when required and only enough to fit everything in the component.
  • Rendering the component in preview mode takes significant time when there are a lot of entries (even on my Core I7 920). This might be an issue when partially updating a page (and the component) during navigation. This is even more reason not to use preview mode unless it is really essential, as with it turned off the breadcrumb renders very quickly. On some occasions it would be possible to update the control client side, for example when just changing the underline/italic decoration on the text (see below re traversing a hierarchy) and no entries are added or removed. In this case the necessary classes could just be added and removed from the breadcrumb entries dynamically with jQuery. I have also not tried any Ajax/partial form updates with it, for example just adding or removing a single entry, but I expect the whole component will be re-rendered each time as the manual makes no mention of partial updating.
  • I experimented a bit with the expand and contract timings in preview mode. These interact with the time taken by the JavaScript to dynamically collapse the entries when the component is first rendered, so if you try to make them too fast it looks clunky. Also if the expand is too fast it can confuse you as to which entry you are hovering on, especially when there is a lot of preview compression, as you can end up highlighting the next entry along without realising it, just due to the expand/collapse effect.
  • One common use case for me is to use the component to hold the navigation path when traversing a hierarchical data set. A desirable feature would be that when you traverse back up the tree say by clicking on one of the higher levels in the breadcrumb, you do not immediately lose all the lower levels you visited. They would only be removed if you visited a higher level and then traversed down a different lower level path at some point, in which case the lower levels visited previously beyond that point would then be removed and a new path built.
  • The nice thing about the above concept is that you can repeatedly wander freely up and down a given tree path via the breadcrumb without losing any of the context, which is handy in my case as the UI deliberately only shows the current level of the tree in a table – no tree or treetable components are used in order to keep things intuitive and simple for novice users.
  • When applying this concept, it is necessary to highlight the current location in the breadcrumb, as this will no longer always be the rightmost entry. The most logical way to do this seemed to apply the same highlight as the mouse hover, which is to underline an entry. Therefore, the current entry will always be underlined, as will any other entry that is hovered over.
  • In addition, it is desirable to distinguish between the breadcrumb levels between the root and the current point from those previously visited below the current point, as the breadcrumb is no longer only showing the path to where you currently are. I tried various kinds of dimmed, disable style highlighting, but whilst it is important to make these previously visited lower level entries look different, it must also be clear that you can still click on them. In the end, my preferred solution which looks good in all the top 5 browsers and with all the Primefaces themes was to italicise the previously visited lower level entries. You therefore end up with ‘normal’ styling up to the current level. The current level itself is then shown underlined so it is clear where you are. All the entries to the right (if any) are then italicised.

The following example shows my preferred component, which is somewhat thinner than the default due to the removed padding. Examples of the different highlighting discussed above are all just coded directly into the menu options. The example also uses my theme switcher component which is not listed.

 

index.xhtml

<!DOCTYPE HTML>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"   
xmlns:util="http://java.sun.com/jsf/composite/uk.co.salientsoft/util">
<f:view contentType="text/html">
<h:head>
    <util:themeSwitcher    outputStyle="true"
                        themeBase="/resources/themes"
                        defaultTheme="redmond"/>
<style>
    .ui-widget {
        font-size: 75% !important;
    }
    h1.header {
        font-size: 1.2em !important;
        padding: 5px;
        margin: 0px 0px 20px 0px;
        float: left;
    }
    .themeswitcher {
        float: left;
        clear: both;
        margin-bottom: 20px;
    }   
    .ss-breadcrumb {
        clear:both;
        margin: 0 0 10px 0;
        padding: 0;
        width:800;
    }   
    a {text-decoration: none;}
    a:hover {text-decoration: underline;}
    .ss-currentlevel {text-decoration:underline;}
    .ss-lowerlevel {font-style: italic;}
</style>

</h:head>
<h:body>
<h1 class="header ui-widget ui-widget-header ui-corner-all" style="">Breadcrumb</h1>

<h:form id="frmTest">
<util:themeSwitcher form="frmTest" outerStyleClass="themeswitcher"/>
<br/><br/>
    <p:breadCrumb styleClass="ss-breadcrumb" preview="false">
        <p:menuitem value="Categories" url="#" />
        <p:menuitem value="Sports" url="#" />
        <p:menuitem value="Football" url="#" />
        <p:menuitem value="Countries" url="#" styleClass="ss-currentlevel"/>
        <p:menuitem value="Spain" url="#"  styleClass="ss-lowerlevel"/>
        <p:menuitem value="F.C. Barcelona" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Lionel Messi" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel"/>
        <p:menuitem value="Lionel Messi" url="#" styleClass="ss-lowerlevel" />
    </p:breadCrumb>
    <p:breadCrumb styleClass="ss-breadcrumb" preview="true" previewWidth="24"
        expandEffectDuration="400" initialCollapseEffectDuration="100"
        expandedBeginningItems="1" expandedEndItems="1">
        <p:menuitem value="Categories" url="#" />
        <p:menuitem value="Sports" url="#" />
        <p:menuitem value="Football" url="#" />
        <p:menuitem value="Countries" url="#" />
        <p:menuitem value="Spain" url="#" />
        <p:menuitem value="F.C. Barcelona" url="#"  styleClass="ss-currentlevel"/>
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Lionel Messi" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Categories" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Sports" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Football" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Countries" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Spain" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="F.C. Barcelona" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Squad" url="#" styleClass="ss-lowerlevel" />
        <p:menuitem value="Lionel Messi" url="#"  styleClass="ss-lowerlevel" />
    </p:breadCrumb>
</h:form>
</h:body>
</f:view>
</html>

No Comments »

December 3rd, 2010
9:42 am
JPA error “Class is mapped, but is not included in any persistence unit”

Posted under JPA
Tags , , , ,

I received this compile time error from Eclipse with one of my test projects which was previously fine, using Eclipse Helios with Eclipselink 2.1.0 (and container managed JPA in EJBs). The error occurred when I was autodiscovering the entities rather than listing them in persistence.xml explicitly, even when <exclude-unlisted-classes>false</exclude-unlisted-classes> was explicitly present.

Supposedly, as the annotated entity sources for the classes are in a subfolder of the parent of the META-INF folder containing persistence.xml, they should be discovered automatically. Listing the fully qualified classes explicitly in persistence.xml solved the problem, however this is not ideal as it would mean having an alternative version of persistence.xml for testing.

I googled for the problem but could not find a solution listed anywhere. For now this is just one to be aware of – I’ll stick with listing the classes explicitly and look further for a solution later on as and when it becomes a nuisance!

No Comments »

December 1st, 2010
11:26 am
List of useful Bookmarklets

Posted under HTML
Tags , , ,

This page here contains a number of useful commonly used bookmarklets.

Just drag them and drop them on your favourites bar to make them easily accessible.

My favourites are the following browser window resizing bookmarklets – useful for web development testing.

NoteThese Bookmarklets use the JavaScript Window.resizeTo() method which is not supported in Opera and Chrome.
Also, IE8 only supports these when a single tab is open. Use F12 in IE to do this if you have multiple tabs open.
Firefox has the best overall support for them as they will still work with multiple tabs open.

Resize to 240×320 (pocketPC)

Resize to 544×372 (webTV)

Resize to 640×480

Resize to 800×600

Resize to 1024×768

Resize to 1280×1024

No Comments »

November 30th, 2010
4:37 pm
Tailoring a Primefaces TreeTable with JavaScript/jQuery/JSF 2.0

Posted under JSF
Tags , , , , , , , ,

This example came about from the desire to hightlight a Primefaces TreeTable row when a checkbox in the row is ticked. I wanted to do this because a ticked checkbox is not as visible as I would like when a lot of data is present. I was not keen on adding DataTable style dynamic selection by hovering and clicking anywhere in a row, as this conflicts somewhat with the paradigm of clicking on the expander to expand/collapse the tree, and you would have to special case hovering/clicking on the expander somehow to prevent row selection.

Ideally you would use CSS for this, but this would involve tagging a component in a TreeTable cell (<td> element) with a class (as in the TreeTable component we cannot directly add row styling), and then using some kind of ancestor selector to traverse the DOM tree upwards to get the row. The simple answer to this is that whilst CSS can do some clever things, it does not have any kind of ancestor selector, so it is not possible to do it just with CSS.

An attractive alternative for this kind of thing in Primefaces is to use jQuery – a very powerful JavaScript based UI library upon which Primefaces is based. As it is already present in a Primefaces environment, it is trivial to call and ideal for this kind of thing. In particular, it has powerful mechanisms for traversing and searching the DOM tree and selecting elements etc. If you combine this with its features for dynamically adding and removing classes from elements, it can do exactly the kind of thing that we cannot do in CSS. The jQuery website is here, and the API documentation for it may be found here.

The sample code fragments below demonstrate the idea. The sample is based on a hacked version of the the Primefaces showcase TreeTable demo. Note the following points:-

  • It is perfectly possible to add both Javascript and JSF EL inline inside a JSF component, such that the JavaScript runs at that point when the page is rendered. This example adds some JavaScript inside the JSF tags for a checkbox.
  • As the example uses JavaScript, the hightlight is added/removed both client side from a click event on the check box, and when the page is rendered based on the current check box value in the TreeTableDocument object from the server.
  • The sample uses the JSF 2.0 EL implicit object reference component.clientId to get the client ID of the component where the EL reference is used. This is new for JSF 2.0 (previously additional code would be needed for this) and like the cc implicit object used with composite components, is not at all well documented. I was unable to find reference documentation for it anywhere in the JSF 2.0 specs, but found details of it here (at the end of the post). Note that the reference needs to be placed with care – it sometimes appears to come up with ‘ghost’ client IDs which may have been allocated by JSF but do not actually appear anywhere as IDs in the HTML. When using it, check that it returns the correct ID, for example by just placing a bare #{component.clientId} on the page directly adjacent to where you are using it, and view the source of the generated page in the browser to check that the client ID it returns matches the id of the component it is used for.
  • Be careful to consider any ordering issues – the inline JavaScript call I am using must be placed on the page after the component it refers to has been rendered. By default, using component.clientId  inside a script block which is in turn inside the checkbox component tags causes the script block to be output immediately prior to the html for the checkbox. Therefore, I use two script blocks – one inside the checkbox to save the component ID in a temporary JavaScript variable, which guarantees that I obtain the correct component ID and not an incorrect or ‘ghost’ one, and then another script block immediately after the closing tag for the checkbox component which passes the form ID and saved component ID to a JavaScript function which calls jQuery to do the highlighting after the html element has been rendered on the page. Note that the client side onClick() event on the checkbox will always run after  the full page has been rendered, when the user clicks the box, so ordering is not an issue for this.
  • The call to jQuery passes in the checkbox DOM element, which jQuery wraps with a jQuery object and returns. The parent() method is then used twice to traverse the DOM tree up from the check box to the table cell <td>, and thence to the table row <tr>. The addClass() and removeClass() methods are then used to dynamically add/remove the required CSS classes to the table row depending on the passed check box state. Adding and removing classes with jQuery is useful as it does all the string bashing for you to check if the class being added/removed is already present, handles spaces correctly, and leaves all other classes on the element intact.
  • Note that in an earlier version I had tricky issues with nested quotes in JSF EL. I initially used outer double quotes, with inner single quotes on the JavaScript calls. The EL through this out however. I ended up using double quotes throughout, and escaped the inner ones with backslashes (\). This worked fine. The version shown here does not need this as it is a later modification.
  • The example extends the Primefaces Document class used in the showcase, adding a boolean property for the check box value.
  • My example uses CDI, whereas the original showcase uses JSF managed beans.

Sample Code Fragments

Index.xhtml

<!DOCTYPE HTML>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"   
xmlns:util="http://java.sun.com/jsf/composite/uk.co.salientsoft/util">
<f:view contentType="text/html">
<h:head>
    <util:themeSwitcher    outputStyle="true"
                        themeBase="/resources/themes"
                        defaultTheme="redmond"/>
<style>
    .ui-widget {
        font-size: 75% !important;
    }
    h1.header {
        font-size: 1.2em !important;
        padding: 5px;
        margin: 0px 0px 20px 0px;
    }
    h2.subheader {
        font-size: 0.9em !important;
        padding: 2px;
        margin: 0px 0px 10px 0px;
    }
    .float {
        float: left;
    }
   
    .clear {
        clear: both;
    }
    .themeswitcher {
        float: left;
        clear: both;
        margin-bottom: 10px;
    }   
    .ss-selectcolumn {
        width:30px !important;
        padding:0px !important;
        text-align:center;
    }
    .ss-checkbox {
        color:red!important;
    }
/* treetable arrow light/dark switch
    .ui-treetable tr.collapsed td .expander {
        background-image:url("/TreeTable1/javax.faces.resource/treetable/images/toggle-expand-light.png.jsf?ln=primefaces&amp;v=2.2.RC2");
    }
    .ui-treetable tr.expanded td .expander {
        background-image:url("/TreeTable1/javax.faces.resource/treetable/images/toggle-collapse-dark.png.jsf?ln=primefaces&amp;v=2.2.RC2");
    }   
*/
/* Styling nicked from default.css in the Primefaces Showcase */
    a {text-decoration: none;}
    a:hover {text-decoration: underline;}
    a img {border: none;}   
</style>

<script type="text/javascript">
//<![CDATA[
    function highlightTreeTableRow(formId, checkBoxId) {
        var checkBox = document.forms[formId][checkBoxId];
        if (checkBox.checked)
            jQuery(checkBox).parent().parent().addClass(‘ui-state-highlight ui-selected’);
        else
            jQuery(checkBox).parent().parent().removeClass(‘ui-state-highlight ui-selected’);
    }
//]]>
</script>
</h:head>
<h:body>
<h1 class="float header ui-widget ui-widget-header ui-corner-all" style="">Theme Switcher</h1>
<h:form prependId="false" id="frmTest">
<util:themeSwitcher form="frmTest" outerStyleClass="themeswitcher" style="margin-bottom:20px;"/>
<br/><br/>

<div style="width:600px;clear:both;">
    <p:treeTable value="#{documentsController.root}" var="document"
       styleClass="#{(document.name==’logo.png’)? ‘ui-state-highlight ui-selected’:’fred’}"
        expanded="true">
        <p:column>
            <f:facet name="header">
                Name
            </f:facet>
            <h:outputText value="#{document.name}" />
        </p:column>
       
        <p:column>
            <f:facet name="header">
                Size
            </f:facet>
            <h:outputText value="#{document.size}" />
        </p:column>
       
        <p:column>
            <f:facet name="header">
                Type
            </f:facet>
            <h:outputText value="#{document.type}" />
        </p:column>
       
        <p:column>
            <f:facet name="header">
                Options
            </f:facet>
            <p:commandLink update="documentPanel" oncomplete="documentDialog.show()" title="View Detail">
                <p:graphicImage value="/images/search.png"/>
                <f:setPropertyActionListener value="#{document}" target="#{documentsController.selectedDocument}" />
            </p:commandLink>
        </p:column>
       
        <p:column styleClass="ss-selectcolumn">
            <f:facet name="header">
            <h:selectBooleanCheckbox disabled="true" label="box header"/>
            </f:facet>
            <h:selectBooleanCheckbox value="#{document.selected}"
                 
onclick="highlightTreeTableRow(‘frmTest’, this.id);" styleClass="ss-checkbox" id="selector" >                
                 <script>selectId = ‘#{component.clientId}’;</script>
            </h:selectBooleanCheckbox>
            <script>highlightTreeTableRow("frmTest", selectId);</script>
        </p:column>
    </p:treeTable>
    <p:commandButton type="submit" value="Submit" onclick="submit();" style="margin-top:10px;"/>
   
    <p:dialog header="Document Detail" fixedCenter="true" effect="FADE" effectDuration="0.3"
        widgetVar="documentDialog" modal="true">
   
        <p:outputPanel id="documentPanel">
            <h:panelGrid  columns="2" cellpadding="5">
                <h:outputLabel for="name" value="Name: " />
                <h:outputText id="name" value="#{documentsController.selectedDocument.name}" style="font-weight:bold" />
               
                <h:outputLabel for="size" value="Size: " />
                <h:outputText id="size" value="#{documentsController.selectedDocument.size}" style="font-weight:bold" />
               
                <h:outputLabel for="type" value="Type " />
                <h:outputText id="type" value="#{documentsController.selectedDocument.type}" style="font-weight:bold" />
            </h:panelGrid>
        </p:outputPanel>
    </p:dialog>
    </div>
</h:form>
</h:body>
</f:view>
</html>

DocumentsController.java (modified from Showcase)

package org.primefaces.examples.view;
import java.io.Serializable;
import java.util.logging.Logger;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
import uk.co.salientsoft.treetable.view.TreeTableDocument;

@Named
@SessionScoped
public class DocumentsController implements Serializable {
   
    private static final long serialVersionUID = -3593168523028092346L;
    private static final Logger logger = Logger.getLogger(DocumentsController.class.getName());
    private TreeNode root;
    private TreeTableDocument selectedDocument;
    public DocumentsController() {
        root = new DefaultTreeNode("root", null);
       
        TreeNode documents = new DefaultTreeNode(new TreeTableDocument("Documents", "-", "Folder"), root);
        TreeNode pictures = new DefaultTreeNode(new TreeTableDocument("Pictures", "-", "Folder"), root);
        TreeNode music = new DefaultTreeNode(new TreeTableDocument("Music", "-", "Folder"), root);
       
        TreeNode work = new DefaultTreeNode(new TreeTableDocument("Work", "-", "Folder"), documents);
        TreeNode primefaces = new DefaultTreeNode(new TreeTableDocument("PrimeFaces", "-", "Folder"), documents);
       
        //Documents
        TreeNode expenses = new DefaultTreeNode("document", new TreeTableDocument("Expenses.doc", "30 KB", "Word Document"), work);
        TreeNode resume = new DefaultTreeNode("document", new TreeTableDocument("Resume.doc", "10 KB", "Word Document"), work);
        TreeNode refdoc = new DefaultTreeNode("document", new TreeTableDocument("RefDoc.pages", "40 KB", "Pages Document"), primefaces);
       
        //Pictures
        TreeNode barca = new DefaultTreeNode("picture", new TreeTableDocument("barcelona.jpg", "30 KB", "JPEG Image"), pictures);
        TreeNode primelogo = new DefaultTreeNode("picture", new TreeTableDocument("logo.jpg", "45 KB", "JPEG Image"), pictures);
        TreeNode optimus = new DefaultTreeNode("picture", new TreeTableDocument("optimusprime.png", "96 KB", "PNG Image"), pictures);
       
        //Music
        TreeNode turkish = new DefaultTreeNode(new TreeTableDocument("Turkish", "-", "Folder"), music);
       
        TreeNode cemKaraca = new DefaultTreeNode(new TreeTableDocument("Cem Karaca", "-", "Folder"), turkish);
        TreeNode erkinKoray = new DefaultTreeNode(new TreeTableDocument("Erkin Koray", "-", "Folder"), turkish);
        TreeNode mogollar = new DefaultTreeNode(new TreeTableDocument("Mogollar", "-", "Folder"), turkish);
       
        TreeNode nemalacak = new DefaultTreeNode("mp3", new TreeTableDocument("Nem Alacak Felek Benim", "1500 KB", "Audio File"), cemKaraca);
        TreeNode resimdeki = new DefaultTreeNode("mp3", new TreeTableDocument("Resimdeki Gozyaslari", "2400 KB", "Audio File"), cemKaraca);
       
        TreeNode copculer = new DefaultTreeNode("mp3", new TreeTableDocument("Copculer", "2351 KB", "Audio File"), erkinKoray);
        TreeNode oylebirgecer = new DefaultTreeNode("mp3", new TreeTableDocument("Oyle bir Gecer", "1794 KB", "Audio File"), erkinKoray);
       
        TreeNode toprakana = new DefaultTreeNode("mp3", new TreeTableDocument("Toprak Ana", "1536 KB", "Audio File"), mogollar);
        TreeNode bisiyapmali = new DefaultTreeNode("mp3", new TreeTableDocument("Bisi Yapmali", "2730 KB", "Audio File"), mogollar);
    }
    public TreeNode getRoot() {return root;}
    public void setRoot(TreeNode root) {this.root = root;}
    public TreeTableDocument getSelectedDocument() {return selectedDocument;}
    public void setSelectedDocument(TreeTableDocument selectedDocument) {
        this.selectedDocument = selectedDocument;
    }
}

TreeTableDocument.java

package uk.co.salientsoft.treetable.view;
import org.primefaces.examples.domain.Document;

public class TreeTableDocument extends Document {
    private static final long serialVersionUID = 7339615098050125785L;
    public TreeTableDocument(String name, String size, String type) {
        super(name, size, type);
    }   
    private boolean;
    public boolean isSelected() {return this.selected;}
    public void setSelected(boolean selected) {this.selected = selected;}
}

No Comments »

November 26th, 2010
8:25 pm
Using container managed JPA 2.0 with CDI/EJB 3.1/Glassfish 3

Posted under JPA
Tags , , , , , ,

Update

  • One issue to be aware of, which is not immediately obvious, is when populating a database from scripts. If the version column is left null (Eclipselink leaves it as nullable by default), then the null value causes an immediate OptimisticLockException to be thrown. This is because EclipseLink expects and checks for a zero as the initial value for a new record. If EclipseLink itself persists the record, then it writes a zero.
  • One good idea to resolve this would be to enforce version columns to be non null with a zero default – although it must be said that it would be helpful if EclipsLink did this automatically in response to the @Version annotation.
  • Population scripts should therefore set version to zero, unless it is set non null with a default of zero in JPA – this latter solution is cleaner and would be automatic for me because I create version columns in a mapped superclass used by all Entities. I have yet to test this out however.

 

Original Post

This follows on from a previous post relating to JPA 1.0/Glassfish 2.1, and contains a few notes and pointers relating to JPA 2.0 under Glassfish 3 with CDI/Weld.

Firstly, when using an EJB from a client, use CDI injection (@Inject) rather than the @EJB annotation, as CDI gives many additional benefits such as type safety.

In an EJB:-

  • You are using container managed transactions, and so simply have to inject an entity manager rather than create one from an entity manager factory.
  • The container managed entity manager can be injected with a simple @PersistenceContext annotation – the persistence unit name may be defaulted and is discovered automatically.
  • The container is responsible for entity manager lifetime/closing. Calling e.g. em.close at the end of a bean method is illegal and will make Glassfish angry. You do not want to make Glassfish angry – you end up with many long stack traces in the log which on the surface do not appear to relate to this trivial problem!

A major issue with container managed transactions is how to use optimistic locking and detect and handle optimistic lock exceptions correctly. This is detailed in Pro JPA 2, pages 355-357 (you can preview this in Google Books). The main problem is that in a server environment, the OptimisticLockException will simply be logged by the container which then throws an EJBException. Trying to catch an OptimisticLockException in the calling client is therefore doomed to failure – it will probably never be caught!

The solution is to call flush() on the entity manger (e.g. em.flush()) just before you are ready to complete the method. This forces a write to the database, locking resources at the end of the method so that the effects on concurrency are minimised. This allows us to handle an optimistic failure while we are still in control, without the container swallowing the exception. The ChangeCollisionException might contain the object which caused the exception, but it is not guarranteed to. If there were multiple objects in the transaction, we could have invoked getEntity() on the caught exception to see whether the offending object was included.

If we do get an exception from the flush() call, we can throw a domain specific application exception which the caller can recognise, i.e. convert an OptimisticLockException to our own ChangeCollisionException, avoiding coupling the caller to the internal semantics of JPA transactions. It is also desirable to factor out the code which calls flush() into our own method, e.g. flushChanges() to avoid the need for every method which needs to flush having to catch the optimistic lock exception and then throw our domain specific one – we can centralise the exception conversion in our own single method.

We must annotate the ChangeCollisionException class with @ApplicationException, which is an EJB container annotation, to indicate to the container that the exception is not really a system level one but should be thrown back to the client as-is. Normally defining an application exception will cause the container not to roll back the transaction, but this is an EJB 3 container notion. The persistence provider that threw the OptimisticLockException  (in this case Eclipselink) does not know about the special semantics of designated application exceptions and, seeing a runtime exception, will go ahead and mark the transaction for rollback. The client can now receive and handle the ChangeCollisionException and do something about it.

Here is an example of our exception class with the required annotation:-

@ApplicationException
public class ChangeCollisionException extends RunTimeException {
   public ChangeCollisionException() {super(); }
}

Here are code fragment examples from a stateless session bean showing the entity manager injection, and a client JSF model bean showing the CDI injection of the stateless session bean. Note that with EJB 3.1 it is not necessary to declare local or remote interfaces for an EJB as business interfaces are not a requirement. However, I always use an interface as it allows for example a mock version of a service layer to be easily swapped in for testing. CDI supports this conveniently via alternatives, whereby a mock version of a bean can be switched in via a setting in beans.xml for testing.

@Stateless
public class SentryServiceImpl implements SentryServiceLocal {

    @PersistenceContext
    private EntityManager em;

}

@Named
@Dependent
public class ModelBeanImpl implements ModelBean, Serializable {
    private static final long serialVersionUID = -366401344661990776L;
    private @Inject SentryServiceLocal sentryService;
… 
}

With container managed JPA and/or Glassfish your persistence.xml  can also be simplified, as you can define your data source in Glassfish rather than explicitly in persistence.xml, as described here.

Note that when defining a data source directly in persistence.xml,  some property names have been standardized for JPA 2.0, so have changed from e.g. eclipselink.jdbc.user to javax.persistence.jdbcuser. The following properties in persistence.xml are now standard:-

<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
<property name="javax.persistence.jdbc.user" value="sentry"/>
<property name="javax.persistence.jdbc.password" value="sentry"/>
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver"/>

An example persistence.xml used under JPA 2.0 follows:-

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="SentryPrototype" transaction-type="JTA">
      <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
      <jta-data-source>jdbc/SentryPool</jta-data-source>
      <properties>
       <property name="eclipselink.logging.level" value="INFO" />
       <property name="eclipselink.target-database" value="Oracle" />      
       <property name="eclipselink.ddl-generation.output-mode" value="database" />      
      </properties>
     </persistence-unit>
</persistence>

No Comments »

November 23rd, 2010
11:38 am
Using floats to place a border around a control group/toolbar

Posted under CSS
Tags , , , , , , ,

I originally used display:inline-block, line-height and vertical-align:middle to do this as detailed here, but the results were inconsistent across browsers.

Using floats is a much better solution for a number of reasons – details are as follows:- 

  • The controls are floated left inside a div which is itself floated left. As the div is floating, it auto resizes to fit around the content, and so scales to fit unknown control sizes.
  • The controls are all set to have fixed top and bottom margins (4px in the example), and the leftmost and rightmost also have similar left and right margins respectively.
  • The floated div is set to have the desired border and background etc. – in my case, I use Primefaces/jQuery UI theme style classes to apply theme look and feel.
  • The floated div is then placed inside another outer div, which may be of fixed dimensions. This allows the control group to adjust in size, but to be located inside a fixed area on a page.
  • If the outer div is of fixed size and non floating, the floating inside it is invisible to the rest of the document, so it is not necessary for example to clear the float.
  • If desired, the outer div can be set to overflow:auto to allow scroll bars if the size of the inner floating div exceeds the space allocated for it on the page.
  • If the area surrounding the control group is also floating, the outer div can also be set to float with no size specified, so the concept works well in both floating and fixed size situations.
  • display:inline-block and vertical-align:middle are not used with this method.

 This mechanism has the following characteristics:-

  • The control group bordering works nicely and consistently with the Primefaces/jQuery theme styling, as rather than trying to centre the controls in a fixed border, instead we vary the border size and keep the margin between the controls and the border constant.
  • The approach makes use of the laws of Gestalt Psychology – the eye notices even small imperfections in the alignment of the controls and their relationship to the border because they are close and obviously grouped/related.
  • Conversely the position of the entire bordered control group within its surroundings (the outer div) will typically not be so critical – it will likely be in a larger area of white space between it and adjacent items,  and so its position and size within that space matters less than the control / border relationship.

A caveat to all this is that it is still not perfect – the simple example below does not perform quite as well in terms of cross browser alignment as the Primefaces/jQuery UI version, as the Primefaces themes apply their own styling as well which changes the situation. This could of course be improved by adjusting the margins individually for different controls in the group to get the best overall cross browser alignment. One very important goal I am trying to acheive is to avoid browser specific CSS. The Primefaces/jQuery UI CSS does in general have browser specific tweaks which will help it in certain situations.

Overall though this approach performs significantly better than the previous method using vertical-align:middle etc. and has the advantage of being fully floating/dynamically sizing if required. An example of this approach follows :-

<!DOCTYPE html>
<html>
<head>
 <style type=”text/css”>
  .ss-outerdiv {
   height: 40px;
   width: 200px;
   background-color: orange;
  } 
  .ss-controlgroup {
   float: left;
   background-color: green;
   border: 1px solid black;
  }
  .ss-select, .ss-leftbutton, .ss-rightbutton {
   margin-top: 4px;
   margin-bottom: 4px;
   float: left;
  }
  .ss-select {
   width: 120px;
     font-family: Arial,Verdana,sans-serif;
     font-size: 11px;    
   margin-left: 4px;
   margin-right: 4px;
  }
  .ss-leftbutton, .ss-rightbutton {
   height: 20px;
   width: 30px;
  }
  .ss-leftbutton  {margin-right: 2px;}
  .ss-rightbutton {margin-right: 4px;}
 </style>
</head>
<body>
<div class=”ss-outerdiv”>
 <div class=”ss-controlgroup”>
  <select class=”ss-select”>
  <option value=”Test”>Test Value</option>
  </select>
  <button class=”ss-leftbutton ss-button”></button>
  <button class=”ss-rightbutton ss-button”></button>
 </div>
</div>
</body>
</html>

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