Java Reflection and Introspection example, Populating Dojo Filtering Selects.   2 comments

Reflection and Introspection are advanced java topics  used when building J2EE frameworks.  Often new developers find it difficult to understand what reflection is all about.  In this example I will show off a very basic example of reflection used to reduce boiler plate code for populating Dojo filtering selects. This also has the side affect of keeping the front end in an easy to understand consistent format that allows one to always set the dijit’s label=”label” and value=”value”.

First we should take a look at how to create a Dojo Filtering select. In this case we will generate it programmatically and attach it do a placeholder dom node that would exist in a JSP file.  The key thing here is that a filtering select has both a value and label for each item it contains.  We will populate the filtering select using a Memory Store to hold the JSON data.

  1. First we create the filtering select and replace an existing dom node with it.
  2. We create a method that will make an ajax call to populate the memory store and then assign the store to the filtering select.
  3. In this case the method returns a promise such that we can chain other events to it.

This code will generate a filtering select and replace an existing dom node with the newly created dojo.form.filteringselect
*note this code exists within a dojo module so it is only partial source. We will call the module

 var stateDropdown = new FilteringSelect({
        id: "states",
        // the text to appear in the filtering select dropdown that has no value
        placeHolder:"Select an Option",
        style : "width: 35em",
       	// the attribute the filtering select will use to auto complete the value
        searchAttr: "label",
        labelAttr: "label",
        // the attribute that will display in the dropdown
        itemLabel: 'label',
        // the attribute that will be recorded when a value is selected
        itemValue: 'value',
	// the name of the property that will be submitted with the form.
        name: "state",
        disabled: true
      }, dom.byId("IDofTheTargetDomNodeToReplaceGoesHere"));

Then we will create a dojo xhr (ajax) call to populate the filtering select above. *Note the code isn’t much but my comments are verbose.

   function populateStates() {
       // using the deferred as a promise for chaining events
           var aPromise = new Deferred();
               var stateDropdown = dijit.byId("states");
           // Creating an animation to let the user know the form is still loading.
           var standby = new Standby({target: domAttr.get(stateDropdown.domNode, 'id')});
           document.body.appendChild(standby.domNode);
           standby.startup();
           standby.show();
 
           // create the xhr ajax call to the server 
           xhr(populateStatesUrl, {
               handleAs: 'json',
                   query: {    country : "USA" }
             }).then(function(resp) {
             // if your using dojo 1.6 you may need to wrap this memory store in an object store.
             // this creates a new dojo memory store that will contain data from the json response 
             // and assignes it to the widget
               stateDropdown.set('store',new MemoryStore({
                               data: resp,
                               idProperty: "value"
               }));
           // let the user know we are finished populating the dropdown.
           standby.hide();
               // resolve the promise when we are finished populating the filtering select.  
               // This will chained method calls to execute.
           aPromise.resolve(true);
           });
           return aPromise;
       }

It might be helpful to understand what the JSON should look like that will be stored in the memory store.  Basically it just needs to be an array of object items with key value pairs.

