« March 2007 | Main | May 2007 »

April 2007 Archives

April 10, 2007

ADF Binding 10.1.3.x: Clearing the input values

Today, I was facing a surpring problem with my ADF application.

My application contains a number of pages for creating new entries in a database (I call them "create" pages). This sounds like a common usage and it is. The interesting part showed up when I called the "create" page again (after doing some other stuff in the application).

The "create" page was not an empty page as expected, but had the values previously entered to create a new entry. This is quite handy for testing but unintentional.

The hint for the solution came from Frank Nimphius:

In an actionListener for the "Create" button do something like this:
FacesCtrlAttrsBinding o =
  (FacesCtrlAttrsBinding)bindings.get("nameSrch");
o.setInputValue("%");


Although this sounds fairly easy, it becomes quite tedious for many different pages.

Digging deeper in the ADF Binding API, I found the generic solution:

protected void resetForm(BindingContainer bindings) {
  List l = bindings.getAttributeBindings();
  for (Iterator it = l.iterator(); it.hasNext();) {
    Object o = it.next();
    if (o != null) {
      if (o instanceof FacesCtrlAttrsBinding) {
        ((FacesCtrlAttrsBinding)o).setInputValue(null);
      }
    }
  }
}


Calling this method in your Action Listener just before you return the desired outcome will do the trick.

April 16, 2007

EJB 3 in Action

My wife usually gets berserk when I return from the book store. (Yet another book!) With this one it might be a bit easier, as I have it as PDF on my disk (a plus when searching in the content...).

Although EJB 3 in Action (Debu Panda, Reza Rahman, Derek Lane) adds 709 pages to your book shelf, these are worth the space and money.

Frankly, EJB 3 in Action is not the first book on EJB 3 and JPA, but it is certainly one of the best. Being suitable for different the entry levels (Beginner, Advanced, Migrators) it gives a gentle and smooth entry into EJB 3 and JPA. If you're used to EJB 2.1 you'll find a complete chapter just for migration to EJB 3, telling which road to go and pit-falls to avoid. If you've just implemented you're solution the book helps you to check your application for performance issues and advises how to solve them. The chapters on EJB 3 with Spring, Annotations Reference, and Deployment Descriptor Reference are a useful wrap-up of this fine book.

I really liked reading it because of the refreshing style of language and, more importantly, the chapter on Performance and Scalability as well as the Part Migration and Interoperability Issues. I'm a bit selfish here, because it proves useful to have a third opinion while suggesting solutions or advising for tuning, issue resolution, migration.

You might also read this review on Javalobby.org

April 23, 2007

ADF Faces 10.1.3: Setting skins per user role

One nice and impressive end user feature of ADF Faces is the Dynanic Skin Switching. To visualize the different user roles in a particular application I've implemented a skin change during the login phase of the application.

1. Get Skins

To use different skins, you need to have different skins available. The easiest way to get them is via the JDeveloper 10.1.3 "Additional ADF Faces Skins" Extension. This is available for free through Help -> Check for Updates.

2. Copy the Skins to Your Application

To use them in your application you have to copy them to the web directory (per default public_html) in your project. Simply create a skins subdirectory and copy them from $JDEV_HOME/jdev/extensions/skins into it.

3. Create adf-faces-skins.xml

To use the skins you to create a file called WEB-INF/adf-faces-skins.xml. This file needs some names for the specific skins. Here is an example:
<?xml version="1.0" encoding="ISO-8859-1"?>
<skins xmlns="http://xmlns.oracle.com/adf/view/faces/skin">
 <skin>
  <id>srdemo.desktop</id>
  <family>srdemo</family>
  <render-kit-id>oracle.adf.desktop</render-kit-id>
  <style-sheet-name>skins/srdemo/srdemo.css</style-sheet-name>
 </skin>
 <skin>
  <id>mycompany.desktop</id>
  <family>mycompany</family>
  <render-kit-id>oracle.adf.desktop</render-kit-id>
  <style-sheet-name>skins/mycompany/myCompanySkin.css</style-sheet-name>
 </skin>
 <skin>
  <id>limerine.desktop</id>
  <family>limerine</family>
  <render-kit-id>oracle.adf.desktop</render-kit-id>
  <style-sheet-name>skins/limerine/limerine.css</style-sheet-name>
 </skin>
</skins>


4. Configure ADF Faces to Use the Skin You Want

By default the oracle skin family will be used in ADF Faces (even if the value of the <skin-family> tag is empty). To make ADF Faces aware of a different skin, you must modify the WEB-INF/adf-faces-config.xml to have line like this:
 <skin-family>#{sessionScope.skinFamily}</skin-family>

With this line we're able to change the skin on the fly simply by setting the skinFamily session attribute.

5. Set the Session Attribute

