Thursday, October 1, 2015

Creating JSON objects in Java using the JSON.simple toolkit

I needed a way to create JSON objects in Java for displaying in a grid. There are several options for doing this that I could have chosen. There is GSON from Google, or I could roll my own using StringBuilder. After doing some research, I decided to use the JSON.simple toolkit because, the examples looked simple and straightforward to me.  In this post, I will explain how I used JSON.simple and give two real life examples.


Installation

To use JSON.simple you need to download the jar and add to your build path. The jar is available here: https://code.google.com/p/json-simple/


Creating a Single Object


In this snippet, contents of a NotesDocument are added to a JSON object and then that object is passed back to the caller of the method. Note this example uses the Name class from the original Notes,jar to format the Notes name. It is the java version of @Name.

Document doc = col.getFirstDocument();
JSONObject json = new JSONObject();

if(doc != null){
   Name name = session.createName(doc.getItemValueString("EmployeeName"));
   json.put("employeeName", name.getCommon());
   json.put("employeeID", doc.getItemValueString("EmployeeID"));
   json.put("employeeLocation", doc.getItemValueString("locationdesc"));
   json.put("employeeRole", getEmployeeRole(name.getCommon()));
}
returnValue = json.toJSONString();
...
return returnValue;

The result will look something like this:

{"employeeLocation":"Pensacola Milton","employeeRole":"Intern to the Intern","employeeID":"12345","employeeName":"Dwain Wuerfel"}


Creating a Collection of Objects


In this snippet, the contents of a multi-value document are traversed and a JSON object is created for each item. Many will recognize that I am grabbing the members of a Name & Address Book group. For each member I create a new object and then that object is added to a JSONArray object called ‘result’ which is then returned to the calling method. Each object will be a displayed on a separate row in the grid.

JSONArray result = new JSONArray();

if(nabDoc != null){
   Item item = nabDoc.getFirstItem("Members");
   Vector<String> v = item.getValues();

   for(String person : v){
   Name name = session.createName(person);

   JSONObject json = new JSONObject();
   json.put("employeeName", name.getCommon());
   json.put("employeeRole", employeeRole);
   json.put("employeeID", EmployeeID);
   json.put("employeeLocation", EmployeeLocation);
   result.add(json);
}
returnValue = result.toJSONString();
...
return returnValue;

The result will look like this if there are three JSON objects in the array:

 [{"employeeLocation":"Pensacola Milton","employeeRole":["Minion"],"employeeID":"12345","employeeName":"Dwain Wuerfel"}, {"employeeLocation":"Pensacola Milton","employeeRole":["Blog Author"],"employeeID":"91984","employeeName":"Steve Zavocki"},{"employeeLocation":"Pensacola Milton","employeeRole":["Cast Member"],"employeeID":"54321","employeeName":"Vernon Miles"}] 

Conclusion


As the name implies the JSON.simple toolkit is simple to use, and a good option to consider if you need to create JSON objects within your java code. In case you are interested in learning more about your other options, here is an article that compares three different json toolkits including JSON.simple.

Monday, September 21, 2015

Sorting a Java ArrayList of SelectItem Objects

Recently I had a task where I needed to read all the names from several groups in the Name & Address Book.  I needed to get all the names sorted and unique for presenting in a Combobox.

In this post, I will show you how I did this, but more importantly I will show how I used the Java Collections Framework to my advantage.

In case you aren’t aware, the SelectItem object is the object type that Java Server Faces (thereby XPages) uses for the values of a Combo Box. It contains a value and a label, of which the label is what is shown and the value is what is saved.

Because the SelectItem does not implement the Comparator interface, you cannot easily sort an ArrayList of SelectItems. You could write your own sorting method if you like using the instructions outlined in this blog post. I considered this but then thought of an easier way to accomplish the same thing.

Here is what I did to solve this: Instead of creating just an ArrayList of SelectItems, I also created one of Strings. Strings of course are easily sortable since the String class does implement Comparator interface. Prior to sorting the list, I need to removed duplicates. To do this, I first create a HashSet and assign the values to it. A Set in java does not allow duplicates, so assigning all the values to the HashSet was the easiest way to remove the dupes. After this is done, I assign all the values back into the ArrayList and then sort the list. I then create an SelectItem ArrayList with the unique sorted values.

Note: This would be a lot more complicated if I needed my SelectItem object to have different Strings for Label and Value. I would probably use a HashMap instead of an ArrayList<String> if this was the case.

Code Example


public List<SelectItemgetUserList(String schema){ 
1  List<String> options = new ArrayList<String>(); 
List<SelectItemsortedOptions = new ArrayList<SelectItem>();

try { 
  Session session = getCurrentSession(); 
  Database nab = session.getDatabase(session.getCurrentDatabase().getServer(), "names");

if (nab.isOpen()) { 
View view = nab.getView("Groups"); 
if (view != null) { 
Document doc = view.getDocumentByKey("Group 1"true); 
if (doc != null) { 
Item item = doc.getFirstItem("Members"); 
Vector<String> v = item.getValues(); 
for(String person : v){ 
Name name = session.createName(person);  options.add(name.getCommon()); 
} 
doc.recycle(); 
item.recycle(); 
else { 
log.error("Group 1 cannot be opened."); 
} 
doc = view.getDocumentByKey("Group 2"true); 
if (doc != null) { 
Item item = doc.getFirstItem("Members"); 
Vector<String> v = item.getValues(); 
for(String person : v){ 
Name name = session.createName(person); 
options.add(name.getCommon()); 
} 
doc.recycle(); 
item.recycle(); 
else { 
log.error("Group cannot be found, or opened."); 
} 
……………… //get names from third group 
} 
else { 
log.error("Address Book is not found, or able to be opened."); 
} 
catch (NotesException e) { 
log.error("EXCEPTION in getUserList(): " + e.toString()); 
e.printStackTrace(); 
} 

Set<String> hs = new HashSet<String>();
hs.addAll(options); 
options.clear(); 
options.addAll(hs); 

Collections.sort(options); 

for(String person : options){  
SelectItem option = new SelectItem(); 
option.setLabel(person); 
option.setValue(person); 
sortedOptions.add(option); 
} 
return sortedOptions; 
}

Code Explanation using footnotes:


1  - Declare two ArrayLists, one for Strings, and one for SelectItems.

2  - The values of a multi-value field are returned as a Vector. For each item in the Vector, I assign the item into the String ArrayList

3 - This uses the Name class to get the formatted name. This is part of the original Notes API for java, and is quite useful.

4 -  This is where I pass the contents of the String ArrayList into a HashSet and then back again. All Sets in Java are not able to contain duplicate values. 

5 - After the duplicates are removed, then I sort the list. If you try to sort before removing duplicates it won't be sorted after changing to a Hashset and back. As you can see, sorting a String List is very easy using the Collections class.

6 -  Lastly, I convert the ArrayList of Strings into an ArrayList of SelectItems for use in my combo box.

Last Words


In Java the Collections Framework is super useful and one of the strengths of the language. If you are learning Java it would wise to pay special attention to knowing what it can do for you.  

Please check comments of this post for some great tips on how to improve on what I posted.