diff --git a/README.mdown b/README.mdown new file mode 100644 index 0000000..d17e56f --- /dev/null +++ b/README.mdown @@ -0,0 +1,78 @@ +SpelHelper provides additional functionalities to work with +[Spring Expression Language (SpEL)][1]. + +The addition functionalities provided are: + +1. Implicit methods +2. Implicit properties +3. Simplified extension functions +4. Simplified constructors + +**Implicit Methods** + +Implicit methods allow one to registers methods with SpelHelper and attach +them to particular classes. After that, when that method is called on an +object of that particular class inside a SpEL expression, SpelHelper +redirects the method call to the registered method. + +Example: [ImplicitMethods#sorted(List)][4] method is automatically +registered by SpelHelper. The class that the method should be invoked for +is the type of the first parameter of the method. In this case, the class is +java.util.List. + +So when an expression like `"#list(1,4,2).sorted()"` is evaluated, the +[ImplicitMethods#sorted(List)][4] method is invoked with the list as its +first parameter and its return value is used in further evaluation of the +expression. + +**Implicit Properties** + +Implicit properties allow one to treat no argument methods of an object +as properties of the object. SpelHelper intercepts the property resolution +of SpEL and if the property name is same as some no-arg method of the target +object then it invokes the method on the object and provides its return value +as the property value for further evaluation of the expression. + +Example: Using implicit properties, the example of implicit methods can be +written as: `"#list(1,4,2).sorted"` - dropping the parens - and it will return +the same value as the last example. + +Implicit property resolution considers both the actual methods of the object +and the implicit methods registered on the object's class. + +**Simplified extension functions** + +SpEL [allows][2] to register extension function on the context by providing a +name and a java.lang.reflect.Method object. SpelHelper simplifies this by taking a class +and registering all the `public static` methods of the class which do not +have a `void` return type. The methods are registered by their simple name. + +Example: All the methods of [ExtensionFunctions][5] class are automatically +registered by SpelHelper. Hence the method [ExtensionFunctions#list(Object...)][5] +can be called from inside a SpEL expression using the function call syntax: +`"#list(1,2,3)`". + +**Simplified constructors** + +SpEL [allows][3] calling constructors from inside a SpEL expression using the +`new` operator. But they have to be called with their full name like: +`"new org.example.Foo('bar')"`. SpelHelper simplifies this by taking a class +and registering all its public constructors to the SpEL context by their +simple name. + +Example: After registering the `org.example.Foo` class with SpelHelper, its +constructor can be called from inside a SpEL expression by: `"new Foo('bar')"`. + +In addition to all the above functionalities, SpelHelper automatically registers +some extension functions and implicit methods which are always available in +the SpEL expressions evaluated through SpelHelper. See [ExtensionFunctions][5] +and [ImplicitMethods][4] for further details. + +For more details see the [API Javadocs][6]. + +[1]: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html +[2]: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html#expressions-ref-functions +[3]: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html#d0e11927 +[4]: http://github.com/abhin4v/spelhelper/blob/master/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethods.java +[5]: http://github.com/abhin4v/spelhelper/blob/master/src/main/java/net/abhinavsarkar/spelhelper/ExtensionFunctions.java +[6]: http://github.com/abhin4v/spelhelper/raw/master/apidocs/net/abhinavsarkar/spelhelper/package-summary.html \ No newline at end of file diff --git a/apidocs/allclasses-frame.html b/apidocs/allclasses-frame.html new file mode 100644 index 0000000..beab58c --- /dev/null +++ b/apidocs/allclasses-frame.html @@ -0,0 +1,36 @@ + + + + + + + +All Classes (SpelHelper 1.0 API) + + + + + + + + + + + +All Classes +
+ + + + + +
ExtensionFunctions +
+ImplicitMethods +
+SpelHelper +
+
+ + + diff --git a/apidocs/allclasses-noframe.html b/apidocs/allclasses-noframe.html new file mode 100644 index 0000000..f7eae00 --- /dev/null +++ b/apidocs/allclasses-noframe.html @@ -0,0 +1,36 @@ + + + + + + + +All Classes (SpelHelper 1.0 API) + + + + + + + + + + + +All Classes +
+ + + + + +
ExtensionFunctions +
+ImplicitMethods +
+SpelHelper +
+
+ + + diff --git a/apidocs/constant-values.html b/apidocs/constant-values.html new file mode 100644 index 0000000..2a2b379 --- /dev/null +++ b/apidocs/constant-values.html @@ -0,0 +1,145 @@ + + + + + + + +Constant Field Values (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Constant Field Values

+
+
+Contents + +
+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/deprecated-list.html b/apidocs/deprecated-list.html new file mode 100644 index 0000000..988010b --- /dev/null +++ b/apidocs/deprecated-list.html @@ -0,0 +1,145 @@ + + + + + + + +Deprecated List (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Deprecated API

+
+
+Contents + +
+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/help-doc.html b/apidocs/help-doc.html new file mode 100644 index 0000000..497790e --- /dev/null +++ b/apidocs/help-doc.html @@ -0,0 +1,216 @@ + + + + + + + +API Help (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+How This API Document Is Organized

+
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.

+Package

+
+ +

+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:

+
+

+Class/Interface

+
+ +

+Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+ +

+Annotation Type

+
+ +

+Each annotation type has its own separate page with the following sections:

+
+ +

+Enum

+
+ +

+Each enum has its own separate page with the following sections:

+
+

+Use

+
+Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+

+Tree (Class Hierarchy)

+
+There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object. +
+

+Deprecated API

+
+The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+

+Index

+
+The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+

+Prev/Next

+These links take you to the next or previous class, interface, package, or related page.

+Frames/No Frames

+These links show and hide the HTML frames. All pages are available with or without frames. +

+

+Serialized Form

+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description. +

+

+Constant Field Values

+The Constant Field Values page lists the static final fields and their values. +

+ + +This help file applies to API documentation generated using the standard doclet. + +
+


+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/index-all.html b/apidocs/index-all.html new file mode 100644 index 0000000..81870a0 --- /dev/null +++ b/apidocs/index-all.html @@ -0,0 +1,260 @@ + + + + + + + +Index (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +D E G I L M N R S T
+

+D

+
+
distinct(List<? extends T>) - +Static method in class net.abhinavsarkar.spelhelper.ImplicitMethods +
Provides implicit method distinct on the List class. +
drop(List<T>, int) - +Static method in class net.abhinavsarkar.spelhelper.ImplicitMethods +
Provides implicit method drop on the List class. +
+
+

+E

+
+
evalExpression(String, Object, Class<T>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Evaluates a SpEL expression expressionString in the context +of root element rootElement and gives back a result of type +desiredType. +
evalExpression(String, EvaluationContext, Class<T>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Evaluates a SpEL expression expressionString in the provided +context evaluationContext and gives back a result of type +desiredType. +
evalExpressions(String[], Object, Class<T>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Evaluates multiple SpEL expressions and returns the result of the last +expression. +
evalExpressions(String[], EvaluationContext, Class<T>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Evaluates multiple SpEL expressions and returns the result of the last +expression. +
ExtensionFunctions - Class in net.abhinavsarkar.spelhelper
Provides some extension functions to create some basic collection types +inline in SpEL expressions.
+
+

+G

+
+
getCurrentContext() - +Static method in class net.abhinavsarkar.spelhelper.SpelHelper +
Returns the current evaluation context. +
+
+

+I

+
+
ImplicitMethods - Class in net.abhinavsarkar.spelhelper
Provides some implicit methods which can be invoked on the instances of +class of the first parameter of the method inside a SpEL expression.
ImplicitMethods() - +Constructor for class net.abhinavsarkar.spelhelper.ImplicitMethods +
  +
+
+

+L

+
+
list(T...) - +Static method in class net.abhinavsarkar.spelhelper.ExtensionFunctions +
Creates an unmodifiable List of the arguments provided. +
lookupImplicitConstructor(String) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Looks up an implicit constructor registered with this instance. +
lookupImplicitMethod(String) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Looks up an implicit method registered with this instance. +
+
+

+M

+
+
map(List<? extends K>, List<? extends V>) - +Static method in class net.abhinavsarkar.spelhelper.ExtensionFunctions +
Creates an unmodifiable Map using the List of keys +provided as the first argument and the List of values provided +as the second argument. +
+
+

+N

+
+
net.abhinavsarkar.spelhelper - package net.abhinavsarkar.spelhelper
 
+
+

+R

+
+
registerConstructorsFromClass(Class<?>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Registers the public constructors of the class clazz so that they +can be called by their simple name from SpEL expressions. +
registerFunctionsFromClass(Class<?>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Registers the public static methods in the class clazz as functions +which can be called from SpEL expressions. +
registerImplicitMethodsFromClass(Class<?>) - +Method in class net.abhinavsarkar.spelhelper.SpelHelper +
Registers the public static methods in the class clazz as implicit +methods for the class of the first parameter of the methods. +
reversed(List<? extends T>) - +Static method in class net.abhinavsarkar.spelhelper.ImplicitMethods +
Provides implicit method reversed on the List class. +
+
+

+S

+
+
set(T...) - +Static method in class net.abhinavsarkar.spelhelper.ExtensionFunctions +
Creates an unmodifiable Set of the arguments provided. +
sorted(List<? extends T>) - +Static method in class net.abhinavsarkar.spelhelper.ImplicitMethods +
Provides implicit method sorted on the List class. +
SpelHelper - Class in net.abhinavsarkar.spelhelper
SpelHelper provides additional functionalities to work with +[Spring Expression Language (SpEL)][1].
SpelHelper() - +Constructor for class net.abhinavsarkar.spelhelper.SpelHelper +
Creates an instance of SpelHelper. +
+
+

+T

+
+
take(List<T>, int) - +Static method in class net.abhinavsarkar.spelhelper.ImplicitMethods +
Provides implicit method take on the List class. +
+
+D E G I L M N R S T + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/index.html b/apidocs/index.html new file mode 100644 index 0000000..c3f15f3 --- /dev/null +++ b/apidocs/index.html @@ -0,0 +1,37 @@ + + + + + + + +SpelHelper 1.0 API + + + + + + + + +<H2> +Frame Alert</H2> + +<P> +This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. +<BR> +Link to<A HREF="net/abhinavsarkar/spelhelper/package-summary.html">Non-frame version.</A> + + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/ExtensionFunctions.html b/apidocs/net/abhinavsarkar/spelhelper/ExtensionFunctions.html new file mode 100644 index 0000000..9152024 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/ExtensionFunctions.html @@ -0,0 +1,314 @@ + + + + + + + +ExtensionFunctions (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +net.abhinavsarkar.spelhelper +
+Class ExtensionFunctions

+
+java.lang.Object
+  extended by net.abhinavsarkar.spelhelper.ExtensionFunctions
+
+
+
+
public final class ExtensionFunctions
extends Object
+ + +

+

Provides some extension functions to create some basic collection types +inline in SpEL expressions. +These functions are automatically registered with SpelHelper .

+ +

See Also: +Spring Docs on extension functions

+

+ +

+

+
Author:
+
Abhinav Sarkar abhinav@abhinavsarkar.net
+
+
+ +

+ + + + + + + + + + + + + + + + + + + + +
+Method Summary
+static + + + + +
+<T> List<T>
+
list(T... args) + +
+          Creates an unmodifiable List of the arguments provided.
+static + + + + +
+<K,V> Map<K,V>
+
map(List<? extends K> keys, + List<? extends V> values) + +
+          Creates an unmodifiable Map using the List of keys +provided as the first argument and the List of values provided +as the second argument.
+static + + + + +
+<T> Set<T>
+
set(T... args) + +
+          Creates an unmodifiable Set of the arguments provided.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Method Detail
+ +

+list

+
+public static <T> List<T> list(T... args)
+
+

Creates an unmodifiable List of the arguments provided.

+ +

Example use: "#list('one', 'two', 'three')"

+

+

+
Type Parameters:
T - Type of the arguments provided.
Parameters:
args - Arguments to create list of. +
Returns:
An unmodifiable list of the arguments provided.
+
+
+
+ +

+set

+
+public static <T> Set<T> set(T... args)
+
+

Creates an unmodifiable Set of the arguments provided.

+ +

Example use: "#set('one', 'two', 'three')"

+

+

+
Type Parameters:
T - Type of the arguments provided.
Parameters:
args - Arguments to create set of. +
Returns:
An unmodifiable set of the arguments provided.
+
+
+
+ +

+map

+
+public static <K,V> Map<K,V> map(List<? extends K> keys,
+                                 List<? extends V> values)
+
+

Creates an unmodifiable Map using the List of keys +provided as the first argument and the List of values provided +as the second argument.

+ +

Example use: "#map(#list('one', 'two', 'three'), #list(1, 2, 3))"

+

+

+
Type Parameters:
K - Type of the keys of the map.
V - Type of the values of map.
Parameters:
keys - List of the keys.
values - List of the values. +
Returns:
A unmodifiable map created from the key and value lists. +
Throws: +
IllegalArgumentException - if the number of keys and the number of +values is not equal.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/ImplicitMethods.html b/apidocs/net/abhinavsarkar/spelhelper/ImplicitMethods.html new file mode 100644 index 0000000..b560308 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/ImplicitMethods.html @@ -0,0 +1,421 @@ + + + + + + + +ImplicitMethods (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +net.abhinavsarkar.spelhelper +
+Class ImplicitMethods

+
+java.lang.Object
+  extended by net.abhinavsarkar.spelhelper.ImplicitMethods
+
+
+
+
public final class ImplicitMethods
extends Object
+ + +

+Provides some implicit methods which can be invoked on the instances of +class of the first parameter of the method inside a SpEL expression. +

+ +

+

+
Author:
+
Abhinav Sarkar abhinav@abhinavsarkar.net
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
ImplicitMethods() + +
+           
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+static + + + + +
+<T> Set<T>
+
distinct(List<? extends T> list) + +
+          Provides implicit method distinct on the List class.
+static + + + + +
+<T> List<T>
+
drop(List<T> list, + int n) + +
+          Provides implicit method drop on the List class.
+static + + + + +
+<T> List<T>
+
reversed(List<? extends T> list) + +
+          Provides implicit method reversed on the List class.
+static + + + + +
+<T extends Comparable<? super T>> +
+List<T>
+
sorted(List<? extends T> list) + +
+          Provides implicit method sorted on the List class.
+static + + + + +
+<T> List<T>
+
take(List<T> list, + int n) + +
+          Provides implicit method take on the List class.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+ImplicitMethods

+
+public ImplicitMethods()
+
+
+ + + + + + + + +
+Method Detail
+ +

+distinct

+
+public static <T> Set<T> distinct(List<? extends T> list)
+
+

Provides implicit method distinct on the List class.

+ +

Example: "#list('a','b','a').distinct()" //should return List('a','b')

+ +

With implicit property support provided by SpelHelper this can +also be written as:

+ +

"#list('a','b','a').distinct" //same output as earlier

+

+

+
Type Parameters:
T - Type of the list's elements.
Parameters:
list - The list to call this method upon. +
Returns:
An unmodifiable Set containing the distinct items of the list.
+
+
+
+ +

+sorted

+
+public static <T extends Comparable<? super T>> List<T> sorted(List<? extends T> list)
+
+

Provides implicit method sorted on the List class.

+ +

Example: "#list('c','b','a').sorted()" //should return List('a','b','c')

+ +

With implicit property support provided by SpelHelper this can +also be written as:

+ +

"#list('c','b','a').sorted" //same output as earlier

+

+

+
Type Parameters:
T - Type of the list's elements.
Parameters:
list - The list to call this method upon. +
Returns:
An unmodifiable List containing the sorted items +of the list.
See Also:
Collections.sort(List)
+
+
+
+ +

+reversed

+
+public static <T> List<T> reversed(List<? extends T> list)
+
+

Provides implicit method reversed on the List class.

+ +

Example: "#list('c','b','a').reversed()" //should return List('a','b','c')

+ +

With implicit property support provided by SpelHelper this can +also be written as:

+ +

"#list('c','b','a').reversed" //same output as earlier

+

+

+
Type Parameters:
T - Type of the list's elements.
Parameters:
list - The list to call this method upon. +
Returns:
An unmodifiable List containing the items of the +list in reverse order.
See Also:
Collections.reverse(List)
+
+
+
+ +

+take

+
+public static <T> List<T> take(List<T> list,
+                               int n)
+
+

Provides implicit method take on the List class.

+ +

Example: "#list('c','b','a').take(2)" //should return List('a','b')

+

+

+
Type Parameters:
T - Type of the list's elements.
Parameters:
list - The list to call this method upon.
n - Number of items to take from the list. +
Returns:
An unmodifiable List containing the first n items +of the list.
+
+
+
+ +

+drop

+
+public static <T> List<T> drop(List<T> list,
+                               int n)
+
+

Provides implicit method drop on the List class.

+ +

Example: "#list('c','b','a').drop(2)" //should return List('a')

+

+

+
Type Parameters:
T - Type of the list's elements.
Parameters:
list - The list to call this method upon.
n - Number of items to drop from the list. +
Returns:
An unmodifiable List containing the items after the +first n items of the list.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/SpelHelper.html b/apidocs/net/abhinavsarkar/spelhelper/SpelHelper.html new file mode 100644 index 0000000..2245d61 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/SpelHelper.html @@ -0,0 +1,618 @@ + + + + + + + +SpelHelper (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +

+ +net.abhinavsarkar.spelhelper +
+Class SpelHelper

+
+java.lang.Object
+  extended by net.abhinavsarkar.spelhelper.SpelHelper
+
+
+
+
public final class SpelHelper
extends Object
+ + +

+

SpelHelper provides additional functionalities to work with +Spring Expression Language (SpEL).

+ +

The addition functionalities provided are:

+ +
    +
  1. Implicit methods
  2. +
  3. Implicit properties
  4. +
  5. Simplified extension functions
  6. +
  7. Simplified constructors
  8. +
+ +

Implicit Methods

+ +

Implicit methods allow one to registers methods with SpelHelper and attach +them to particular classes. After that, when that method is called on an +object of that particular class inside a SpEL expression, SpelHelper +redirects the method call to the registered method.

+ +

Example: ImplicitMethods.sorted(List) method is automatically +registered by SpelHelper. The class that the method should be invoked for +is the type of the first parameter of the method. In this case, the class is +List .

+ +

So when an expression like "#list(1,4,2).sorted()" is evaluated, the +ImplicitMethods.sorted(List) method is invoked with the list as its +first parameter and its return value is used in further evaluation of the +expression.

+ +

See registerImplicitMethodsFromClass(Class) .

+ +

Implicit Properties

+ +

Implicit properties allow one to treat no argument methods of an object +as properties of the object. SpelHelper intercepts the property resolution +of SpEL and if the property name is same as some no-arg method of the target +object then it invokes the method on the object and provides its return value +as the property value for further evaluation of the expression.

+ +

Example: Using implicit properties, the example of implicit methods can be +written as: "#list(1,4,2).sorted" - dropping the parens - and it will return +the same value as the last example.

+ +

Implicit property resolution considers both the actual methods of the object +and the implicit methods registered on the object's class.

+ +

Simplified extension functions

+ +

SpEL allows to register extension function on the context by providing a +name and a Method object. SpelHelper simplifies this by taking a class +and registering all the public static methods of the class which do not +have a void return type. The methods are registered by their simple name.

+ +

Example: All the methods of ExtensionFunctions class are automatically +registered by SpelHelper. Hence the method ExtensionFunctions.list(Object...) +can be called from inside a SpEL expression using the function call syntax: +"#list(1,2,3)".

+ +

See registerFunctionsFromClass(Class) .

+ +

Simplified constructors

+ +

SpEL allows calling constructors from inside a SpEL expression using the +new operator. But they have to be called with their full name like: +"new org.example.Foo('bar')". SpelHelper simplifies this by taking a class +and registering all its public constructors to the SpEL context by their +simple name.

+ +

Example: After registering the org.example.Foo class with SpelHelper, its +constructor can be called from inside a SpEL expression by: "new Foo('bar')".

+ +

See registerConstructorsFromClass(Class) .

+ +

In addition to all the above functionalities, SpelHelper automatically registers +some extension functions and implicit methods which are always available in +the SpEL expressions evaluated through SpelHelper. See ExtensionFunctions +and ImplicitMethods for further details.

+

+ +

+

+
Author:
+
Abhinav Sarkar abhinav@abhinavsarkar.net
+
+
+ +

+ + + + + + + + + + + +
+Constructor Summary
SpelHelper() + +
+          Creates an instance of SpelHelper.
+  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Method Summary
+ + + + + +
+<T> T
+
evalExpression(String expressionString, + EvaluationContext evaluationContext, + Class<T> desiredType) + +
+          Evaluates a SpEL expression expressionString in the provided +context evaluationContext and gives back a result of type +desiredType.
+ + + + + +
+<T> T
+
evalExpression(String expressionString, + Object rootElement, + Class<T> desiredType) + +
+          Evaluates a SpEL expression expressionString in the context +of root element rootElement and gives back a result of type +desiredType.
+ + + + + +
+<T> T
+
evalExpressions(String[] expressionStrings, + EvaluationContext evaluationContext, + Class<T> desiredType) + +
+          Evaluates multiple SpEL expressions and returns the result of the last +expression.
+ + + + + +
+<T> T
+
evalExpressions(String[] expressionStrings, + Object rootElement, + Class<T> desiredType) + +
+          Evaluates multiple SpEL expressions and returns the result of the last +expression.
+static EvaluationContextgetCurrentContext() + +
+          Returns the current evaluation context.
+ Constructor<?>lookupImplicitConstructor(String lookup) + +
+          Looks up an implicit constructor registered with this instance.
+ MethodlookupImplicitMethod(String lookup) + +
+          Looks up an implicit method registered with this instance.
+ SpelHelperregisterConstructorsFromClass(Class<?> clazz) + +
+          Registers the public constructors of the class clazz so that they +can be called by their simple name from SpEL expressions.
+ SpelHelperregisterFunctionsFromClass(Class<?> clazz) + +
+          Registers the public static methods in the class clazz as functions +which can be called from SpEL expressions.
+ SpelHelperregisterImplicitMethodsFromClass(Class<?> clazz) + +
+          Registers the public static methods in the class clazz as implicit +methods for the class of the first parameter of the methods.
+ + + + + + + +
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
+  +

+ + + + + + + + +
+Constructor Detail
+ +

+SpelHelper

+
+public SpelHelper()
+
+
Creates an instance of SpelHelper. +

+

+ + + + + + + + +
+Method Detail
+ +

+registerImplicitMethodsFromClass

+
+public SpelHelper registerImplicitMethodsFromClass(Class<?> clazz)
+
+

Registers the public static methods in the class clazz as implicit +methods for the class of the first parameter of the methods.

+ +

Only registers the public static methods with non void return type and at +least one argument.

+

+

+
Parameters:
clazz - The class to register the methods from. +
Returns:
The current instance of SpelHelper. This is for chaining +the methods calls.
See Also:
ImplicitMethods
+
+
+
+ +

+registerFunctionsFromClass

+
+public SpelHelper registerFunctionsFromClass(Class<?> clazz)
+
+

Registers the public static methods in the class clazz as functions +which can be called from SpEL expressions. +The functions are registered with the simple name of the methods.

+ +

Only registers the public static methods with non void return type.

+

+

+
Parameters:
clazz - The class to register the functions from. +
Returns:
The current instance of SpelHelper. This is for chaining +the methods calls.
See Also:
ExtensionFunctions
+
+
+
+ +

+registerConstructorsFromClass

+
+public SpelHelper registerConstructorsFromClass(Class<?> clazz)
+
+
Registers the public constructors of the class clazz so that they +can be called by their simple name from SpEL expressions. +

+

+
Parameters:
clazz - The class to register the constructors from. +
Returns:
The current instance of SpelHelper. This is for chaining +the methods calls.
+
+
+
+ +

+evalExpression

+
+public <T> T evalExpression(String expressionString,
+                            Object rootElement,
+                            Class<T> desiredType)
+
+
Evaluates a SpEL expression expressionString in the context +of root element rootElement and gives back a result of type +desiredType. +

+

+
Type Parameters:
T - The type of the result desired.
Parameters:
expressionString - The SpEL expression to evaluate.
rootElement - The root element in context of which the expression +is to be evaluated.
desiredType - The class of the result desired. +
Returns:
The result of the evaluation of the expression.
See Also:
ExpressionParser.parseExpression(String), +Expression.getValue(EvaluationContext, Class)
+
+
+
+ +

+evalExpression

+
+public <T> T evalExpression(String expressionString,
+                            EvaluationContext evaluationContext,
+                            Class<T> desiredType)
+
+
Evaluates a SpEL expression expressionString in the provided +context evaluationContext and gives back a result of type +desiredType. +

+

+
Type Parameters:
T - The type of the result desired.
Parameters:
expressionString - The SpEL expression to evaluate.
evaluationContext - The context in which the expression is to be evaluated.
desiredType - The class of the result desired. +
Returns:
The result of the evaluation of the expression.
See Also:
ExpressionParser.parseExpression(String), +Expression.getValue(EvaluationContext, Class)
+
+
+
+ +

+evalExpressions

+
+public <T> T evalExpressions(String[] expressionStrings,
+                             Object rootElement,
+                             Class<T> desiredType)
+
+
Evaluates multiple SpEL expressions and returns the result of the last +expression. +

+

+
Type Parameters:
T - The type of the result desired.
Parameters:
expressionStrings - The SpEL expressions to evaluate.
rootElement - The root element in context of which the expressions +are to be evaluated.
desiredType - The class of the result desired. +
Returns:
The result of the evaluation of the last expression.
See Also:
evalExpression(String, EvaluationContext, Class), +evalExpression(String, Object, Class)
+
+
+
+ +

+evalExpressions

+
+public <T> T evalExpressions(String[] expressionStrings,
+                             EvaluationContext evaluationContext,
+                             Class<T> desiredType)
+
+
Evaluates multiple SpEL expressions and returns the result of the last +expression. +

+

+
Type Parameters:
T - The type of the result desired.
Parameters:
expressionStrings - The SpEL expressions to evaluate.
evaluationContext - The context in which the expression is to be evaluated.
desiredType - The class of the result desired. +
Returns:
The result of the evaluation of the last expression.
See Also:
evalExpression(String, EvaluationContext, Class), +evalExpression(String, Object, Class)
+
+
+
+ +

+lookupImplicitMethod

+
+public Method lookupImplicitMethod(String lookup)
+
+
Looks up an implicit method registered with this instance. +

+

+
Parameters:
lookup - key to lookup which should be of form: +method.getParameterTypes()[0].getName() + "." + method.getName() +
Returns:
The registered method if found, else null.
+
+
+
+ +

+lookupImplicitConstructor

+
+public Constructor<?> lookupImplicitConstructor(String lookup)
+
+
Looks up an implicit constructor registered with this instance. +

+

+
Parameters:
lookup - key to lookup which should be of form: +constructor.getDeclaringClass().getSimpleName() + + Arrays.toString(constructor.getParameterTypes()) +
Returns:
The registered constructor if found, else null.
+
+
+
+ +

+getCurrentContext

+
+public static EvaluationContext getCurrentContext()
+
+
Returns the current evaluation context. Null if there is no context. +

+

+ +
Returns:
The current evaluation context.
+
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/class-use/ExtensionFunctions.html b/apidocs/net/abhinavsarkar/spelhelper/class-use/ExtensionFunctions.html new file mode 100644 index 0000000..508c4c6 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/class-use/ExtensionFunctions.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class net.abhinavsarkar.spelhelper.ExtensionFunctions (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
net.abhinavsarkar.spelhelper.ExtensionFunctions

+
+No usage of net.abhinavsarkar.spelhelper.ExtensionFunctions +

+


+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/class-use/ImplicitMethods.html b/apidocs/net/abhinavsarkar/spelhelper/class-use/ImplicitMethods.html new file mode 100644 index 0000000..8d7dd4d --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/class-use/ImplicitMethods.html @@ -0,0 +1,143 @@ + + + + + + + +Uses of Class net.abhinavsarkar.spelhelper.ImplicitMethods (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
net.abhinavsarkar.spelhelper.ImplicitMethods

+
+No usage of net.abhinavsarkar.spelhelper.ImplicitMethods +

+


+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/class-use/SpelHelper.html b/apidocs/net/abhinavsarkar/spelhelper/class-use/SpelHelper.html new file mode 100644 index 0000000..5f7e7f7 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/class-use/SpelHelper.html @@ -0,0 +1,185 @@ + + + + + + + +Uses of Class net.abhinavsarkar.spelhelper.SpelHelper (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Class
net.abhinavsarkar.spelhelper.SpelHelper

+
+ + + + + +
+Uses of SpelHelper in net.abhinavsarkar.spelhelper
+  +

+ + + + + + + + + + + + + + + + + +
Methods in net.abhinavsarkar.spelhelper that return SpelHelper
+ SpelHelperSpelHelper.registerConstructorsFromClass(Class<?> clazz) + +
+          Registers the public constructors of the class clazz so that they +can be called by their simple name from SpEL expressions.
+ SpelHelperSpelHelper.registerFunctionsFromClass(Class<?> clazz) + +
+          Registers the public static methods in the class clazz as functions +which can be called from SpEL expressions.
+ SpelHelperSpelHelper.registerImplicitMethodsFromClass(Class<?> clazz) + +
+          Registers the public static methods in the class clazz as implicit +methods for the class of the first parameter of the methods.
+  +

+


+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/package-frame.html b/apidocs/net/abhinavsarkar/spelhelper/package-frame.html new file mode 100644 index 0000000..516148b --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/package-frame.html @@ -0,0 +1,37 @@ + + + + + + + +net.abhinavsarkar.spelhelper (SpelHelper 1.0 API) + + + + + + + + + + + +net.abhinavsarkar.spelhelper + + + + +
+Classes  + +
+ExtensionFunctions +
+ImplicitMethods +
+SpelHelper
+ + + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/package-summary.html b/apidocs/net/abhinavsarkar/spelhelper/package-summary.html new file mode 100644 index 0000000..7e4a1ce --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/package-summary.html @@ -0,0 +1,167 @@ + + + + + + + +net.abhinavsarkar.spelhelper (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+

+Package net.abhinavsarkar.spelhelper +

+ + + + + + + + + + + + + + + + + +
+Class Summary
ExtensionFunctionsProvides some extension functions to create some basic collection types +inline in SpEL expressions.
ImplicitMethodsProvides some implicit methods which can be invoked on the instances of +class of the first parameter of the method inside a SpEL expression.
SpelHelperSpelHelper provides additional functionalities to work with +[Spring Expression Language (SpEL)][1].
+  + +

+

+
+
+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/package-tree.html b/apidocs/net/abhinavsarkar/spelhelper/package-tree.html new file mode 100644 index 0000000..15e11a8 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/package-tree.html @@ -0,0 +1,149 @@ + + + + + + + +net.abhinavsarkar.spelhelper Class Hierarchy (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For Package net.abhinavsarkar.spelhelper +

+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/net/abhinavsarkar/spelhelper/package-use.html b/apidocs/net/abhinavsarkar/spelhelper/package-use.html new file mode 100644 index 0000000..89cb419 --- /dev/null +++ b/apidocs/net/abhinavsarkar/spelhelper/package-use.html @@ -0,0 +1,157 @@ + + + + + + + +Uses of Package net.abhinavsarkar.spelhelper (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Uses of Package
net.abhinavsarkar.spelhelper

+
+ + + + + + + + +
+Classes in net.abhinavsarkar.spelhelper used by net.abhinavsarkar.spelhelper
SpelHelper + +
+          SpelHelper provides additional functionalities to work with +[Spring Expression Language (SpEL)][1].
+  +

+


+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/overview-tree.html b/apidocs/overview-tree.html new file mode 100644 index 0000000..b0c5c56 --- /dev/null +++ b/apidocs/overview-tree.html @@ -0,0 +1,151 @@ + + + + + + + +Class Hierarchy (SpelHelper 1.0 API) + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+ +
+ + + +
+
+

+Hierarchy For All Packages

+
+
+
Package Hierarchies:
net.abhinavsarkar.spelhelper
+
+

+Class Hierarchy +

+ +
+ + + + + + + + + + + + + + + +
+Code hosted at github +
+ + + +
+Copyright © 2010. All Rights Reserved. + + diff --git a/apidocs/package-list b/apidocs/package-list new file mode 100644 index 0000000..a3859ab --- /dev/null +++ b/apidocs/package-list @@ -0,0 +1 @@ +net.abhinavsarkar.spelhelper diff --git a/apidocs/resources/inherit.gif b/apidocs/resources/inherit.gif new file mode 100644 index 0000000..c814867 Binary files /dev/null and b/apidocs/resources/inherit.gif differ diff --git a/apidocs/spring-javadoc.css b/apidocs/spring-javadoc.css new file mode 100644 index 0000000..6e69d80 --- /dev/null +++ b/apidocs/spring-javadoc.css @@ -0,0 +1,178 @@ +/* stylesheet.css 2008/04/22 nicolekonicki */ + +/* + * + * Spring-specific Javadoc style sheet + * + */ + + + +.code +{ + border: 1px solid black; + background-color: #F4F4F4; + padding: 5px; +} + +body +{ + font: 12px Verdana, Arial, Helvetica, "Bitstream Vera Sans", sans-serif; + background-color: #fff; + color: #333; +} + + +/* Link colors */ +a +{ + color:#2c7b14; + text-decoration:none; +} + +a:hover +{ + text-decoration:underline; +} + +/* Headings */ +h1 +{ + font-size:28px; + color:#007c00; +} + +/* Table colors */ + +table +{ + border:none; +} + +td +{ + border:none; + border-bottom:1px dotted #ddd; +} + +th +{ + border:none; +} + +.TableHeadingColor th +{ + background-color: #064F52; + background-image: url(http://static.springsource.org/spring/docs/3.0.x/javadoc-api/resources/TableHeading-background.png); + background-repeat: repeat-x; + color:#fff; + font-size:14px; + height:26px; +} + +.TableSubHeadingColor +{ + background: #f7ffee; + +} +.TableRowColor +{ + background: #fff; +} + +.TableRowColor a +{ + border-bottom:none; + color:#2c7b14; + font-weight:normal; +} + +tr.TableRowColor:hover +{ + background:#eef2e1; +} + + +/* Font used in left-hand frame lists */ +.FrameTitleFont +{ + font-size: 120%; + font-weight:bold; +} + +.FrameTitleFont a +{ + color: #333; +} + +.FrameHeadingFont +{ + font-weight: bold; + font-size:95%; +} + +.FrameItemFont +{ + line-height:130%; + font-size: 95%; +} + +.FrameItemFont a +{ + color:#333; +} + +.FrameItemFont a:hover +{ + color:#249901; + border-bottom:none; + text-decoration:underline; +} + +/* Navigation bar fonts and colors */ +.NavBarCell1 +{ + background-color:#fff; + border:none; +} + +.NavBarCell1Rev +{ + background-color:#e3faa5; + border:1px solid #9ad00c; + padding:0; + margin:0; +} + +.NavBarCell1 a +{ + color:#333; + text-decoration:none; +} + +.NavBarFont1Rev +{ + +} + +.NavBarCell2 +{ + border:none; +} + +.NavBarCell2 a +{ + color:#249901; + font-size:90%; +} + +.NavBarCell3 +{ + border:none; +} + +/* Override sizes in font tags */ +font +{ + font: inherit !important; +} diff --git a/lib/markdown-doclet-3.0.jar b/lib/markdown-doclet-3.0.jar new file mode 100644 index 0000000..9570d5f Binary files /dev/null and b/lib/markdown-doclet-3.0.jar differ diff --git a/pom.xml b/pom.xml index 4a0042f..12d95a2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,47 +1,75 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - net.abhinavsarkar.spelhelper - SpelHelper - 1.0 - jar + net.abhinavsarkar.spelhelper + SpelHelper + 1.0 + jar - SpelHelper - http://maven.apache.org + SpelHelper + http://maven.apache.org - - UTF-8 - - - - - - maven-compiler-plugin - - 1.5 - 1.5 - - - - + + UTF-8 + - - - junit - junit - 4.4 - test - - - org.springframework - spring-core - 3.0.2.RELEASE - - - org.springframework - spring-expression - 3.0.2.RELEASE - - + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.7 + + + javadoc + process-sources + + javadoc + + + + + ${basedir}/apidocs +
Code hosted at <a target='_blank' href='http://github.com/abhin4v/spelhelper/'>github</a>
+ + http://static.springsource.org/spring/docs/3.0.x/javadoc-api/ + + protected + spring-javadoc.css + com.visural.doclets.markdown.standard.Standard + ${basedir}/lib/markdown-doclet-3.0.jar + true +
+
+ + org.apache.maven.plugins + maven-compiler-plugin + 2.3.1 + + 1.6 + 1.5 + + +
+
+ + + + junit + junit + 4.4 + test + + + org.springframework + spring-core + 3.0.2.RELEASE + + + org.springframework + spring-expression + 3.0.2.RELEASE + +
diff --git a/src/main/java/net/abhinavsarkar/spelhelper/ExtensionFunctions.java b/src/main/java/net/abhinavsarkar/spelhelper/ExtensionFunctions.java index bc4871f..48a4dac 100644 --- a/src/main/java/net/abhinavsarkar/spelhelper/ExtensionFunctions.java +++ b/src/main/java/net/abhinavsarkar/spelhelper/ExtensionFunctions.java @@ -13,16 +13,58 @@ import java.util.Set; import org.springframework.util.Assert; -final class ExtensionFunctions { +/** + * Provides some extension functions to create some basic collection types + * inline in SpEL expressions. + * These functions are automatically registered with {@link SpelHelper}. + * + * **See Also:** + * [Spring Docs on extension functions](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html#expressions-ref-functions) + * @author Abhinav Sarkar _abhinav@abhinavsarkar.net_ + */ +public final class ExtensionFunctions { + private ExtensionFunctions() { + } + + /** + * Creates an unmodifiable {@link List} of the arguments provided. + * + * Example use: `"#list('one', 'two', 'three')"` + * @param Type of the arguments provided. + * @param args Arguments to create list of. + * @return An unmodifiable list of the arguments provided. + */ public static List list(final T... args) { return unmodifiableList(Arrays.asList(args)); } + /** + * Creates an unmodifiable {@link Set} of the arguments provided. + * + * Example use: `"#set('one', 'two', 'three')"` + * @param Type of the arguments provided. + * @param args Arguments to create set of. + * @return An unmodifiable set of the arguments provided. + */ public static Set set(final T... args) { return unmodifiableSet(new HashSet(list(args))); } + /** + * Creates an unmodifiable {@link Map} using the {@link List} of keys + * provided as the first argument and the {@link List} of values provided + * as the second argument. + * + * Example use: `"#map(#list('one', 'two', 'three'), #list(1, 2, 3))"` + * @param Type of the keys of the map. + * @param Type of the values of map. + * @param keys List of the keys. + * @param values List of the values. + * @return A unmodifiable map created from the key and value lists. + * @throws IllegalArgumentException if the number of keys and the number of + * values is not equal. + */ public static Map map(final List keys, final List values) { Assert.isTrue(keys.size() == values.size(), diff --git a/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethodResolver.java b/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethodResolver.java index b4506de..9130ae5 100644 --- a/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethodResolver.java +++ b/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethodResolver.java @@ -14,7 +14,7 @@ import org.springframework.expression.MethodResolver; import org.springframework.expression.TypedValue; import org.springframework.expression.spel.support.ReflectiveMethodResolver; -public final class ImplicitMethodResolver implements MethodResolver { +final class ImplicitMethodResolver implements MethodResolver { private static final ConcurrentHashMap cache = new ConcurrentHashMap(); diff --git a/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethods.java b/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethods.java index 4050a55..330c277 100644 --- a/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethods.java +++ b/src/main/java/net/abhinavsarkar/spelhelper/ImplicitMethods.java @@ -9,12 +9,45 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -final class ImplicitMethods { +/** + * Provides some implicit methods which can be invoked on the instances of + * class of the first parameter of the method inside a SpEL expression. + * @author Abhinav Sarkar _abhinav@abhinavsarkar.net_ + */ +public final class ImplicitMethods { + /** + * Provides implicit method `distinct` on the {@link List} class. + * + * Example: `"#list('a','b','a').distinct()" //should return List('a','b')` + * + * With implicit property support provided by {@link SpelHelper} this can + * also be written as: + * + * `"#list('a','b','a').distinct" //same output as earlier` + * @param Type of the list's elements. + * @param list The list to call this method upon. + * @return An unmodifiable {@link Set} containing the distinct items of the list. + */ public static Set distinct(final List list) { return unmodifiableSet(new HashSet(list)); } + /** + * Provides implicit method `sorted` on the {@link List} class. + * + * Example: `"#list('c','b','a').sorted()" //should return List('a','b','c')` + * + * With implicit property support provided by {@link SpelHelper} this can + * also be written as: + * + * `"#list('c','b','a').sorted" //same output as earlier` + * @param Type of the list's elements. + * @param list The list to call this method upon. + * @return An unmodifiable {@link List} containing the sorted items + * of the list. + * @see Collections#sort(List) + */ public static > List sorted( final List list) { List temp = new ArrayList(list); @@ -22,16 +55,53 @@ final class ImplicitMethods { return unmodifiableList(temp); } + /** + * Provides implicit method `reversed` on the {@link List} class. + * + * Example: `"#list('c','b','a').reversed()" //should return List('a','b','c')` + * + * With implicit property support provided by {@link SpelHelper} this can + * also be written as: + * + * `"#list('c','b','a').reversed" //same output as earlier` + * @param Type of the list's elements. + * @param list The list to call this method upon. + * @return An unmodifiable {@link List} containing the items of the + * list in reverse order. + * @see Collections#reverse(List) + */ public static List reversed(final List list) { List temp = new ArrayList(list); Collections.reverse(temp); return unmodifiableList(temp); } + /** + * Provides implicit method `take` on the {@link List} class. + * + * Example: `"#list('c','b','a').take(2)" //should return List('a','b')` + * + * @param Type of the list's elements. + * @param list The list to call this method upon. + * @param n Number of items to _take_ from the list. + * @return An unmodifiable {@link List} containing the first `n` items + * of the list. + */ public static List take(final List list, final int n) { return unmodifiableList(list.subList(0, n)); } + /** + * Provides implicit method `drop` on the {@link List} class. + * + * Example: `"#list('c','b','a').drop(2)" //should return List('a')` + * + * @param Type of the list's elements. + * @param list The list to call this method upon. + * @param n Number of items to _drop_ from the list. + * @return An unmodifiable {@link List} containing the items after the + * first `n` items of the list. + */ public static List drop(final List list, final int n) { return unmodifiableList(list.subList(n, list.size())); } diff --git a/src/main/java/net/abhinavsarkar/spelhelper/ImplicitPropertyAccessor.java b/src/main/java/net/abhinavsarkar/spelhelper/ImplicitPropertyAccessor.java index 9877490..b50ff30 100644 --- a/src/main/java/net/abhinavsarkar/spelhelper/ImplicitPropertyAccessor.java +++ b/src/main/java/net/abhinavsarkar/spelhelper/ImplicitPropertyAccessor.java @@ -1,5 +1,5 @@ /** - * + * */ package net.abhinavsarkar.spelhelper; @@ -13,11 +13,11 @@ import org.springframework.expression.MethodResolver; import org.springframework.expression.TypedValue; import org.springframework.util.Assert; -public final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAccessor { - +final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAccessor { + private static final ConcurrentHashMap cache = new ConcurrentHashMap(); - + public boolean canRead(final EvaluationContext context, final Object target, final String name) throws AccessException { @@ -26,7 +26,7 @@ public final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAcces if (cache.containsKey(cacheKey)) { return cache.get(cacheKey) != null; } - + for (MethodResolver mr : context.getMethodResolvers()) { MethodExecutor me = mr.resolve(context, target, name, new Class[0]); if (me != null) { @@ -34,7 +34,7 @@ public final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAcces return true; } } - + cache.putIfAbsent(cacheKey, null); return false; } @@ -49,5 +49,5 @@ public final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAcces throw new AccessException(MessageFormat.format( "Cannot read property: {0} of target: {1}", name, target)); } - + } \ No newline at end of file diff --git a/src/main/java/net/abhinavsarkar/spelhelper/ReadOnlyGenericPropertyAccessor.java b/src/main/java/net/abhinavsarkar/spelhelper/ReadOnlyGenericPropertyAccessor.java index a6ff27b..5636236 100644 --- a/src/main/java/net/abhinavsarkar/spelhelper/ReadOnlyGenericPropertyAccessor.java +++ b/src/main/java/net/abhinavsarkar/spelhelper/ReadOnlyGenericPropertyAccessor.java @@ -6,7 +6,7 @@ import org.springframework.expression.AccessException; import org.springframework.expression.EvaluationContext; import org.springframework.expression.PropertyAccessor; -public abstract class ReadOnlyGenericPropertyAccessor implements +abstract class ReadOnlyGenericPropertyAccessor implements PropertyAccessor { public final boolean canWrite(final EvaluationContext context, diff --git a/src/main/java/net/abhinavsarkar/spelhelper/SpelHelper.java b/src/main/java/net/abhinavsarkar/spelhelper/SpelHelper.java index 3e3496a..6b0c6de 100644 --- a/src/main/java/net/abhinavsarkar/spelhelper/SpelHelper.java +++ b/src/main/java/net/abhinavsarkar/spelhelper/SpelHelper.java @@ -15,14 +15,98 @@ import java.util.concurrent.ConcurrentHashMap; import org.springframework.expression.ConstructorResolver; import org.springframework.expression.EvaluationContext; +import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.Assert; +/** + * SpelHelper provides additional functionalities to work with + * [Spring Expression Language (SpEL)][1]. + * + * The addition functionalities provided are: + * + * 1. Implicit methods + * 2. Implicit properties + * 3. Simplified extension functions + * 4. Simplified constructors + * + * **Implicit Methods** + * + * Implicit methods allow one to registers methods with SpelHelper and attach + * them to particular classes. After that, when that method is called on an + * object of that particular class inside a SpEL expression, SpelHelper + * redirects the method call to the registered method. + * + * Example: {@link ImplicitMethods#sorted(List)} method is automatically + * registered by SpelHelper. The class that the method should be invoked for + * is the type of the first parameter of the method. In this case, the class is + * {@link List}. + * + * So when an expression like `"#list(1,4,2).sorted()"` is evaluated, the + * {@link ImplicitMethods#sorted(List)} method is invoked with the list as its + * first parameter and its return value is used in further evaluation of the + * expression. + * + * See {@link SpelHelper#registerImplicitMethodsFromClass(Class)}. + * + * **Implicit Properties** + * + * Implicit properties allow one to treat no argument methods of an object + * as properties of the object. SpelHelper intercepts the property resolution + * of SpEL and if the property name is same as some no-arg method of the target + * object then it invokes the method on the object and provides its return value + * as the property value for further evaluation of the expression. + * + * Example: Using implicit properties, the example of implicit methods can be + * written as: `"#list(1,4,2).sorted"` - dropping the parens - and it will return + * the same value as the last example. + * + * Implicit property resolution considers both the actual methods of the object + * and the implicit methods registered on the object's class. + * + * **Simplified extension functions** + * + * SpEL [allows][2] to register extension function on the context by providing a + * name and a {@link Method} object. SpelHelper simplifies this by taking a class + * and registering all the `public static` methods of the class which do not + * have a `void` return type. The methods are registered by their simple name. + * + * Example: All the methods of {@link ExtensionFunctions} class are automatically + * registered by SpelHelper. Hence the method {@link ExtensionFunctions#list(Object...)} + * can be called from inside a SpEL expression using the function call syntax: + * `"#list(1,2,3)`". + * + * See {@link SpelHelper#registerFunctionsFromClass(Class)}. + * + * **Simplified constructors** + * + * SpEL [allows][3] calling constructors from inside a SpEL expression using the + * `new` operator. But they have to be called with their full name like: + * `"new org.example.Foo('bar')"`. SpelHelper simplifies this by taking a class + * and registering all its public constructors to the SpEL context by their + * simple name. + * + * Example: After registering the `org.example.Foo` class with SpelHelper, its + * constructor can be called from inside a SpEL expression by: `"new Foo('bar')"`. + * + * See {@link SpelHelper#registerConstructorsFromClass(Class)}. + * + * In addition to all the above functionalities, SpelHelper automatically registers + * some extension functions and implicit methods which are always available in + * the SpEL expressions evaluated through SpelHelper. See {@link ExtensionFunctions} + * and {@link ImplicitMethods} for further details. + * + * [1]: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html + * [2]: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html#expressions-ref-functions + * [3]: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html#d0e11927 + * + * @author Abhinav Sarkar _abhinav@abhinavsarkar.net_ + */ public final class SpelHelper { - public static final String CONTEXT_LOOKUP_KEY = SpelHelper.class.getName(); + static final String CONTEXT_LOOKUP_KEY = SpelHelper.class.getName(); private static final ExpressionParser PARSER = new SpelExpressionParser(); private static final ThreadLocal currentContext = @@ -35,11 +119,25 @@ public final class SpelHelper { private final Map> registeredConstructors = new ConcurrentHashMap>(); - { + /** + * Creates an instance of SpelHelper. + */ + public SpelHelper() { registerFunctionsFromClass(ExtensionFunctions.class); registerImplicitMethodsFromClass(ImplicitMethods.class); } + /** + * Registers the public static methods in the class `clazz` as implicit + * methods for the class of the first parameter of the methods. + * + * Only registers the public static methods with non void return type and at + * least one argument. + * @see ImplicitMethods + * @param clazz The class to register the methods from. + * @return The current instance of SpelHelper. This is for chaining + * the methods calls. + */ public SpelHelper registerImplicitMethodsFromClass(final Class clazz) { for (Method method : filterMethods(clazz)) { registeredMethods.put(String.format( @@ -49,13 +147,31 @@ public final class SpelHelper { return this; } + /** + * Registers the public static methods in the class `clazz` as functions + * which can be called from SpEL expressions. + * The functions are registered with the simple name of the methods. + * + * Only registers the public static methods with non void return type. + * @see ExtensionFunctions + * @param clazz The class to register the functions from. + * @return The current instance of SpelHelper. This is for chaining + * the methods calls. + */ public SpelHelper registerFunctionsFromClass(final Class clazz) { - registeredFunctions.addAll(filterMethods(clazz)); + registeredFunctions.addAll(filterFunctions(clazz)); context = null; return this; } - public SpelHelper registerImplicitConstructorsFromClass(final Class clazz) { + /** + * Registers the public constructors of the class `clazz` so that they + * can be called by their simple name from SpEL expressions. + * @param clazz The class to register the constructors from. + * @return The current instance of SpelHelper. This is for chaining + * the methods calls. + */ + public SpelHelper registerConstructorsFromClass(final Class clazz) { for (Constructor constructor : asList(clazz.getConstructors())) { registeredConstructors.put( constructor.getDeclaringClass().getSimpleName() @@ -65,22 +181,58 @@ public final class SpelHelper { return this; } + /** + * Evaluates a SpEL expression `expressionString` in the context + * of root element `rootElement` and gives back a result of type + * `desiredType`. + * @param The type of the result desired. + * @param expressionString The SpEL expression to evaluate. + * @param rootElement The root element in context of which the expression + * is to be evaluated. + * @param desiredType The class of the result desired. + * @return The result of the evaluation of the expression. + * @see ExpressionParser#parseExpression(String) + * @see Expression#getValue(EvaluationContext, Class) + */ public T evalExpression(final String expressionString, final Object rootElement, final Class desiredType) { EvaluationContext evaluationContext = getEvaluationContext(rootElement); currentContext.set(evaluationContext); T value = evalExpression(expressionString, evaluationContext, desiredType); currentContext.set(null); - return value; } + /** + * Evaluates a SpEL expression `expressionString` in the provided + * context `evaluationContext` and gives back a result of type + * `desiredType`. + * @param The type of the result desired. + * @param expressionString The SpEL expression to evaluate. + * @param evaluationContext The context in which the expression is to be evaluated. + * @param desiredType The class of the result desired. + * @return The result of the evaluation of the expression. + * @see ExpressionParser#parseExpression(String) + * @see Expression#getValue(EvaluationContext, Class) + */ public T evalExpression(final String expressionString, final EvaluationContext evaluationContext, final Class desiredType) { return PARSER.parseExpression(expressionString) .getValue(evaluationContext, desiredType); } + /** + * Evaluates multiple SpEL expressions and returns the result of the last + * expression. + * @param The type of the result desired. + * @param expressionStrings The SpEL expressions to evaluate. + * @param rootElement The root element in context of which the expressions + * are to be evaluated. + * @param desiredType The class of the result desired. + * @return The result of the evaluation of the last expression. + * @see SpelHelper#evalExpression(String, EvaluationContext, Class) + * @see SpelHelper#evalExpression(String, Object, Class) + */ public T evalExpressions(final String[] expressionStrings, final Object rootElement, final Class desiredType) { int length = expressionStrings.length; @@ -93,6 +245,29 @@ public final class SpelHelper { rootElement, desiredType); } + /** + * Evaluates multiple SpEL expressions and returns the result of the last + * expression. + * @param The type of the result desired. + * @param expressionStrings The SpEL expressions to evaluate. + * @param evaluationContext The context in which the expression is to be evaluated. + * @param desiredType The class of the result desired. + * @return The result of the evaluation of the last expression. + * @see SpelHelper#evalExpression(String, EvaluationContext, Class) + * @see SpelHelper#evalExpression(String, Object, Class) + */ + public T evalExpressions(final String[] expressionStrings, + final EvaluationContext evaluationContext, final Class desiredType) { + int length = expressionStrings.length; + Assert.isTrue(length > 0, + "expressionStrings should have length more than 0"); + for (int i = 0; i < length - 1; i++) { + evalExpression(expressionStrings[i], evaluationContext, Object.class); + } + return evalExpression(expressionStrings[length - 1], + evaluationContext, desiredType); + } + private EvaluationContext getEvaluationContext(final Object rootObject) { if (context == null) { synchronized (PARSER) { @@ -113,16 +288,33 @@ public final class SpelHelper { return context; } + /** + * Looks up an implicit method registered with this instance. + * @param lookup key to lookup which should be of form: + * `method.getParameterTypes()[0].getName() + "." + method.getName()` + * @return The registered method if found, else null. + */ public Method lookupImplicitMethod(final String lookup) { Assert.notNull(lookup); return registeredMethods.get(lookup); } + /** + * Looks up an implicit constructor registered with this instance. + * @param lookup key to lookup which should be of form: + * `constructor.getDeclaringClass().getSimpleName()` + * `+ Arrays.toString(constructor.getParameterTypes())` + * @return The registered constructor if found, else null. + */ public Constructor lookupImplicitConstructor(final String lookup) { Assert.notNull(lookup); return registeredConstructors.get(lookup); } + /** + * Returns the current evaluation context. Null if there is no context. + * @return The current evaluation context. + */ public static EvaluationContext getCurrentContext() { return currentContext.get(); } @@ -140,4 +332,16 @@ public final class SpelHelper { return allowedMethods; } + private static List filterFunctions(final Class clazz) { + List allowedMethods = new ArrayList(); + for (Method method : clazz.getMethods()) { + int modifiers = method.getModifiers(); + if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) + && !method.getReturnType().equals(Void.TYPE)) { + allowedMethods.add(method); + } + } + return allowedMethods; + } + } diff --git a/src/main/javadoc/spring-javadoc.css b/src/main/javadoc/spring-javadoc.css new file mode 100644 index 0000000..6e69d80 --- /dev/null +++ b/src/main/javadoc/spring-javadoc.css @@ -0,0 +1,178 @@ +/* stylesheet.css 2008/04/22 nicolekonicki */ + +/* + * + * Spring-specific Javadoc style sheet + * + */ + + + +.code +{ + border: 1px solid black; + background-color: #F4F4F4; + padding: 5px; +} + +body +{ + font: 12px Verdana, Arial, Helvetica, "Bitstream Vera Sans", sans-serif; + background-color: #fff; + color: #333; +} + + +/* Link colors */ +a +{ + color:#2c7b14; + text-decoration:none; +} + +a:hover +{ + text-decoration:underline; +} + +/* Headings */ +h1 +{ + font-size:28px; + color:#007c00; +} + +/* Table colors */ + +table +{ + border:none; +} + +td +{ + border:none; + border-bottom:1px dotted #ddd; +} + +th +{ + border:none; +} + +.TableHeadingColor th +{ + background-color: #064F52; + background-image: url(http://static.springsource.org/spring/docs/3.0.x/javadoc-api/resources/TableHeading-background.png); + background-repeat: repeat-x; + color:#fff; + font-size:14px; + height:26px; +} + +.TableSubHeadingColor +{ + background: #f7ffee; + +} +.TableRowColor +{ + background: #fff; +} + +.TableRowColor a +{ + border-bottom:none; + color:#2c7b14; + font-weight:normal; +} + +tr.TableRowColor:hover +{ + background:#eef2e1; +} + + +/* Font used in left-hand frame lists */ +.FrameTitleFont +{ + font-size: 120%; + font-weight:bold; +} + +.FrameTitleFont a +{ + color: #333; +} + +.FrameHeadingFont +{ + font-weight: bold; + font-size:95%; +} + +.FrameItemFont +{ + line-height:130%; + font-size: 95%; +} + +.FrameItemFont a +{ + color:#333; +} + +.FrameItemFont a:hover +{ + color:#249901; + border-bottom:none; + text-decoration:underline; +} + +/* Navigation bar fonts and colors */ +.NavBarCell1 +{ + background-color:#fff; + border:none; +} + +.NavBarCell1Rev +{ + background-color:#e3faa5; + border:1px solid #9ad00c; + padding:0; + margin:0; +} + +.NavBarCell1 a +{ + color:#333; + text-decoration:none; +} + +.NavBarFont1Rev +{ + +} + +.NavBarCell2 +{ + border:none; +} + +.NavBarCell2 a +{ + color:#249901; + font-size:90%; +} + +.NavBarCell3 +{ + border:none; +} + +/* Override sizes in font tags */ +font +{ + font: inherit !important; +} diff --git a/src/test/java/net/abhinavsarkar/spelhelper/SpelHelperTest.java b/src/test/java/net/abhinavsarkar/spelhelper/SpelHelperTest.java index 6539527..75d5a40 100644 --- a/src/test/java/net/abhinavsarkar/spelhelper/SpelHelperTest.java +++ b/src/test/java/net/abhinavsarkar/spelhelper/SpelHelperTest.java @@ -36,7 +36,7 @@ public class SpelHelperTest { Assert.assertEquals( new ConstructorTest(), new SpelHelper() - .registerImplicitConstructorsFromClass(ConstructorTest.class) + .registerConstructorsFromClass(ConstructorTest.class) .evalExpression("new ConstructorTest()", new Object(), ConstructorTest.class)); }