Saturday, April 28, 2007

Comparison using Java's ternary operator

When using Java's ternary operator which allows assignment to a variable based upon one or more Boolean decisions, construct the code in such a way as to mitigate null exception errors.

For example, in the event the field “verified” contains a null value, the following construct results in a null exception error:


boolean verifiedAsBoolean = "Y".equalsIgnoreCase(verified) ? true : false;


This version will return false.


boolean verifiedAsBoolean = verified.equalsIgnoreCase("Y") ? true : false;


Although acceptable, consider employing a basic if / then construct. The test example below will not fail if verified contains a null and will return false. The construct also allows new logic to be to implemented more efficiently.

If ('Y'.equals(verified)) {
verifiedAsBoolean = true;
} else {
verifiedAsBoolean = false;
}

Wednesday, April 25, 2007

Eclipse tip - Showing more projects in prompt




You can specify that during Eclipse’s startup phase Eclipse should provide a prompt to allow you to select from a list the project you want to work with. By default, this list is limited to showing the last 5 projects you used. Here, I will explain how to specify that the prompt should be shown and how to change the default setting which governs the number of projects in the list.

Showing the prompt.

Once Eclipse is presented, select the following menu path:
Window -> Preferences…

The Preferences Wizard will be presented. From the list provided on the left select:
General, Startup and Shutdown.

Check the option labeled as “Prompt for workspace on startup”. Click the “Apply” then the “Ok” button.

Now, end Eclipse. This is important because if Eclipse is left running you will not be able to edit the file being discussed in the next step.


Changing the default number of projects in the project select list.

Using Windows Explorer, locate the parent directory for your current Eclipse installation, then locate the “configuration” directory and finally the “.settings” directory. For example, my Eclipse instance (Version 3.1.0.) is installed in “Eclipse310”. So the path we want is


“C:\Eclipse310\eclipse\configuration\.settings”.


In the “.settings” directory there is a file named “org.eclipse.ui.ide.prefs”. Open it with your favorite text editor. Here are the contents:


#Fri Mar 31 07:34:04 CST 2006
RECENT_WORKSPACES_PROTOCOL=2
MAX_RECENT_WORKSPACES=10
SHOW_WORKSPACE_SELECTION_DIALOG=true
eclipse.preferences.version=1
RECENT_WORKSPACES=C\:\\Desk\\AppDevJava\\HibernateWorkspace,
C\:\\Desk\\AppDevJava\\DAOGenWorkspace,
C\:\\Desk\\AppDevJava\\TableTestWorkspace,
C\:\\Desk\\AppDevJava\\Development\\TableTests


The line we want to change is the one containing this “MAX_RECENT_WORKSPACES”.

As you can see, it has been changed from the default value of 5 to 10. Change the value for yours to oh, say 15 for example, and save.

Now, the next time you start Eclipse, you will be prompted to select from a list of 15 entries the project you wish to work with.

Monday, April 23, 2007

Reconciling ArrayList contents with the Comparator class

For the current project requiring enhancements to be made to a JSF-based web application, I had to determine what was changed by the user and then write the changes identified into a new table for reporting purposes – an activity journal.

The page had the usual input text boxes and a list-box into which entries as seen within a companion list-box could be selected to add those selections to the second list-box. When the user removed items from the list-box, they were returned to the companion list-box. The problem was to capture those events as “adds’ or “deletes”.

The solution uses two ArrayLists. The first (named “preservedSelectedValues”) holds the list of items in a list-box BEFORE changes. The second (named “selectedValues”), holds the list of items in that list-box after changes. Both ArrayLists hold those entries as SelectItem objects.

Since I need to know what was added to or deleted from the list-box represented by the second ArrayLists it can be treated as a simple reconciliation problem. The brute force code, reeking of COBOL or RPG approaches, is represented here:


//Capture changes.
if (preservedSelectedValues.size() >= selectedValues.size()) {
int foundCount = 0;
for (int i=0; i < preservedSelectedValues.size(); i++) {
boolean found = false;
SelectItem psi = (SelectItem)preservedSelectedValues.get(i);
for(int j=0; j < selectedValues.size(); j++){
SelectItem si = (SelectItem)selectedValues.get(j);
//Found - No change
if(psi.getLabel().equals(si.getLabel()) ) {
found = true;
foundCount++;
break;
}
}
//The item was deleted
if (!found ) {
System.out.println("Deleted : " + psi.getLabel() + " " + psi.getValue());
}
}
if(preservedSelectedValues.size() == foundCount) {
System.out.println("No changes were detected.");
}
if(preservedSelectedValues.size() > foundCount) {
System.out.println("Some items have been deleted.");
}
}

if (selectedValues.size() >= preservedSelectedValues.size()) {
int foundCount = 0;
for (int i=0; i < selectedValues.size(); i++) {
boolean found = false;
SelectItem psi = (SelectItem)selectedValues.get(i);
for(int j=0; j < preservedSelectedValues.size(); j++){
SelectItem si = (SelectItem)preservedSelectedValues.get(j);
//Found - No change
if(psi.getLabel().equals(si.getLabel()) ) {
found = true;
foundCount++;
break;
}
}
//The item was added
if (!found ) {
System.out.println("Added : " + psi.getLabel() + " " + psi.getValue());
}
}
if(selectedValues.size() == foundCount) {
System.out.println("No changes were detected.");
}
if(selectedValues.size() > foundCount) {
System.out.println("Some items have been added.");
}
}


The better way is to create a comparator class which has dual responsibilities. The first responsibility is to act as a comparator to assist in sorting the ArrayLists. The second responsibility is to assist in the comparison for differences between the ArrayLists. The comparator class accepts 2 objects and then casts them to SelectItem objects to perform compares against the value properties. The returned value from this exercise is an integer reporting whether it was found to be less than, equal to or greater than. The comparator:


/**
* Modification History
*
* Date Project Pgmr Description
* -------- --------- ------- -----------------------------------------------
*
*
*/
package com.util;

import java.util.Comparator;

import javax.faces.model.SelectItem;


public class SelectItemComparator implements Comparator {

String name = this.getClass().getName();

/**
* Constructor
*
*/
public SelectItemComparator() {
super();
}

/**
* Compares the suppled SelectItem objects to each other. This method is used
* to resolve sorts and to determine equality.
*
*/
public int compare(Object o1, Object o2) {
SelectItem s1 = (SelectItem)o1;
SelectItem s2 = (SelectItem)o2;
return s1.getValue().toString().compareTo((s2.getValue().toString()));
}

}




The implementation does the sort followed by the comparison operations. The sprit is the same as the first set of code shown at the top of this post.

//Capture changes. First, sort the arraylists containing the SelectItem objects
Collections.sort(preservedSelectedValues, new SelectItemComparator());
Collections.sort(selectedValues, new SelectItemComparator());

//Second, perform the compares
for (int i=0,size=preservedSelectedValues.size(); i < size; i++) {
SelectItem psi = (SelectItem)preservedSelectedValues.get(i);
int pos = Collections.binarySearch(selectedValues, psi, new SelectItemComparator() );
if (pos<0) {
System.out.println("Comparator method. Deleted : " + psi.getLabel() + " " + psi.getValue());
}
}
for (int i=0,size=selectedValues.size(); i < size; i++) {
SelectItem si = (SelectItem)selectedValues.get(i);
int pos = Collections.binarySearch(preservedSelectedValues, si, new SelectItemComparator() );
if (pos<0) {
System.out.println("Comparator method. Added : " + si.getLabel() + " " + si.getValue());
}
}



There. Much better.