A Legacy Notes Developer's journey into madness.

A very brief introduction to Expression Language

Devin Olson  November 6 2014 01:31:06 PM
It has been a while since my last post, and I thought i would break the silence with a fun little excursion into the Expression Language Processor.  

I will follow this up with a subsequent post which may or may not be called the "What #&$%ing Broke Now?" lesson.   But I digress...


A bit of a primer on EL (Expression Language) and Java is in order.  

Expression Language


"A primary feature of JSP technology version 2.0 is its support for an expression language (EL). An expression language makes it possible to easily access application data stored in JavaBeans components. For example, the JSP expression language allows a page author to access a bean using simple syntax such as ${name} for a simple variable or ${name.foo.bar} for a nested property."  -- Oracle's J2EE Tutorial

Ok, that seems a bit confusing.  For now, for this post, all we really need to know about EL is that it allows us to grab a property from a back-end Java object (or Bean) by just referencing the property getter method, without using the get prefix.

Hmmm. that is a bit complicated as well. Here, let me try a simple example. Say I have the following class:

public class Lectroid {
 public static enum COLOR { RED, BLACK }

 private final COLOR _color;

 public Lectroid(final COLOR color) {
     this._color = color;
 }

 public COLOR getColor() {
     return this._color;  
 }

 public String getColorName() {
     return this.getColor().name();
 }
}  


Let us also say I have created an instance of class Lectroid and made it available to my XPage (either as a Data Source or a Bean):


Lectroid JohnSmallBerries = new Lectroid(COLOR.RED);


I can now display the color name of my Lectroid object on my XPage using Server Side Java Script (SSJS):


<xp:text
 escape="true"
 id="text1"
  value="#{javascript:JohnSmallBerries.getColorName()}" />
 

This is pretty cool, and goes to the heart of XPages -I can reference Java Object methods from an XPage, cause those methods to run, and retrieve data from the object.  

The only downside about this is the SSJS I am using.  Yes, it works, and yes, it does what I need, but the truth is that SSJS is a crutch, and I want to avoid using it unless I absolutely have no other choice.  

Which brings us to the power of Expression Language.  Using EL I can reference Java Object methods from an XPage, cause those methods to run, and retrieve data from the object -all without overhead and other issues associated with SSJS.  

In order to use EL in place of the SSJS, all we need to do is to replace the SSJS stuff with EL stuff.  


<xp:text
 escape="true"
 id="text1"
 value="#{JohnSmallBerries.colorName}" />
 

See what I did there?  I removed the javascript: prefix, and made a slight change to the code after JohnSmallBerries.


Expression Language Processor


The Expression Language Processor (part of the JSF back-end black magic invoked by XPages) is intelligent enough to usually figure out what you are asking for when you reference a Scope or Bean or Document or Java Object property.   This is what allows you to use EL like I have above, or like this:


<xp:text
  escape="true"
  id="subject1"
  value="#{document1.subject}" />
 


The Expression Language Processor (I'm going to call it ELP because I'm tired of typing the whole thing) does a bunch of very complex stuff, most of which is outside the scope of this post ;-)  

What follows is my very simple explanation of how the ELP figures out what to return.  

The ELP uses built in logic to try and determine what it is you are asking for.  When you specify the property you want (such as .subject or .colorName), the ELP queries your object to see if it (among other things) has  

1) a method called 'getValue(String key)" (technically implements DataObject).  If your object DOES have this method, then the ELP will call the method and pass in the name of the property you requested (the part after the period).  If it gets back any value other than null it stops processing and returns the value.

2) a Getter method for the property you requested.  It searches the object for a method named getYourPropertyName() (a process called Introspection).  The naming of this method is critical, in that the ELP takes the property you requested (which must begin with a lower-case character), changes the first character to upper case, then sticks "get" on the front of it, and finally checks to see if the method exists.   If the method exists the ELP then calls that method and returns the value.

With me so far?   Ok.  So in the case of a Document object called document1, if we wanted to get the value of the Subject field, we could use the following EL:


#{document.subject}


The ELP would check the document object to see if it has a getValue() method, and then finding that it does will call getValue("subject")  and return that result.  Simple right?

In the case of our Lectroid object called JohnSmallBerries, our EL looks like this:


#{JohnSmallBerries.colorName}


The ELP checks to see if the Lectroid object has a getValue() method, and then finding that it does NOT, will use Introspection to determine if it has a method called getColorName().   The ELP will then call that method and return the value.


Method Overloading


Java is an awesome language, with a ton of way cool stuff associated with it.  One of the cool things it allows us to do is something called Method Overloading.  Method Overloading basically means that for any given class you can create multiple methods with the same name, as long as
1) they all return the same thing, and
2) they all have different method signatures (arguments are different)

In a nutshell, this means you can write a bunch of methods, each with the same name, that each return the same thing, but which each takes a different argument.    For example, here are three methods, each of which will return a Common Name string, but each of which has a different method signature:


public String getCommonName(Session session)

public String getCommonName(String string)

public String getCommonName(Name name)



Ok, that was a lot to absorb.  Take a few minutes and give your brain a chance rest.


Comments Disabled