In your loginAction method you can set the value for the user by calling this code sequence (with the mycompany skin for a particular role):
 FacesContext ctx = FacesContext.getCurrentInstance();
 Map sessionState =
   ctx.getExternalContext().getSessionMap();

 sessionState.put("skinFamily", "mycompany");

6. Resetting the Session Attribute

To make the appearance of your application reproducable and recognizable, you should have a common skin for the login page. This means that you should reset the skin of your application. In my sample I reset the skin to the oracle skinFamily to leverage the default behaviour and to have neutral skin just for the login page. The code is as easy as in point 5:
 FacesContext ctx = FacesContext.getCurrentInstance();

 Map sessionState =

   ctx.getExternalContext().getSessionMap();


 sessionState.put("skinFamily", "oracle");

April 25, 2007

ADF Faces 10.1.3: Dynamic Menus w/ ADF Regions

While developing my application I reused a number of pages for different pages flows for different user roles. This resulted in the need for different sub menus (aka "menu2" facet in <af:panelPage>).

The Approach

Instead of putting the sub menu in every page, I've chosen to use <af:region> to reduce the code and be more flexible during the design. This region uses a member of the application's state bean. (An implementation detail of my application - see the SRDemo for a similar approach to store context information). The region itself retrieves the menu context and decides which menu to display.

Using a Region

Using a Region within a .jspx page is quite easy. Instead of your ADF Faces tags use the <af:region> tag to reference the specific region:

<f:facet name="menu2">
 <af:region id="menu2Region"
            regionType="demo.regions.menu2">
  <f:attribute name="create" value="false" />
 </af:region>
</f:facet>

Define a Region Mapping

To use a region we must tell ADF Faces where to find the definition of the region. This will be done in the WEB-INF/region-metadata.xml file.

<component>
 <component-type>demo.regions.menu2</component-type>
 <component-class>oracle.adf.view.faces.component.UIXRegion</component-class>
 <component-extension>
  <region-jsp-ui-def>/regions/subMenu.jspx</region-jsp-ui-def>
 </component-extension>
 <attribute>

  <attribute-name>create</attribute-name>
  <attribute-class>java.lang.String</attribute-class>
 </attribute>
</component>

This example also shows that a region can have parameters (or attributes) that are used within the region definition. You see the usage of parameters above.

Define a Region

Finally we define the region in a separate file which contains the complete tags we'd like to use.

<af:regionDef var="aParam"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:af="http://xmlns.oracle.com/adf/faces">
 <!-- ... -->
</af:regionDef>

Don't forget to define the namespaces in the <af:regionDef> tag to make JDeveloper Code-Insight happy.

The Dynamic Region Content

Essentially, you put every tag you want to use within the <af:regionDef> tag. To add a bit dynamic for the context-based menu display, I've put the <af:switcher> around my different versions of the menus. Every possible case is wrapped by a normal JSF <f:facet> tag.

<af:switcher defaultFacet="default"
 facetName="#{userState.menuContext}">

 <f:facet name="organisation">
  <af:menuBar>
   <af:commandMenuItem
    text="#{res['page.organisation.create']}"
    action="createOrganisation"
    rendered="#{!userState.patientRole}"

    immediate="true"
    selected="#{aParam.create == 'true'}"/>
  </af:menuBar>
 </f:facet>
 <!-- more facets here -->
</af:regionDef>

Please note, how I determine the current menu context from the application context bean with facetName="#{userState.menuContext}".

We also see how the parameters are used. As these are Strings we have to compare them with literal values.

Setting the Menu Context

When I change the main menu context, an action is called and sets the current menu context field in the application context bean. Here is a sample of the action:

public String organisationAction() {
  setMenuContext("organisation");
  return "GlobalOrganisation";
}

Since the navigation  rule for the menus is designed as a global outcome ("GlobalOrganisation"), I've placed this action in the application context bean, too.

Conclusion

This sample is a fast, usable, and easy to understand solution (important for co-workers, or when I have to maintain it in two weeks time). There are more flexible solutions in ADF Faces available, but often much harder to read, maintain, etc.

April 26, 2007

Creating XML Processing Instructions with XSLT

In a joint effort Clemens Utschig-Utschig and I did a small exercise to answer a question from one of our Oracle Partners:

How to create an XML processing instruction like <?Foo?> after the normal XML preamble <?xml?> but before the document root with XSLT?

Answer:
Before any other XSLT template have this one:
<xsl:template match="/">

 <xsl:processing-instruction name="Foo"/>

 <xsl:apply-templates />

</xsl:template>




This will generate something like this:
<?xml version="1.0" encoding="UTF-8"?><?Foo?>

About April 2007

This page contains all entries posted to Olaf Heimburger's Blog in April 2007. They are listed from oldest to newest.

March 2007 is the previous archive.

May 2007 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle