mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
Introduces new callMethod() function to be used to execute actions
(cherry picked from commit b28b78c062)
This commit is contained in:
@@ -419,7 +419,7 @@ public class DefaultActionInvocation implements ActionInvocation {
|
||||
|
||||
Object methodResult;
|
||||
try {
|
||||
methodResult = ognlUtil.getValue(methodName + "()", getStack().getContext(), action);
|
||||
methodResult = ognlUtil.callMethod(methodName + "()", getStack().getContext(), action);
|
||||
} catch (MethodFailedException e) {
|
||||
// if reason is missing method, try checking UnknownHandlers
|
||||
if (e.getReason() instanceof NoSuchMethodException) {
|
||||
|
||||
@@ -289,6 +289,9 @@ public class OgnlUtil {
|
||||
if (isEvalExpression(tree, context)) {
|
||||
throw new OgnlException("Eval expression/chained expressions cannot be used as parameter name");
|
||||
}
|
||||
if (isArithmeticExpression(tree, context)) {
|
||||
throw new OgnlException("Arithmetic expressions cannot be used as parameter name");
|
||||
}
|
||||
Ognl.setValue(tree, context, root, value);
|
||||
return null;
|
||||
}
|
||||
@@ -308,6 +311,32 @@ public class OgnlUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isArithmeticExpression(Object tree, Map<String, Object> context) throws OgnlException {
|
||||
if (tree instanceof SimpleNode) {
|
||||
SimpleNode node = (SimpleNode) tree;
|
||||
OgnlContext ognlContext = null;
|
||||
|
||||
if (context!=null && context instanceof OgnlContext) {
|
||||
ognlContext = (OgnlContext) context;
|
||||
}
|
||||
return node.isOperation(ognlContext);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isSimpleMethod(Object tree, Map<String, Object> context) throws OgnlException {
|
||||
if (tree instanceof SimpleNode) {
|
||||
SimpleNode node = (SimpleNode) tree;
|
||||
OgnlContext ognlContext = null;
|
||||
|
||||
if (context!=null && context instanceof OgnlContext) {
|
||||
ognlContext = (OgnlContext) context;
|
||||
}
|
||||
return node.isSimpleMethod(ognlContext) && !node.isChain(ognlContext);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object getValue(final String name, final Map<String, Object> context, final Object root) throws OgnlException {
|
||||
return compileAndExecute(name, context, new OgnlTask<Object>() {
|
||||
public Object execute(Object tree) throws OgnlException {
|
||||
@@ -316,6 +345,14 @@ public class OgnlUtil {
|
||||
});
|
||||
}
|
||||
|
||||
public Object callMethod(final String name, final Map<String, Object> context, final Object root) throws OgnlException {
|
||||
return compileAndExecuteMethod(name, context, new OgnlTask<Object>() {
|
||||
public Object execute(Object tree) throws OgnlException {
|
||||
return Ognl.getValue(tree, context, root);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Object getValue(final String name, final Map<String, Object> context, final Object root, final Class resultType) throws OgnlException {
|
||||
return compileAndExecute(name, context, new OgnlTask<Object>() {
|
||||
public Object execute(Object tree) throws OgnlException {
|
||||
@@ -350,6 +387,27 @@ public class OgnlUtil {
|
||||
return exec;
|
||||
}
|
||||
|
||||
private <T> Object compileAndExecuteMethod(String expression, Map<String, Object> context, OgnlTask<T> task) throws OgnlException {
|
||||
Object tree;
|
||||
if (enableExpressionCache) {
|
||||
tree = expressions.get(expression);
|
||||
if (tree == null) {
|
||||
tree = Ognl.parseExpression(expression);
|
||||
checkSimpleMethod(tree, context);
|
||||
}
|
||||
} else {
|
||||
tree = Ognl.parseExpression(expression);
|
||||
checkSimpleMethod(tree, context);
|
||||
}
|
||||
|
||||
final T exec = task.execute(tree);
|
||||
// if cache is enabled and it's a valid expression, puts it in
|
||||
if(enableExpressionCache) {
|
||||
expressions.putIfAbsent(expression, tree);
|
||||
}
|
||||
return exec;
|
||||
}
|
||||
|
||||
public Object compile(String expression, Map<String, Object> context) throws OgnlException {
|
||||
return compileAndExecute(expression,context,new OgnlTask<Object>() {
|
||||
public Object execute(Object tree) throws OgnlException {
|
||||
@@ -364,6 +422,12 @@ public class OgnlUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSimpleMethod(Object tree, Map<String, Object> context) throws OgnlException {
|
||||
if (!isSimpleMethod(tree, context)) {
|
||||
throw new OgnlException("It isn't a simple method which can be called!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the properties in the object "from" and sets them in the object "to"
|
||||
* using specified type converter, or {@link com.opensymphony.xwork2.conversion.impl.XWorkConverter} if none
|
||||
|
||||
@@ -759,6 +759,21 @@ public class OgnlUtilTest extends XWorkTestCase {
|
||||
assertEquals(expected.getMessage(), "Eval expressions/chained expressions have been disabled!");
|
||||
}
|
||||
|
||||
public void testCallMethod() throws Exception {
|
||||
Foo foo = new Foo();
|
||||
|
||||
Exception expected = null;
|
||||
try {
|
||||
ognlUtil.callMethod("#booScope=@myclass@DEFAULT_SCOPE,#bootScope.init()", ognlUtil.createDefaultContext(foo), foo);
|
||||
fail();
|
||||
} catch (OgnlException e) {
|
||||
expected = e;
|
||||
}
|
||||
assertNotNull(expected);
|
||||
assertSame(OgnlException.class, expected.getClass());
|
||||
assertEquals(expected.getMessage(), "It isn't a simple method which can be called!");
|
||||
}
|
||||
|
||||
public static class Email {
|
||||
String address;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user