Skip to content

Commit

Permalink
Fix #175 - add support for array length as a property of an array
Browse files Browse the repository at this point in the history
  • Loading branch information
markt-asf committed Apr 12, 2023
1 parent 6747e54 commit 94cb7ce
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
31 changes: 20 additions & 11 deletions api/src/main/java/jakarta/el/ArrayELResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
*/
public class ArrayELResolver extends ELResolver {

private static final String LENGTH_PROPERTY_NAME = "length";

/**
* Creates a new read/write <code>ArrayELResolver</code>.
*/
Expand Down Expand Up @@ -116,23 +118,27 @@ public Class<?> getType(ELContext context, Object base, Object property) {
}

/**
* If the base object is a Java language array, returns the value at the given index. The index is specified by the
* <code>property</code> argument, and coerced into an integer. If the coercion could not be performed, an
* <code>IllegalArgumentException</code> is thrown. If the index is out of bounds, <code>null</code> is returned.
* If the base object is a Java language array, returns the length of the array or the value at the given index. If
* the {@code property} argument is the case sensitive string {@code "length"}, then the length of the array is
* returned. Otherwise, the {@code property} argument is coerced into an integer and used as the index of the value
* to be returned. If the coercion could not be performed, an {@code IllegalArgumentException} is thrown. If the
* index is out of bounds, {@code null} is returned.
*
* <p>
* If the base is a Java language array, the <code>propertyResolved</code> property of the <code>ELContext</code> object
* must be set to <code>true</code> by this resolver, before returning. If this property is not <code>true</code> after
* this method is called, the caller should ignore the return value.
* If the base is a Java language array, the {@code propertyResolved} property of the {@code ELContext} object must
* be set to {@code true} by this resolver, before returning. If this property is not {@code true} after this method
* is called, the caller should ignore the return value.
* </p>
*
* @param context The context of this evaluation.
* @param base The array to analyze. Only bases that are Java language arrays are handled by this resolver.
* @param property The index of the value to be returned. Will be coerced into an integer.
* @return If the <code>propertyResolved</code> property of <code>ELContext</code> was set to <code>true</code>, then
* the value at the given index or <code>null</code> if the index was out of bounds. Otherwise, undefined.
* @throws IllegalArgumentException if the property could not be coerced into an integer.
* @throws NullPointerException if context is <code>null</code>.
* @param property Either the string {@code "length"} or the index of the value to be returned. An index value will
* be coerced into an integer.
* @return If the {@code propertyResolved} property of {@code ELContext} was set to {@code true}, then the length of
* the array, the value at the given index or {@code null} if the index was out of bounds. Otherwise, undefined.
* @throws IllegalArgumentException if the property was not the string {@code "length"} and could not be coerced
* into an integer.
* @throws NullPointerException if context is {@code null}.
* @throws ELException if an exception was thrown while performing the property or variable resolution. The thrown
* exception must be included as the cause property of this exception, if available.
*/
Expand All @@ -145,6 +151,9 @@ public Object getValue(ELContext context, Object base, Object property) {

if (base != null && base.getClass().isArray()) {
context.setPropertyResolved(base, property);
if (LENGTH_PROPERTY_NAME.equals(property)) {
return Integer.valueOf(Array.getLength(base));
}
int index = toInteger(property);
if (index >= 0 && index < Array.getLength(base)) {
return Array.get(base, index);
Expand Down
12 changes: 12 additions & 0 deletions spec/src/main/asciidoc/ELSpec.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,14 @@ the EL, `mySuit`, that is a `Spade`. If you want to test for equality with
the `Spade` enum, you would say `${mySuit == 'Spade'}`. The type of the
`mySuit` will trigger the invocation of `Enum.valueOf(Suit.class, 'Spade')`.


=== Arrays

In addition to accessing array elements by index, the unified EL also supports
the property `length` for arrays which will return the length of the array as an
integer.


=== Static Field and Method Reference

A static field or static method of a Java
Expand Down Expand Up @@ -3026,6 +3034,10 @@ This appendix is non-normative.

* Add a JPMS module descriptor that defines the module name as `jakarta.el`.

* https://github.com/jakartaee/expression-language/issues/175[#175]
Add a special case for the property `length` to the `ArrayELResolver` that
returns the length of the array.

* https://github.com/jakartaee/expression-language/issues/183[#183]
Avoid a `NullPointerException` when passing `null` for varargs.

Expand Down

0 comments on commit 94cb7ce

Please sign in to comment.