Coder Social home page Coder Social logo

el-spec's People

Contributors

glassfishrobot avatar pranjal10 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

el-spec's Issues

ImportHandler should allow interfaces and abstract classes

It's not mentioned in 3.0 spec, but the API comment for ImportHandler#resolveClass says that it @throws ELException if the class is not public, or is abstract or is an interface., and implementations seem to enforce this. It may not be a best practice to reference static members via an interface, but it does happen, and with Java 8's added support for static methods on interfaces, this seemingly opinionated restriction should be removed from the API and left as a code style decision for the caller as it would be in the broader Java language.

Importing a (public, concrete) nested static class does not work

Hello; I am not sure if this is a specification issue, or a reference implementation issue.

If I define a static nested class that is public and non-abstract, and then attempt to import it using ImportHandler#importClass(String), it does not get imported.

Unavailable

This issue was unavailable for migration from original issue tracker.

Clarify how single variable evaluates to method

Section 1.2.1.2 in the EL specification mentions that a method expression can consist of a single variable:

A method expression shares the same syntax as an lvalue. 
That is, it can only consist of either a single variable
(e.g. ${name}) or a property resolution on some object, 
via the . or [] operator (e.g. ${employee.name}).

As it appears, it's not entirely clear how such single variable should be evaluated.

In the reference implementation for example, we see that in this case a MethodExpressionImpl will reference an AstIdentifier, which will use the context's variable mapper to obtain a ValueExpression. The value is then obtained from this value expression, and it's expected to be a MethodExpression, which is then invoked.

This can be seen at http://java.net/projects/el-spec/sources/source-code/content/trunk/impl/src/main/java/com/sun/el/parser/AstIdentifier.java?rev=198 where the method getMethodExpression at line 198 demonstrates the "value expression wrapping a method expression" assumption. invoke at line 183 then shows this obtained method expression is simply invoked.

Comments on line 198 and 209 explicitly mention 2 cases:

case A: ValueExpression exists, getValue which must
be a MethodExpression

[...]

case B: evaluate the identity against the ELResolver, again, must be
a MethodExpression to be able to invoke

These cases however are not outlined in the specification. As a result, alternative EL implementations (like JUEL) have taken a completely different approach. In the case of JUEL, it also expects a ValueExpression, but then guessed that this value expression should be wrapping a Method. This on its turn leads to unexpected behavior and bugs such as reported here: http://code.google.com/p/omnifaces/issues/detail?id=100

In order to ensure portability between EL implementations, I would like to request this specific case to be clarified in the specification.

Access public fields

There is an increasingly recommended practice of disallowing entities in the presentation layer, and instead just passing DTOs. Since DTOs don't have any behavior, nor are they persistent, and because their very purpose is to simply hold and serve data, there is no reason to encapsulate their fields. So there is no reason what DTO fields shouldn't be public, since getters & setters don't add any value to them.

It would therefore be great if EL could access public fields, to save developers the bother of having to add needless getters & setters:

public class PersonDTO

{ public String name; }

$

{person.name}

Environment

Any

MethodExpression.getMethodInfo() always returns null

When invoking getMethodInfo() on a method expression, I always get null.

This seems to be caused by AstValue.getMethodInfo():

public MethodInfo getMethodInfo(EvaluationContext ctx, Class[] paramTypes)
            throws ELException {
        Target t = getTarget(ctx);
        if (t.isMethodCall()) {
            return null;
        }
        Object property = t.suffixNode.getValue(ctx);
        Method m = ReflectionUtil.getMethod(t.base, property, paramTypes);
        return new MethodInfo(m.getName(), m.getReturnType(), m
.getParameterTypes());
    }

Shouldn't this be

if ( ! t.isMethodCall()) {
    return null;
}

Environment

javax.el-3.0.0.jar standalone, Oracle Java 1.7.0_45 on Linux 64-bit

ELProcessor.defineFunction methods do not check for null args...

API documentation states for both of the defineFunction methods that a NullPointerException should be thrown if any arg is null. Niether on of the methods looks to be testing for null args.

Example below.

public void defineFunction(String prefix, String function, Method method) {

if (prefix == null || function == null || method == null)

{ <-- need to add something like this. throw new NullPointerException(); }

if (function.equals(""))

{ function = method.getName(); }

elManager.mapFunction(prefix, function, method);
}

Environment

N/A

Collections defaultIfEmpty operator does not exist

There appears to be no code for defaultIfEmpty operator.

products.orderByDescending(p->p.unitPrice).elementAtOrDefault(3).defaultIfEmpty()
ERROR: Exception at:
ERROR: javax.el.MethodNotFoundException:

Environment

N/A

Property support for Optional<T>

Expression language in Java EE 8 should bring special treatment for java.util.Optional, similar like it does for maps and lists:

