Fix #175 - add support for array length as a property of an array
diff --git a/api/src/main/java/jakarta/el/ArrayELResolver.java b/api/src/main/java/jakarta/el/ArrayELResolver.java index 445f6e8..0da612c 100644 --- a/api/src/main/java/jakarta/el/ArrayELResolver.java +++ b/api/src/main/java/jakarta/el/ArrayELResolver.java
@@ -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>. */ @@ -116,23 +118,27 @@ } /** - * 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. */ @@ -145,6 +151,9 @@ 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);
diff --git a/spec/src/main/asciidoc/ELSpec.adoc b/spec/src/main/asciidoc/ELSpec.adoc index e502dab..434ff4c 100644 --- a/spec/src/main/asciidoc/ELSpec.adoc +++ b/spec/src/main/asciidoc/ELSpec.adoc
@@ -1269,6 +1269,14 @@ 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 @@ -3026,6 +3034,10 @@ * 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.