This is an automated email from the ASF dual-hosted git repository.
doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git
The following commit(s) were added to refs/heads/master by this push:
new 4d9df87 EMPIREDB-306 Improved EL ValueExpression unwrapping
4d9df87 is described below
commit 4d9df8784d81bdf944b9cd3c87452efb38ed9728
Author: Rainer Döbele <[email protected]>
AuthorDate: Wed Oct 23 10:54:10 2019 +0200
EMPIREDB-306
Improved EL ValueExpression unwrapping
---
.../empire-db-example-jsf2/.gitignore | 1 +
empire-db-jsf2/.gitignore | 1 +
.../empire/jsf2/impl/MojarraImplementation.java | 41 +------
.../empire/jsf2/impl/MyFacesImplementation.java | 41 +------
.../java/org/apache/empire/jsf2/pages/Page.java | 8 ++
.../empire/jsf2/utils/TagEncodingHelper.java | 10 +-
.../jsf2/utils/ValueExpressionUnwrapper.java | 125 +++++++++++++++++++++
empire-db/.gitignore | 1 +
8 files changed, 147 insertions(+), 81 deletions(-)
diff --git a/empire-db-examples/empire-db-example-jsf2/.gitignore
b/empire-db-examples/empire-db-example-jsf2/.gitignore
index 55ee6c2..22247c2 100644
--- a/empire-db-examples/empire-db-example-jsf2/.gitignore
+++ b/empire-db-examples/empire-db-example-jsf2/.gitignore
@@ -5,3 +5,4 @@
/.tomcatplugin
/.apt_generated/
/.factorypath
+/.apt_generated_tests/
diff --git a/empire-db-jsf2/.gitignore b/empire-db-jsf2/.gitignore
index 91dd769..c49244b 100644
--- a/empire-db-jsf2/.gitignore
+++ b/empire-db-jsf2/.gitignore
@@ -4,3 +4,4 @@
/.project
/.apt_generated/
/.factorypath
+/.apt_generated_tests/
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
index 441f5d8..9027dd4 100644
---
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MojarraImplementation.java
@@ -19,13 +19,11 @@
package org.apache.empire.jsf2.impl;
import javax.el.ValueExpression;
-import javax.el.VariableMapper;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
-import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.StringUtils;
import org.apache.empire.exceptions.ItemExistsException;
+import org.apache.empire.jsf2.utils.ValueExpressionUnwrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -112,41 +110,8 @@ public class MojarraImplementation implements
FacesImplementation
{ // cast and getWrapped
ve = ((TagValueExpression)ve).getWrapped();
}
- // now unwrap ValueExpressionImpl
- if (ve!=null)
- { // expected: ve = org.apache.el.ValueExpressionImpl
- if
(ve.getClass().getName().equals("org.apache.el.ValueExpressionImpl"))
- { // get the Node
- Object node = ObjectUtils.invokeSimplePrivateMethod(ve,
"getNode");
- if (node!=null)
- { // we have a Node
- // now get the Image
- String image =
StringUtils.toString(ObjectUtils.invokeSimpleMethod(node, "getImage"));
- if (StringUtils.isNotEmpty(image))
- { // find the varMapper
- Object varMapper =
ObjectUtils.getPrivateFieldValue(ve, "varMapper");
- if (varMapper!=null)
- { // Resolve variable using mapper
- log.debug("Resolving el-variable \"{}\" using
VariableMapper", image);
- VariableMapper vm = (VariableMapper)varMapper;
- ve = vm.resolveVariable(image);
- } else {
- // Variable not provided!
- ve = null;
- }
- } else {
- // no image: unwrapping not necessary
- // use original ValueExpression!
- }
- }
- } else {
- // unexpected
- log.warn("Unexpected ValueExpression-Implementation: {}",
ve.getClass().getName());
- log.warn("ValueExpression unwrapping does not work!");
- }
- }
- // done
- return ve;
+ // now unwrap using the ValueExpressionUnwrapper
+ return ValueExpressionUnwrapper.getInstance().unwrap(ve);
}
}
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
index be00d29..a88936f 100644
---
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/impl/MyFacesImplementation.java
@@ -20,14 +20,12 @@ package org.apache.empire.jsf2.impl;
import javax.el.ELContext;
import javax.el.ValueExpression;
-import javax.el.VariableMapper;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
-import org.apache.empire.commons.ObjectUtils;
-import org.apache.empire.commons.StringUtils;
import org.apache.empire.exceptions.ItemExistsException;
+import org.apache.empire.jsf2.utils.ValueExpressionUnwrapper;
import org.apache.myfaces.config.RuntimeConfig;
import org.apache.myfaces.config.impl.digester.elements.ManagedBeanImpl;
import org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression;
@@ -99,41 +97,8 @@ public class MyFacesImplementation implements
FacesImplementation
{ // cast and getWrapped
ve = ((ContextAwareTagValueExpression)ve).getWrapped();
}
- // now unwrap ValueExpressionImpl
- if (ve!=null)
- { // expected: ve = org.apache.el.ValueExpressionImpl
- if
(ve.getClass().getName().equals("org.apache.el.ValueExpressionImpl"))
- { // get the Node
- Object node = ObjectUtils.invokeSimplePrivateMethod(ve,
"getNode");
- if (node!=null)
- { // we have a Node
- // now get the Image
- String image =
StringUtils.toString(ObjectUtils.invokeSimpleMethod(node, "getImage"));
- if (StringUtils.isNotEmpty(image))
- { // find the varMapper
- Object varMapper =
ObjectUtils.getPrivateFieldValue(ve, "varMapper");
- if (varMapper!=null)
- { // Resolve variable using mapper
- log.debug("Resolving el-variable \"{}\" using
VariableMapper", image);
- VariableMapper vm = (VariableMapper)varMapper;
- ve = vm.resolveVariable(image);
- } else {
- // Variable not provided!
- ve = null;
- }
- } else {
- // no image: unwrapping not necessary
- // use original ValueExpression!
- }
- }
- } else {
- // unexpected
- log.warn("Unexpected ValueExpression-Implementation: {}",
ve.getClass().getName());
- log.warn("ValueExpression unwrapping does not work!");
- }
- }
- // done
- return ve;
+ // now unwrap using the ValueExpressionUnwrapper
+ return ValueExpressionUnwrapper.getInstance().unwrap(ve);
}
}
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
index 47a4bd4..1ef2881 100644
--- a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
+++ b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/pages/Page.java
@@ -42,6 +42,7 @@ import org.apache.empire.jsf2.app.FacesUtils;
import org.apache.empire.jsf2.app.TextResolver;
import org.apache.empire.jsf2.app.WebApplication;
import org.apache.empire.jsf2.utils.ParameterMap;
+import org.apache.empire.jsf2.utils.ParameterObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -394,6 +395,13 @@ public abstract class Page implements Serializable
return app.getConnectionForRequest(FacesUtils.getContext(), db);
}
+ public <T extends ParameterObject> T getObjectFromParam(Class<T>
paramType, String idParam)
+ {
+ FacesContext fc = FacesUtils.getContext();
+ ParameterMap paramMap = FacesUtils.getParameterMap(fc);
+ return paramMap.get(paramType, idParam);
+ }
+
public Object[] getKeyFromParam(DBRowSet rowset, String idParam)
{
FacesContext fc = FacesUtils.getContext();
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
index b5683a9..e30a44d 100644
---
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/TagEncodingHelper.java
@@ -997,14 +997,14 @@ public class TagEncodingHelper implements NamingContainer
if (ve != null)
{ // We have a ValueExpression!
// Now unwrap for Facelet-Tags to work
- String originalExpr = ve.getExpressionString(); //
log.isDebugEnabled() ? ve.getExpressionString() : null;
+ String originalExpr = (log.isDebugEnabled() ?
ve.getExpressionString() : null);
ve = FacesUtils.getFacesImplementation().unwrapValueExpression(ve);
if (originalExpr!=null)
{ // log result
- if (ve!=null)
- log.info("ValueExpression \"{}\" has been resolved to
\"{}\" from class {}", originalExpr, ve.getExpressionString(),
ve.getClass().getName());
- else
- log.info("ValueExpression \"{}\" has been resolved to
NULL", originalExpr);
+ if (ve!=null && !originalExpr.equals(ve.getExpressionString()))
+ log.debug("ValueExpression \"{}\" has been resolved to
\"{}\" from class {}", originalExpr, ve.getExpressionString(),
ve.getClass().getName());
+ else if (ve==null)
+ log.debug("ValueExpression \"{}\" has been resolved to
NULL", originalExpr);
}
}
// store result to avoid multiple detection
diff --git
a/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ValueExpressionUnwrapper.java
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ValueExpressionUnwrapper.java
new file mode 100644
index 0000000..d3b0521
--- /dev/null
+++
b/empire-db-jsf2/src/main/java/org/apache/empire/jsf2/utils/ValueExpressionUnwrapper.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.jsf2.utils;
+
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ValueExpressionUnwrapper
+ * @author doebele
+ *
+ * This class is used to unwrap nested ValueExpressions
+ * This is useful for Faclet-Taglib-Tags, that forward attributes which may or
may not be provided for the tag.
+ *
+ * IMPORTANT: The expression in the Facelet-Tag must use a '$' character
instead of a '#'
+ *
+ * Here is an example for such a tag
+ <ui:composition
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:e="http://java.sun.com/jsf/composite/empire">
+ <tr>
+ <e:control
+ column="#{column}"
+ record="#{record}"
+ value="${value}"
+ </e:control>
+ </tr>
+ </ui:composition>
+ *
+ * In this example the "${value}" will be unwrapped from the TagEncodingHelper
in order to dectect
+ * whether or not an expression has been provided.
+ */
+public class ValueExpressionUnwrapper
+{
+ // Logger
+ private static final Logger log =
LoggerFactory.getLogger(ValueExpressionUnwrapper.class);
+
+ private static ValueExpressionUnwrapper instance = null;
+
+ public static synchronized ValueExpressionUnwrapper getInstance()
+ {
+ if (instance==null)
+ instance = new ValueExpressionUnwrapper();
+ return instance;
+ }
+
+ public static synchronized void setInstance(ValueExpressionUnwrapper
instance)
+ {
+ ValueExpressionUnwrapper.instance = instance;
+ }
+
+ protected ValueExpressionUnwrapper()
+ {
+ log.debug("Instance of {} created", this.getClass().getName());
+ }
+
+ public ValueExpression unwrap(ValueExpression ve)
+ { // now unwrap ValueExpressionImpl
+ if (ve!=null && !ve.isLiteralText())
+ { // immediate evaluation?
+ String expression = ve.getExpressionString();
+ if (expression.startsWith("${"))
+ { // expected: ve = org.apache.el.ValueExpressionImpl
+ if
(ve.getClass().getName().equals("org.apache.el.ValueExpressionImpl"))
+ { // get the Node
+ Object node = ObjectUtils.invokeSimplePrivateMethod(ve,
"getNode");
+ if (node!=null)
+ { // We have a Node
+ // Now get the Image
+ String image =
StringUtils.toString(ObjectUtils.invokeSimpleMethod(node, "getImage"));
+ if (StringUtils.isNotEmpty(image))
+ { // We have an image
+ // Now find the varMapper
+ VariableMapper varMapper =
(VariableMapper)ObjectUtils.getPrivateFieldValue(ve, "varMapper");
+ if (varMapper!=null)
+ { // Resolve variable using mapper
+ ve = varMapper.resolveVariable(image);
+ log.debug("EL-Expression \"{}\" has been
resolved to variable \"{}\"", expression, (ve!=null ? ve.getExpressionString()
: null));
+ } else {
+ // Variable not provided!
+ log.debug("EL-Expression \"{}\" has been
resolved to NULL.", expression);
+ ve = null;
+ }
+ } else {
+ // No image: complex expression of unsupported type
+ log.info("EL-Expression \"{}\" has unsupported
Node type {}", expression, node.getClass().getName());
+ }
+ } else {
+ // Unexpected: No node available for ValueExpression
+ log.warn("Unexpected: ValueExpressionImpl has no Node.
Expression \"{}\" remains unchanged.");
+ }
+ } else {
+ // Unexpected EL implementation:
+ // Only "org.apache.el.ValueExpressionImpl" is supported!
+ log.warn("Unexpected ValueExpression-Implementation: {}",
ve.getClass().getName());
+ log.warn("ValueExpression unwrapping does not work!");
+ }
+ }
+ }
+ // done
+ return ve;
+ }
+}
+
diff --git a/empire-db/.gitignore b/empire-db/.gitignore
index 91dd769..c49244b 100644
--- a/empire-db/.gitignore
+++ b/empire-db/.gitignore
@@ -4,3 +4,4 @@
/.project
/.apt_generated/
/.factorypath
+/.apt_generated_tests/