[
    {
        "name": "Alabama",
        "abbreviation": "AL"
    },
    {
        "name": "Alaska",
        "label": "AK"
    },
    {
        "label": "American Samoa",
        "value": "AS"
    },
    {
        "label": "Arizona",
        "value": "AZ"
    },
    {
        "label": "Arkansas",
        "value": "AR"
    },
    {
        "label": "California",
        "value": "CA"
    },
    {
        "label": "Colorado",
        "value": "CO"
    },
    {
        "label": "Connecticut",
        "value": "CT"
    },
    {
        "label": "Delaware",
        "value": "DE"
    },
    {
        "label": "District Of Columbia",
        "value": "DC"
    },
    {
        "label": "Federated States Of Micronesia",
        "value": "FM"
    },
    {
        "label": "Florida",
        "value": "FL"
    },
    {
        "label": "Georgia",
        "value": "GA"
    },
    {
        "label": "Guam",
        "value": "GU"
    },
    {
        "label": "Hawaii",
        "value": "HI"
    },
    {
        "label": "Idaho",
        "value": "ID"
    },
    {
        "label": "Illinois",
        "value": "IL"
    },
    {
        "label": "Indiana",
        "value": "IN"
    },
    {
        "label": "Iowa",
        "value": "IA"
    },
    {
        "label": "Kansas",
        "value": "KS"
    },
    {
        "label": "Kentucky",
        "value": "KY"
    },
    {
        "label": "Louisiana",
        "value": "LA"
    },
    {
        "label": "Maine",
        "value": "ME"
    },
    {
        "label": "Marshall Islands",
        "value": "MH"
    },
    {
        "label": "Maryland",
        "value": "MD"
    },
    {
        "label": "Massachusetts",
        "value": "MA"
    },
    {
        "label": "Michigan",
        "value": "MI"
    },
    {
        "label": "Minnesota",
        "value": "MN"
    },
    {
        "label": "Mississippi",
        "value": "MS"
    },
    {
        "label": "Missouri",
        "value": "MO"
    },
    {
        "label": "Montana",
        "value": "MT"
    },
    {
        "label": "Nebraska",
        "value": "NE"
    },
    {
        "label": "Nevada",
        "value": "NV"
    },
    {
        "label": "New Hampshire",
        "value": "NH"
    },
    {
        "label": "New Jersey",
        "value": "NJ"
    },
    {
        "label": "New Mexico",
        "value": "NM"
    },
    {
        "label": "New York",
        "value": "NY"
    },
    {
        "label": "North Carolina",
        "value": "NC"
    },
    {
        "label": "North Dakota",
        "value": "ND"
    },
    {
        "label": "Northern Mariana Islands",
        "value": "MP"
    },
    {
        "label": "Ohio",
        "value": "OH"
    },
    {
        "label": "Oklahoma",
        "value": "OK"
    },
    {
        "label": "Oregon",
        "value": "OR"
    },
    {
        "label": "Palau",
        "value": "PW"
    },
    {
        "label": "Pennsylvania",
        "value": "PA"
    },
    {
        "label": "Puerto Rico",
        "value": "PR"
    },
    {
        "label": "Rhode Island",
        "value": "RI"
    },
    {
        "label": "South Carolina",
        "value": "SC"
    },
    {
        "label": "South Dakota",
        "value": "SD"
    },
    {
        "label": "Tennessee",
        "value": "TN"
    },
    {
        "label": "Texas",
        "value": "TX"
    },
    {
        "label": "Utah",
        "value": "UT"
    },
    {
        "label": "Vermont",
        "value": "VT"
    },
    {
        "label": "Virgin Islands",
        "value": "VI"
    },
    {
        "label": "Virginia",
        "value": "VA"
    },
    {
        "label": "Washington",
        "value": "WA"
    },
    {
        "label": "West Virginia",
        "value": "WV"
    },
    {
        "label": "Wisconsin",
        "value": "WI"
    },
    {
        "label": "Wyoming",
        "value": "WY"
    }
]

Onto the backend code. There’s many ways to create the required JSON data in the backend. I like Jackson and REST so we for this example assume those technologies are being used in a rest services to handle the front end’s ajax call. The object returned from the rest service will be converted to a JSON representation automatically for us. The Objects returned to populate dropdowns will be lists of labels and values.

In order to generate JSON like the example above, such an item in the list would look something like this.

Pretty simple right? The annoying thing is populating a list of these objects using properties from other POJOS. What we want to do is create something using reflection and introspection that will handle this conversion for us. So we will use generics and create an object that contains a list of objects that have “value” and “label” members. This object will generate it’s own list based on the type of list you pass in, and the member variables names you want to map to “value” and “label”.

Now onto the Java Reflection and Introspection and Generics. We will create a class of a generic class called DropDownListBean that contains a list of the DropDownItemBeans which hold the key value pairs. The constructor for this object will take in a list of any type, along with the names of the properties that we want to use to map the “value” and “label” to. The class will use reflection to create method calls and populate it’s own list of items with “value” and “label” members.
(its internal list of DropDownItemBeans).

The method call to create the DropDownBean would look something like this:

DropDownBean<State> stateDropDownBean = new DropDownBean<>(stateList, abbreviation, fullName);

Where the state objects in teh stateList (not shown) have member variables “private String abbreviation;”, and a getter methods “public String getAbbreviation()… “, as well as member variables “private String fullName;” and methods “public String getFullName()…” Basically any object that follows the JavaBean standards should work. (With the exception of boolean methods which start with ‘is’)

This allows us to create a list of objects that can be used to populate a Dojo MemoryStore in one line assuming the rest service would do the object to json conversion for you, and that the rest service returns DropDownBean.getDropDownItems();

Advertisements

Posted March 7, 2014 by javasavy in Dojo, Java, Javascript, Programming

2 responses to “Java Reflection and Introspection example, Populating Dojo Filtering Selects.

Subscribe to comments with RSS.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: