In most programming languages there is a way to reuse code. Code that can be called from another part of a program is usually referred to as a function or method depending on your language. So you may have wondered is there something similar in OGNL? In fact there is.
In the Language Guide you will find that it is called Pseudo-Lambda Expressions, but we will simply call them functions.
To show how they can be used, I'll go back to a previous article in my series on OGNL, Looping in OGNL take 2, and use that code as an example. We want to look for duplicated code, which is a good candidate for a function.
See the complete list of articles in my OGNL series at the end of this post.
The original code is listed below:
#groupCnOnly = new java.util.ArrayList(),
#groups = #this.get("ds.LDAP.memberOf")!=null?#this.get("ds.LDAP.memberOf").getValues():{},
#groups.{
#group = #this,
#group = new javax.naming.ldap.LdapName(#group),
#cn = #group.getRdn(#group.size() - 1).getValue().toString(),
#groupCnOnly.add(#cn)
},
#this.get("ds.LDAP.memberOf")!=null? new org.sourceid.saml20.adapter.attribute.AttributeValue(#groupCnOnly):null
Looking at the code we get the attribute ds.LDAP.memberOf three times and we test for a null value twice. To simplify, the first thing we do is declare a variable to hold the value from the get:
#testVal = #this.get("ds.LDAP.memberOf")
Instead of using the expression #this.get("ds.LDAP.memberOf") we use #testVal. This reduces some of the duplicate code, but what do we do about the testing for a non-null value expression #this.get("ds.LDAP.memberOf")!=null? This can be our function. The function syntax looks like the following:
#notNull = :[#this != null]
Inside the square brackets [ ] is the code in our function. We assign that code to a variable that we use to call the function. The colon : [ at the open square bracket is also part of the syntax. Taking the proposed code changes we end up with the following:
#notNull = :[#this != null],
#testVal = #this.get("ds.LDAP.memberOf"),
#groupCnOnly = new java.util.ArrayList(),
#groups = #notNull(#testVal)?#testVal.getValues():{},
#groups.{
#group = #this,
#group = new javax.naming.ldap.LdapName(#group),
#cn = #group.getRdn(#group.size() - 1).getValue().toString(),
#groupCnOnly.add(#cn)
},
#notNull(#testVal)? new org.sourceid.saml20.adapter.attribute.AttributeValue(#groupCnOnly):null
The function must be declared before it is used, so we put it at the top. The first use of the function is initializing the groups variable:
#groups = #notNull(#testVal)?#testVal.getValues():{},
We pass in the testVal variable initialized earlier. The variable passed becomes the this variable in the function.
In PingFederate it will look like:
Once we execute it:
Stay tuned for more about OGNL. In the meantime please leave a comment on this post and let me know what topics you would like to see. Follow me on Twitter: @jdasilvaPI
****************************************
OGNL Blog Series:
- Introduction to OGNL
- A simple OGNL expression
- Declaring variables in OGNL
- Method calls in OGNL
- Arrays in OGNL
- OGNL: What about those curly braces?
- Looping in OGNL
- Looping in OGNL take 2
- So what exactly is #this in OGNL?
- A continuing look at #this variable in OGNL
- Functions in OGNL
- Misc Topics in OGNL
John DaSilva develops training and solutions at Ping Identity.