Lecture 11

Reflection & more Java Beans

Last lecture we learned quite a lot about Java component based architecture called JavaBeans.
JavaBeans are customizable components written in Java which can be configured and used in many
different applications. JavaBeans have to adhere to certain coding and interaction standards.
Lets look at the diagram below to summarize what we've seen so far

In addition to this we saw that how we can serialize beans using Java built-in serialization mechanism. Now the issue we need to look at is how do we actually know what properties are supported by a bean? Before we answer this question, we need to digress for a moment and take a look at java.lang.reflection. The reflection package offered in Java allows us to get access to class fields and methods. You will see that this addition makes Java incredibly powerful and dynamic. Lets take a look at the following code

If you create main and run this, the result would be

Etc. So as you can see, reflection allows us to get all the methods of ANY Java class. Look into its
return types, parameters and exception. Similarly we can look up class Fields and Constructors.
Now if you think that this is cool, this is not it yet. We can also INVOKE methods dynamically.
This is super useful. You will see why pretty soon. For now, lets take a closer look at classes and
interface found in the reflection

Here is the example which illustrates how to invoke a method dynamically

We match set method, then form array of arguments (notice how array is declared and initialized), then we just simply call invoke on the instance the Method and pass to it a target (which is always an object of a class or subclass which has this method) and an argument array. So this is what Java reflection allows us to do.
We will see how powerful this can be shortly.

Now we are coming back to the question that we asked earlier about beans: How do we know
what properties and methods are supported by a bean? The answer to this question is offered
within java.beans package. The creator of a bean has an option of providing description of a bean
in the form of Bean Info class. BeanInfo class contains meta information about the bean. It is
really good idea to factor it out. The bean maybe easily used without BeanInfo. Usually
BeanInfo is useful only to GUI builders. BeanInfo contains a lot of information about a bean
(almost always, much more that we want to know :). BeanInfo allows users to learn about
Bean properties, events, methods and much more.


Lets work our way through this Interface. First of all, all the way on the bottom we see
Method and Property descriptors. Both of these are Feature Descriptors. The
FeatureDescriptor class is the common base class for descriptors. It supports some
common information that can be set and retrieved for any of the introspection descriptors.
In addition it provides an extension mechanism so that arbitrary attribute/value pairs can
be associated with a design feature.


Note that FeatureDescriptor provides additional flexibility by offering bean creators to store
any kind of name value pairs. This means that if the descriptor user knows about them as well, they can be retrieved and used in any manner. isExpert in the FeatureDescriptor class means that this
property or method or event should be displayed only for expert users. This is very convenient because
a lot of GUI builders today try to minimize the amount of things that programmers need to fill in.
In the MethodDescriptor, we see getMethod which simply returns us a handle to the method and
we can access array of descriptors of parameters of this method. PropertyDescriptor also make sense.
We see that we can discriminate between bound and constrained properties, get property type and
its read and write methods.

Another class which also extends FeatureDescriptor is BeanDescriptor, which is also returned by
BeanInfo. This describes bean as a whole. Also offered by BeanInfo default property index and
default event index, this is also done for the sake of GUI builders. Finally, BeanInfo allows user to
access all icons associated with the bean. Okay, so this is great, but who wants to do all of this?
Certainly programmers are too important to create BeanInfo. One step towards making our life
easier is offered by SimpleBeanInfo class. This is an adapter class much like AWT adapters.
It simply implements BeanInfo interfaces by having empty methods.
This is helpful because if we extend from SimpleBeanInfo, we can override only the once
that we want. Still, there is work to be done. Now, Introspection to the rescue! java.beans packages
comes with the class called Introspector. This class offers static method getBeanInfo given a class,
which goes into a class definition and does its best at finding out all the contained information.
Here is how it works:

The output looks like this

In exactly the same fashion we could have fetched all other information which is contained
in the BeanInfo. Obviously when Introspector creates a bean it will not be able to provide
meaningful strings of descriptions of methods and field, but this is not too bad.

Let us see how this can be applied to our project. Consider the following extract from the EworldConfig file

<RENDERER CLASS=edu.nyu.sejava.iskold.eworld.sites.DesertRnd>
<PROPERTY NAME=X VALUE=0/>
<PROPERTY NAME=Y VALUE=0/>
<PROPERTY NAME=Height VALUE=100/>
<PROPERTY NAME=Width VALUE=100/>
</RENDERER>

We can create instance of an appropriate renderer (DesertRnd in this case) and then use
Introspectorto find appropriate setMethod and then simply INVOKE it! Thus our code which
walks through the parsed tree instantiates objects and sets attributes can be completely generic!
So what do we need to do? Given an object and property name we need to find its write (set)
method. To do this we create a utility class called BeanUtilities. BeanUtilities offers several
convenient static methods for extraction information out of the BeanInfo. Here is the method that
allows us to get a property descriptor for a property

Now using the above method we can provide locators for read(get) and write(set) methods like this

So now given any object which we instantiate based on the config file, we can find the set
method for a given property. There is only one issue that needs to be taken care of - type conversion.
We need to be able to handle these

<RENDERER CLASS=edu.nyu.sejava.iskold.eworld.sites.DesertRnd>
<PROPERTY NAME=Label CLASS=java.lang.String VALUE=Hello/>
<PROPERTY NAME=Height CLASS=java.lang.Integer VALUE=100/>
<PROPERTY NAME=Width CLASS=java.lang.Integer VALUE=100/>
</RENDERER>

Furthermore, we would like to avoid putting class in properties whenever possible,
we just want to say this

<RENDERER CLASS=edu.nyu.sejava.iskold.eworld.sites.DesertRnd>
<PROPERTY NAME=Label VALUE=Hello/>
<PROPERTY NAME=Height VALUE=100/>
<PROPERTY NAME=Width VALUE=100/>
</RENDERER>

and somehow the magic should happen.

Remember that we just wrote a routine which allows us to get setMethod of a property.
This set method will contain the description of its arguments, along with types. Thus we can
deduce what type of property do we need to create.

We are now ready to find out about another clever engineering concept ingrained into beans -
Property Editors. At the very least, property editor is a factory that knows how to convert
objects of particular type back and forth between object and string representation.
For example an IntPropertyEditor knows how convert between integers and strings.
Here is what Sun API says about property editors:

Now lets take a look at PropertyEditor interface and implementation of ColorPropertyEditor

Property editors are found via PropertyEditorManager. With the following two methods we can now
convert string value to correct method argument:

We are now ready to write generic code that walks through tag tree and builds actual objects.