When a base expression evaluates to instance of java.util.Optional, and the property name is not equal present, the result of the evaluation shall be equivalent to calling method map or flatMap on the optional:

  • if the base {{Optional]} has value:
    1. evaluate the property against the value of the property,
    2. if the result of an evaluation is instance of an Optional
      • return the value; otherwise
      • return the value wrapped in an Optional
  • if base optional, doesn't have value, return Optional.empty()

The property present is evaluated by invoking the method isPresent() of the base object.

An example of implementation of this behaviour can be found in this ELResolver implementation.

Make it possible to use javax.el.LambdaExpression in place of java se 8 functional interfaces

Since EL Lambdas predate Java functional interfaces, custom EL resolvers must be used to as bridge between javax.el.LambdaExpression, and actual method with a accepting functional interface parameter.

Java EE 8 revision of EL should either

  1. bring sufficient support for all Java SE methods accepting functional interfaces, or
  2. offer implicit type conversion from LambdaExpression to appropriate types defined in java.util.function, or
  3. offer implicit conversion to any Functional interface conforming to §9.8 of JLS.

Example implementation of the first approach for java.util.Optional can be seen here

Reduce source/target from 1.7 to 1.6

Currently the el api and impl are set to source/target 1.7

However, there are no functional requirement or features of the 1.7 JRE used.

The only current barrier is with tests which fail when set to 1.6. However, when skipping tests, el compiles quite fine.

This has a transitive cost of imposing 1.7 on JSP also.

Static fields and methods are evaluated to null in Facelets

When I use static field or method within Facelet, it's value is evaluated to null.

Example:

{Integer.MAX_VALUE}

{Integer.toHexString(16)}

Or this shows in the rendered page that result of the static call was null

{[0, 1, Integer.MAX_VALUE]}

Environment

GF4.0, JSF2.2

Javadoc for ExpressionFactory#getInitFunctionMap is incorrect

The javadoc for ExpressionFactory#getInitFunctionMap says:

/**
     * Retrieve a function map containing a pre-configured function
     * mapping.  It must include the following functions.
     * <ul>
     * <li>linq:range</li>
     * <li>linq:repeat</li>
     * <li>linq:_empty</li>
     * </ul>
     * @return A initial map for functions, null if there is none.
     *
     * @since EL 3.0
     */

This is not correct, as EL 3.0 no longer has to support these functions.

Backwards Compatibility Issue with Binary Operator "+"

In section 1.7.1 Binary Operators of the Expression Language Specification Version 3.0, there has been an additional Rule added that causes a Backwards compatibility issue.

From version 3.0 of the specification its states the following:

1.7.1 Binary operators - A {+,-,*} B
■ If the operator is a +, and either A or B is a String, then + is a string concatenation <---- This is the newly added Rule.
operator.
■ If A and B are null, return (Long)0
■ If A or B is a BigDecimal, coerce both to BigDecimal and then:
■ If operator is +, return A.add(B)
■ If operator is -, return A.subtract(B)
■ If operator is *, return A.multiply(B)
■ If A or B is a Float, Double, or String containing ., e, or E: <---------- This Rule never gets reached now !!!!!
■ If A or B is BigInteger, coerce both A and B to BigDecimal and apply
operator.
■ Otherwise, coerce both A and B to Double and apply operator
■ If A or B is BigInteger, coerce both to BigInteger and then:
■ If operator is +, return A.add(B)
■ If operator is -, return A.subtract(B)
■ If operator is *, return A.multiply(B)
■ Otherwise coerce both A and B to Long and apply operator
■ If operator results in exception, error

The problem with the newly added rule at the top of the order is that they " If A or B is a Float, Double, or String containing ., e, or E:" Never gets a chance to be parsed. This breaks backwards compatibility.

Environment

N/A

Stream operators anyMatch, allMatch, and nonMatch should return boolean

