{"action":"created","issue":{"url":"https://api.github.com/repos/omnifaces/omnifaces/issues/279","repository_url":"https://api.github.com/repos/omnifaces/omnifaces","labels_url":"https://api.github.com/repos/omnifaces/omnifaces/issues/279/labels{/name}","comments_url":"https://api.github.com/repos/omnifaces/omnifaces/issues/279/comments","events_url":"https://api.github.com/repos/omnifaces/omnifaces/issues/279/events","html_url":"https://github.com/omnifaces/omnifaces/issues/279","id":163194216,"number":279,"title":"Feature request: Add method getMethodReference for MethodExpression parameter","user":{"login":"dmaidaniuk","id":12764116,"avatar_url":"https://avatars.githubusercontent.com/u/12764116?v=3","gravatar_id":"","url":"https://api.github.com/users/dmaidaniuk","html_url":"https://github.com/dmaidaniuk","followers_url":"https://api.github.com/users/dmaidaniuk/followers","following_url":"https://api.github.com/users/dmaidaniuk/following{/other_user}","gists_url":"https://api.github.com/users/dmaidaniuk/gists{/gist_id}","starred_url":"https://api.github.com/users/dmaidaniuk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmaidaniuk/subscriptions","organizations_url":"https://api.github.com/users/dmaidaniuk/orgs","repos_url":"https://api.github.com/users/dmaidaniuk/repos","events_url":"https://api.github.com/users/dmaidaniuk/events{/privacy}","received_events_url":"https://api.github.com/users/dmaidaniuk/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":4,"created_at":"2016-06-30T15:26:24Z","updated_at":"2016-07-06T12:03:59Z","closed_at":"2016-07-06T12:03:15Z","body":"In our project we extended OmniFaces `ExpressionInspector` by one more additional method `MethodReference getMethodReference(ELContext elContext, MethodExpression methodExpression)`. Method is pretty obvious as ongoing  for existing similar method for `ValueExpression`. And it could be useful for other OmniFaces users.\r\nThat's how it looks like on OmniFaces v1.8.3 code base:\r\n```\r\npackage org.omnifaces.el.experimental;\r\n\r\nimport javax.el.ELContext;\r\nimport javax.el.ELException;\r\nimport javax.el.ExpressionFactory;\r\nimport javax.el.MethodExpression;\r\nimport javax.el.PropertyNotFoundException;\r\nimport javax.el.ValueExpression;\r\nimport javax.el.ValueReference;\r\nimport javax.faces.view.facelets.FaceletContext;\r\nimport org.omnifaces.el.ExpressionInspector;\r\nimport static org.omnifaces.el.ExpressionInspector.findMethod;\r\nimport static org.omnifaces.el.ExpressionInspector.getValueReference;\r\nimport org.omnifaces.el.MethodExpressionValueExpressionAdapter;\r\nimport org.omnifaces.el.MethodReference;\r\nimport org.omnifaces.util.Faces;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\npublic final class ExtendedExpressionInspector extends ExpressionInspector {\r\n\r\n\tprivate static final Logger log = LoggerFactory.getLogger(ExtendedExpressionInspector.class);\r\n\r\n    private ExtendedExpressionInspector() {\r\n    }\r\n    \r\n    /**\r\n     * Gets a MethodReference from a MethodExpression.\r\n     * <p>\r\n     * Note that the method reference contains <em>a</em> method with the name the expression refers to. Overloads are\r\n     * not supported.\r\n     * <p>\r\n     * Reused <code>ExpressionInspector#getValueReference(...)</code> method to apply advanced OmniFaces ELContext wrapper.\r\n     * Standard <code>com.sun.faces.el.ELContextImpl</code> has problems with resolving parameterized methods.\r\n     * <p>\r\n     * @param elContext the context of this evaluation\r\n     * @param methodExpression the method expression being evaluated\r\n     * @return a MethodReference holding the final base and Method where the value expression evaluated to or NULL.\r\n     */\r\n    public static MethodReference getMethodReference(ELContext elContext, MethodExpression methodExpression) {\r\n        \r\n        MethodReference methodReference = null;\r\n        if (methodExpression == null) {\r\n            return methodReference;\r\n        }\r\n        \r\n        String expr = methodExpression.getExpressionString();\r\n        try {\r\n        \r\n            ExpressionFactory factory = Faces.getApplication().getExpressionFactory();\r\n            ValueExpression valueExpression = factory.createValueExpression(elContext, expr, Object.class);\r\n\r\n            methodReference = getSafelyMethodReference(elContext, valueExpression);\r\n            if (methodReference == null) {                 \r\n                methodReference = getMethodReferenceInFaceletContext(factory, expr);\r\n            }\r\n        }\r\n        catch (ELException e) {\r\n            if (log.isTraceEnabled()) {\r\n                log.trace(\"Error during evaluation: \" + e.getMessage());\r\n            }\r\n        }\r\n        return methodReference;\r\n    }\r\n\r\n    /**\r\n     * Protected from NullPointerException implementation of <code>ExpressionInspector.getMethodReference(...)</code> method.\r\n     * Also caught <code>PropertyNotFoundException</code> in case if base class redefined by <code>ui:param</code>.\r\n     * <p>\r\n     * \r\n     * @param elContext\r\n     * @param valueExpression\r\n     * @return MethodReference of given valueExpression or NULL\r\n     */\r\n    public static MethodReference getSafelyMethodReference(ELContext elContext, ValueExpression valueExpression) {\r\n        try {\r\n            ValueReference valueReference = getValueReference(elContext, valueExpression);\r\n            Object base = valueReference.getBase();\r\n            Object methodName = valueReference.getProperty();\r\n            if (base != null && methodName != null) {\r\n                return new MethodReference(base, findMethod(base, methodName.toString()));\r\n            }\r\n        }\r\n        catch (PropertyNotFoundException ex) {\r\n            if (log.isTraceEnabled()) {\r\n                log.trace(\"Error during evaluation: \" + ex.getMessage());\r\n            }\r\n        }\r\n        return null;\r\n    }\r\n\r\n    private static MethodReference getMethodReferenceInFaceletContext(ExpressionFactory factory, String expr) {\r\n        // UI Param case first\r\n        FaceletContext faceletElContext = Faces.getFaceletContext();\r\n        ValueExpression exp = factory.createValueExpression(faceletElContext, expr, Object.class);\r\n        MethodReference methodReference = getSafelyMethodReference(faceletElContext, exp);\r\n        if (methodReference == null) { // OmniFaces MethodParam case next\r\n            Object faceletValue = exp.getValue(faceletElContext);\r\n            if (faceletValue instanceof MethodExpressionValueExpressionAdapter) {\r\n                ValueExpression originExpression = ((MethodExpressionValueExpressionAdapter)faceletValue).getValueExpression();\r\n                methodReference = getSafelyMethodReference(faceletElContext, originExpression);\r\n            }\r\n        }\r\n        return methodReference;\r\n    }\r\n    \r\n}\r\n```\r\nI'm not sure that given implementation is optimal. However it works quite good for us.\r\nAlso if such method will be included into OmniFaces it will be easier for us to migrate to latest OmniFaces 2.x version, where `ExpressionInspector` was significantly changed.\r\n\r\nThanks,\r\nDmytro"},"comment":{"url":"https://api.github.com/repos/omnifaces/omnifaces/issues/comments/230752594","html_url":"https://github.com/omnifaces/omnifaces/issues/279#issuecomment-230752594","issue_url":"https://api.github.com/repos/omnifaces/omnifaces/issues/279","id":230752594,"user":{"login":"BalusC","id":173372,"avatar_url":"https://avatars.githubusercontent.com/u/173372?v=3","gravatar_id":"","url":"https://api.github.com/users/BalusC","html_url":"https://github.com/BalusC","followers_url":"https://api.github.com/users/BalusC/followers","following_url":"https://api.github.com/users/BalusC/following{/other_user}","gists_url":"https://api.github.com/users/BalusC/gists{/gist_id}","starred_url":"https://api.github.com/users/BalusC/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BalusC/subscriptions","organizations_url":"https://api.github.com/users/BalusC/orgs","repos_url":"https://api.github.com/users/BalusC/repos","events_url":"https://api.github.com/users/BalusC/events{/privacy}","received_events_url":"https://api.github.com/users/BalusC/received_events","type":"User","site_admin":false},"created_at":"2016-07-06T12:03:59Z","updated_at":"2016-07-06T12:03:59Z","body":"It's available in today's latest [2.5-SNAPSHOT](https://oss.sonatype.org/content/repositories/snapshots/org/omnifaces/omnifaces/2.5-SNAPSHOT). Please let me know if everything works for you."}}
{"actor":{"display_login":"BalusC"}}