Year: 2014

List binding for selectOneChoice

In order to add a drop down box with a list of selectable values inside an af:tree or af:treeTable cell, an af:selectOneChoice component can be used:

<af:selectOneChoice id="soc1" 
                    value="#{node.bindings.ForeignKey.inputValue}"
                    autoSubmit="true">
    <f:selectItems id="si1" value="#{bindings.SelectionList.items}"/>
</af:selectOneChoice>

The two important attributes are the value attributes:

  • On the inner f:selectItems element, it defines the list binding which delivers the list of values to show in the drop down box.
  • On the af:selectOneChoice element, it defines the foreign key attribute from the current row (determined by node or row as set in the var attribute of the af:table or af:treeTable) which references the corresponding primary key from the selection list. The mapping between the foreign key and the primary key attributes is defined in the list binding in the respective pageDef file.
Now, there is one important detail to know about this list binding: When it is created automatically by JDeveloper when dragging an attribute from the Data Control panel onto the jsf page, the IDE automatically adds the attribute SelectItemValueMode="ListObject" to the list binding definition. This is absolutely crucial for the list binding to properly map foreign keys to primary keys. Without this attribute, the mapping is not done through the key mapping, but through the index of the entry in the selection list – thus, foreign key 2 would map to the second entry in the selection list (SelectItemValueMode="ListIndex" which is also the default if the attribute is missing). Now, the point is: This attribute is not added to the binding if we create the list binding manually through the bindings editor. The dialog which is shown when manually creating the list binding also does not provide the possibility to select one or the other value for the attribute. So, if we have created the list binding manually (which is sometimes convenient), it is automatically in mode SelectItemValueMode="ListIndex". In order to change it to ListObject, we need to manually change it in the property editor (or in the XML source code)! The same, by the way, happens for the DTSupportsMRU attribute of the list binding – when the binding is added by the IDE through drag&drop from the data control panel, this attribute is added automatically so that the list binding supports most recently used entries. When created manually through the binding editor, the attribute is not added – you need to add it manually in the XML code after the binding has been created.

Initializing Java collections and arrays during creation

Initializing collections with predefined values

Especially when writing unit tests or mock objects, it can be useful to initialize collections like Lists, Maps and Arrays with specific values. The usual way to do this is to instantiate the corresponding class and then add the values, e.g.

List<String> names = new ArrayList<>();
names.add("John");
names.add("Jack");
names.add("Greg");

However, when the collection is only required to be passed to a method as parameter, this adds a temporary reference variable to the current scope. In another scenario, it could be necessary to create a collection with predefined values as class members, and using the approach above would require the add() calls to be done in the class constructor (or in the instance initializer). For readability and maintainability, it would be better to add the default values at the same place where the member is defined. In any case, initializing collections in this way can be done using the “double brace initialization syntax”:

List<String> names = new ArrayList<String>() {{
      add("John");
      add("Jack");
      add("Greg");
   }};

Is this really a specific, probably new, Java syntax? Not really – lets rewrite it slighty:

List<String> names = new ArrayList<String>() {

   {
      add("John");
      add("Jack");
      add("Greg");
   }

};

It might be more obvious now – what we do is that we create an anonymous class as a sub class of ArrayList<String>. In that class, we create an instance initializer which is enclosed with the inner pair of braces. Syntactically this can be written as above, hence the name “double brace initializer”. One particular detail to consider is that the diamond operator can not be used with anonymous classes, so we need to explicitly name the type when instantiating a generic class. See https://stackoverflow.com/questions/13821586/why-cant-diamond-infer-types-on-anonymous-inner-classes for more details. Using this approach also allows to pass a readily initialized collection as a parameter to a method, without the need to create a temporary variable as in our introductionary example:

   public void processMap(Map map) {
      System.err.println(map);
   }

   public static void main() {
       processMap(new HashMap<String, Integer>() {{
             put("one",  1); 
             put("two",  2); 
             put("three",  3); 
          }});
   }

Initializing raw arrays with predefined values

Another common use case is to create a raw array with predefined values. When T is the array type, then the syntax for array initialization is:

T[] array = new T[] {val1, val2, val3, ..., valN};

This creates an array with N elements, initialized with the given values. The nice thing is that this syntax can also be used to initialize an array while passing it as parameter. Consider the following method:

public void processArray(int[] array) {
   System.err.println(Arrays.toString(array));
}

Then, when we want to pass an array with the values 1, 2, 3, we can simply call the method like this:

processArray(new int[] {1, 2, 3} );

The same works also with reference type arrays:

public void processArray(Date[] array) {
   System.err.println(Arrays.toString(array));
}

processArray(new Date[] {new Date(123456789012L), new Date(234567890123L), new Date(345678901234L)} );

Retrieving original hashcode of a Java object

For debugging Java applications, it is sometimes useful to know if two references point to the same or to different objects – this can be easily checked by evaluating the return value of hashCode() (the default implementation from java.lang.Object returns distinct integers for distinct objects). However, this might not work if hashCode() is overridden – in that case, hashCode() might return the same value for different objects to fulfill the equals() contract. In that case, it is still possible to retrieve the same hashCode() value as it would be returned by java.lang.Object if the hashCode() method was not overridden, by using System.identityHashCode() on this object:

public class Value {
    private int theValue;

    public Value(int val) {
        theValue = val;
    }

    @Override
    public int hashCode() {
        return theValue;
    }
	
    public static void main(String[] args) {
        Value value = new Value(42);
        System.err.println(value.hashCode());
        System.err.println(System.identityHashCode(value));
    }
}

Output:

42
1024180077