The stream operators anyMatch, allMatch, and noneMatch returns an Optional, while those operators in JDK 8 (java.util.stream#Stream) returns a boolean. This difference is confusing. EL spec should be changed to agree with JDK 8.

The difference happened because EL 3.0 spec was released before Java SE 8. Now that SE 8 was release, EL should be brought up to date.

Collections average operator does not return null

The specification states the following for the average operator section 2.3.44.2

"The average operator returns null for an empty collection."

The below should return null and does not.

"[].average()"

Environment

N/A

Rewrite the spec for collection support

The EL spec needs to align with Java Se8 regarding the support for collection operators. The part about LINQ operator needs to be removed, and replace with similar operations in SE 8.

The operators also need to be implemented.

null string value is converted to ""

null string from JSF is converted to empty string.
I traced to code com.sun.el.lang.ELSupport 350. Should this decision be left to EL client?

Environment

glassfish 4.0, el 3.0

API doc errors for javax.el.TypeConverter

Here is the Example that we have provided in the API docs.

ELProcessor elp = new ELProcessor();
elp.getELManager().addELResolver(new TypeConverter() {
Object convertToType(ELContext context, Object obj, Class type) {
if (obj instanceof String) && type == MyDate.class)

{ context.setPropertyResoved(obj, type); return (obj == null)? null: new MyDate(obj.toString()); }

return null;
}
};

Below I have put the various fixes in spelling and syntax.

ELProcessor elp = new ELProcessor();
elp.getELManager().addELResolver(new TypeConverter() {
Object convertToType(ELContext context, Object obj, Class type) {
if ((obj instanceof String) && type == MyDate.class)

{ <------ Added missing "(" context.setPropertyResolved(obj, type); <------ Fixed Spelling on Method call. return (obj == null)? null: new MyDate(obj.toString()); }

return null;
}
};

Environment

N/A

null String are converted to "" on the bound bean properties

Change the spec like this:

  • 1.23.1, If X is null and Y is not a primitive type, return null.
  • 1.23.2, If A is null: return null

Justification:

JSF uses EL expressions to get and set bean properties. With the String behavior as defined in EL spec 3 null String will be converted to "" also without any user input. This is wrong behavior - null String should remain null also after an form edit roundtrip.

JSF has explicitly a parameter to define if empty String input should be handled as null. With EL 3 this null handling is rendered useless.

The problematic sections in the spec are:

  • 1.2.1 the part: In the case of lvalues, the expected type is ignored and the provided value is coerced to the actual type of the property the expression points to, before that property is set.
  • 1.23.1, If X is null and Y is not a primitive type and also not a String, return null.
  • 1.23.2, If A is null: return ""

1.2.1 is problematic for JSF using mostly Object.class as expected type for ValueExpression - but according to 1.2.1 in VE.setValue(elContext, value) the expected type is ignored and therefore the String specific exceptional rules in 1.23.1 and 1.23.2 cause null to "" conversion in VE.setValue(elContext, value).

Looking at the rules 1.23.3 - 1.23.6 for all other non-primitive types null is always remaining null. Why not also for String - it's also a non-primitive.

javax.el.BeanELResolver.setValue inconsistent javadoc

Hi,

EL 3.0 javadoc javax.el.BeanELResolver.setValue describes:

...
If the property exists but does not have a setter, then a PropertyNotFoundException is thrown.
...
PropertyNotWritableException - if this resolver was constructed in read-only mode, or if there is no setter for the property.
...

Can you please clarify which exception should be thrown when the property does not have a setter method?

Thanks
Violeta

Accessing properties of a bean implementing the Map interface

Hello all,

we are trying to access properties of a Java-bean implementing the Map interface with an EL-expression like "#{bean.property}" which always yields null. Is this a bug or is it specified? Please see the following testcase for details.

public class ElTestCase {

    private ELProcessor elProcessor;

    @Before
    public void before() {
        elProcessor = new ELProcessor();
        TestMapWithProperty test = new TestMapWithProperty("hello");
        test.put("entry", "world");
        elProcessor.defineBean("test", test);
    }

    @Test
    public void property() {
        // fails because the expression evaluates to null
        assertThat( elProcessor.eval("test.property"), is("hello") );
    }

    @Test
    public void property_II() {
        // fails because the expression evaluates to null
        assertThat( elProcessor.eval("test['property']"), is("hello") );
    }

    @Test
    public void entry() {
        // success
        assertThat( elProcessor.eval("test.entry"), is("world") );
    }

    public static class TestMapWithProperty extends HashMap<String, String> {
        private String property;

        public TestMapWithProperty(String property) {
            this.property = property;
        }

        public String getProperty() {
            return property;
        }
    }
}

The EL-Implementation we are using is

    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.1-b10</version>
    </dependency>

TypeConverter API documentation does not match impl.

According to the API documentation all the methods except for "convertToType" are and say exactly what the ELRosolver would do. But the Imp for any of these methods(listed below) do nothing or return null. the

getCommonPropertyType
getFeatureDescriptors
getType
getValue
isReadOnly
setValue

Example:

From the src for getValue

@OverRide
public Object getValue(ELContext context,
Object base,
Object property)

{ return null; }

This is what the Javadoc says

public Object getValue(ELContext context,
Object base,
Object property)
Description copied from class: ELResolver
Attempts to resolve the given property object on the given base object.
If this resolver handles the given (base, property) pair, the propertyResolved property of the ELContext object must be set to true by the resolver, before returning. If this property is not true after this method is called, the caller should ignore the return value.

Specified by:
getValue in class ELResolver
Parameters:
context - The context of this evaluation.
base - The base object whose property value is to be returned, or null to resolve a top-level variable.
property - The property or variable to be resolved.
Returns:
If the propertyResolved property of ELContext was set to true, then the result of the variable or property resolution; otherwise undefined.

Environment

N/A

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.