You are here: Home ยป Blog

This tutorial shows how to expose a plain Java Bean as a Data Control, and how to create a user interface from this Data Control. The sample use case is to show the current time depending on a timezone which can be selected from a drop down list.


In JDeveloper, the integrated weblogic server creates its runtime domain in a directory like $HOME/.jdeveloper/system12.1.3.0.41.140521.1008/DefaultDomain or $HOME/.jdeveloper/system/11.1.1.7.40.65.57.5/DefaultDomain.

While $HOME and the fixed DefaultDomain are well known, it is not so easy to determine the actual name of the system directory - one could assume that there is only one and use system* as the name, but there could be more than one, especially if more than one JDeveloper version is installed at the same time and each of them had been creating its own WLS domain. What we actually need is to get the JDeveloper version since that is what is used in the system directory name.

Assumed that $JDEV_HOME is the installation directory of the JDeveloper installation for which we would like to get its domain home directory (like /opt/Oracle/Middleware/Oracle_Home/jdeveloper), then the file $JDEV_HOME/jdev/bin/version.properties contains the full version number of JDeveloper, which is identical to the version number used in the system directory name:

$ grep VER_FULL $JDEV_HOME/jdev/bin/version.properties
VER_FULL=12.1.3.0.41.140521.1008

To extract the version number, we can use a simple sed script like

$ sed -n 's/^VER_FULL=\([0-9.]*\).*$/\1/p' $JDEV_HOME/jdev/bin/version.properties
12.1.3.0.41.140521.1008

(we need to make sure not to include the terminating line feed, hence we only collect digits and dots after the =).

Finally we can now generate the complete directoy path to the domain directory:

$ JDEV_VER=`sed -n 's/^VER_FULL=\([0-9.]*\).*$/\1/p' $JDEV_HOME/jdev/bin/version.properties`
$ DOMAIN_HOME="${HOME}/.jdeveloper/system${JDEV_VER}/DefaultDomain"
$ ls $DOMAIN_HOME/servers
AdminServerTag  DefaultServer

This can be useful for any kind of automation tasks.


Implementing a custom EL resolver in ADF

Posted on Thursday, January 15 2015 at 08:05 | Category: Oracle ADF & JDeveloper | 0 Comment(s)

New tutorial available: Implementing a custom EL resolver in ADF shows how to implement, register and use a custom EL resolver in Oracle ADF.


Runtime-defined properties in EL expressions

Posted on Monday, January 12 2015 at 08:47 | Category: Oracle ADF & JDeveloper | 1 Comment(s)

Expression Language (EL) is used to access application logic (Managed Beans) from the presentation logic (JSF pages and page fragments). Assume that we have a class called com.example.SomeBeanImpl which is registered as a managed bean called someBean. Then, an expression like #{someBean.someProperty} essentially calls the getSomeProperty() method of the com.example.SomeBeanImpl class whenever the expression is used in a read operation, and calls the setSomeProperty() method of the com.example.SomeBeanImpl class whenever the expression is used in a write operation. Note that this requires that there are explicit setter and getter methods for each property accessible from an EL expression. If the expression tries to access a property for which there is no corresponding getter or setter, an exception is thrown.

So, adding the getters and setters for the properties is a compile time operation - the class needs to contain the required methods. However, for some scenarios, it might be useful to be able to define properties at runtime. In fact, the ADF engine does this in several places - one example are the "row" or "node" variables for the <af:table> or <af:treeTable> components to reference one row of a table or a tree table. Even though there is one specific java class used inside the ADF runtime which represents one row or node, it is possible to access all of the table's attributes through those classes (and the ADF runtime does not synthesize any specific classes during build- or runtime):

<af:table value="#{myManagedBean.allEmployees}"  
          var="emp">    <!-- Internally, instanciates a class used as the container for one row -->
  <af:column>
    <af:outputText value="#{emp.ename}"/>   <!-- Accesses the "ename" property of the row -->
  </af:column>
  <af:column>
    <af:outputText value="#{emp.deptno}"/>  <!-- Accesses the "deptno" property of the row -->
  </af:column>
</af:table>

In this example, we can access the ename and the depto properties of the row container class, even through this internal container class will certainly not have corresponding getters and setters available (as their names depend on the attributes of the associated view objects). ADF internally further routes those accesses to the proper view object rows.

EL Resolvers

The J2EE concept which allows such "dynamic" beans with properties defined at runtime is called "EL Resolvers". Essentially, the EL engine is using EL resolvers each time it needs to evaluate an expression. For example, by default there is a BeanELResolver which resolves properties which correspond to the JavaBeans specification, using getter and setter methods as described above. However, there are also other resolvers like MapELResolver which can access properties which are stored in a Map, and it is also possible to define custom EL resolvers to implement a custom property resolver for more unique requirements. Resolvers can be chained together by using a CompositeELResolver - the CompositeELResolver iterates over all its resolvers until one resolver was able to evaluate the expression.

The Java EE 5 Tutorial: EL Resolvers  gives additional information and shows a list of standard resolvers. The JavaServer Pages Specification, chapter JSP2.9: Resolution of Variables and their Properties describes the resolution process in more detail and shows the order in which the CompositeELResolver resolves properties by default. The JavaDoc at http://docs.oracle.com/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/el/ELResolver.html describes the Java classes used in the EL resolvers API.

Example

A simple approach to implement beans with runtime properties as described above is to have the managed bean implement the Map interface. This lets the default CompositeELResolver use the MapELResolver to resolve its expressions. According to 5 Reasons to Use Composition over Inheritance in Java and OOP, we will not inherit from a container class, but implement the required interface and then delegate to a HashMap instance:

public class DynamicPropertyBean implements Map<String, Object> {
    public DynamicPropertyBean() {
        put("value1", 42L);
        put("value2", "Hello");
    }

    private Map<String, Object> theMap = new HashMap<>();

    @Override
    public int size() {
        return theMap.size();
    }

    @Override
    public boolean isEmpty() {
        return theMap.isEmpty();
    }

    ... 
    // All additional required methods from the Map interface
    ...
}

If this bean is registered with the name dynamicBean, we can access the properties "value1" and "value2" like #{dynamicBean.value1} and #{dynamicBean.value2}. All other property names will return an empty value - there will be no exception thrown, and the CompositeELResolver will also not try any other resolver further down in the chain, such as BeanELResolver, to resolve the property name. If we want to catch accesses to unknown properties, we either need to further tweek the methods which implement the Map interface (instead of simply delegating), or implement a custom EL resolver.


Displaying results 1 to 4 out of 21
<< First < Previous 1-4 5-8 9-12 13-16 17-20 21-21 Next > Last >>