Author: konstantin.mishin
Date: 2009-11-19 14:23:40 -0500 (Thu, 19 Nov 2009)
New Revision: 15932
Modified:
branches/enterprise/3.3.X/framework/impl/src/main/java/org/ajax4jsf/renderkit/compiler/MethodCallElement.java
Log:
RFPL-252
Modified:
branches/enterprise/3.3.X/framework/impl/src/main/java/org/ajax4jsf/renderkit/compiler/MethodCallElement.java
===================================================================
---
branches/enterprise/3.3.X/framework/impl/src/main/java/org/ajax4jsf/renderkit/compiler/MethodCallElement.java 2009-11-19
19:15:29 UTC (rev 15931)
+++
branches/enterprise/3.3.X/framework/impl/src/main/java/org/ajax4jsf/renderkit/compiler/MethodCallElement.java 2009-11-19
19:23:40 UTC (rev 15932)
@@ -31,73 +31,88 @@
import java.util.Map;
import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
import javax.faces.el.MethodNotFoundException;
+import javax.faces.render.Renderer;
import org.ajax4jsf.Messages;
+import org.ajax4jsf.renderkit.RendererBase;
+import org.ajax4jsf.renderkit.RendererUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;
-
/**
* @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
* @version $Revision: 1.1.2.1 $ $Date: 2007/01/09 18:57:47 $
- *
+ *
*/
-public class MethodCallElement extends ElementBase {
+public class MethodCallElement extends ElementBase {
public static final String UTILS_PREFIX = "utils.";
-
+
static final Log _log = LogFactory.getLog(MethodCallElement.class);
private String _name = null;
-
- private List parameters = new ArrayList();
-
- private Invoker invoker = new Invoker();
-
- private MethodCacheState state = new MethodCacheState();
-
-
- /* (non-Javadoc)
- * @see org.ajax4jsf.renderkit.compiler.CompiledXML#encode(javax.faces.render.Renderer,
javax.faces.context.FacesContext, javax.faces.component.UIComponent)
+
+ private List<MethodParameterElement> parameters = new
ArrayList<MethodParameterElement>(
+ 3);
+
+ private volatile Invoker invoker;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.ajax4jsf.renderkit.compiler.CompiledXML#encode(javax.faces.render
+ * .Renderer, javax.faces.context.FacesContext,
+ * javax.faces.component.UIComponent)
*/
- public void encode(TemplateContext context ) throws IOException {
- getValue(context);
+ public void encode(TemplateContext context) throws IOException {
+ getValue(context);
}
- /* (non-Javadoc)
- * @see
org.ajax4jsf.renderkit.compiler.ElementBase#encode(org.ajax4jsf.renderkit.compiler.TemplateContext,
java.lang.String)
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.ajax4jsf.renderkit.compiler.ElementBase#encode(org.ajax4jsf.renderkit
+ * .compiler.TemplateContext, java.lang.String)
*/
- public void encode(TemplateContext context, String breakPoint) throws IOException {
+ public void encode(TemplateContext context, String breakPoint)
+ throws IOException {
// Text not contain breakpoints.
encode(context);
}
-
-
+
public Object getValue(TemplateContext context) throws FacesException {
+ if (null == invoker) {
+ throw new FacesException(Messages
+ .getMessage(Messages.RENDERER_METHOD_NOT_SET_ERROR));
+ }
// prepare method params. we attempt to call 3 signatures :
// a) name(FacesContext,UIComponent [, param0...])
// b) name(TempalateContext [,param0...])
// c) name([param0...])
- state.init(parameters);
- Object[] values = state.computeParameterValues(context);
-
- InvokeData data = null;
- synchronized (state) {
- state.update(context, values, invoker);
- data = invoker.invokeMethod(context, state);
- }
- return invoker.invokeMethod(data);
+ Object[] values = computeParameterValues(context);
+
+ return invoker.invokeMethod(context, values);
// perform childrens.
// super.encode(renderer,context,component);
}
+ public Object[] computeParameterValues(TemplateContext context) {
+ Object[] ps = new Object[parameters.size()];
+ for (int i = 0; i < ps.length; i++) {
+ ps[i] = parameters.get(i).valueGetter.getValueOrDefault(context);
+ }
+ return ps;
+ }
-
- public void addParameter(MethodParameterElement parameter){
+ public void addParameter(MethodParameterElement parameter) {
parameters.add(parameter);
}
+
/**
* @return Returns the methodName.
*/
@@ -106,13 +121,14 @@
}
/**
- * @param methodName The methodName to set.
+ * @param methodName
+ * The methodName to set.
*/
public void setName(String methodName) {
- if(methodName.startsWith(UTILS_PREFIX)){
+ if (methodName.startsWith(UTILS_PREFIX)) {
this._name = methodName.substring(UTILS_PREFIX.length());
this.invoker = getRendererUtilsInvoker(_name);
- } else if(methodName.indexOf('.') >= 0) {
+ } else if (methodName.indexOf('.') >= 0) {
this._name = methodName;
this.invoker = getStaticInvoker(_name);
} else {
@@ -121,385 +137,430 @@
}
}
- static Map staticInvokers = new HashMap();
-
- public StaticInvoker getStaticInvoker(String methodName) {
- StaticInvoker invoker = (StaticInvoker)staticInvokers.get(methodName);
- if(invoker == null) {
- invoker = new StaticInvoker(methodName);
- staticInvokers.put(methodName, invoker);
- }
- return invoker;
+ public Invoker getStaticInvoker(String methodName) {
+ StaticInvoker invoker = new StaticInvoker(methodName);
+ return invoker;
}
- static Map rendererInvokers = new HashMap();
-
- public RendererInvoker getRendererInvoker(String methodName) {
- RendererInvoker invoker = (RendererInvoker)rendererInvokers.get(methodName);
- if(invoker == null) {
- invoker = new RendererInvoker(false, methodName);
- rendererInvokers.put(methodName, invoker);
- }
+ public Invoker getRendererInvoker(String methodName) {
+ RendererInvoker invoker = new RendererInvoker(methodName);
return invoker;
}
-
- static Map utilsInvokers = new HashMap();
- public RendererInvoker getRendererUtilsInvoker(String methodName) {
- RendererInvoker invoker = (RendererInvoker)utilsInvokers.get(methodName);
- if(invoker == null) {
- invoker = new RendererInvoker(true, methodName);
- utilsInvokers.put(methodName, invoker);
- }
+ public Invoker getRendererUtilsInvoker(String methodName) {
+ RendererInvoker invoker = new RendererUtilsInvoker(methodName);
return invoker;
}
-
+
public String getTag() {
- return HtmlCompiler.NS_PREFIX+HtmlCompiler.CALL_TAG;
+ return HtmlCompiler.NS_PREFIX + HtmlCompiler.CALL_TAG;
}
-
- /* (non-Javadoc)
- * @see
org.ajax4jsf.renderkit.compiler.ElementBase#setParent(org.ajax4jsf.renderkit.compiler.PreparedTemplate)
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.ajax4jsf.renderkit.compiler.ElementBase#setParent(org.ajax4jsf.renderkit
+ * .compiler.PreparedTemplate)
*/
- public void setParent(PreparedTemplate parent) throws SAXException {
+ public void setParent(PreparedTemplate parent) throws SAXException {
super.setParent(parent);
- if (getName()==null) {
- throw new SAXException(Messages.getMessage(Messages.NO_NAME_ATTRIBUTE_ERROR,
getTag()));
+ if (getName() == null) {
+ throw new SAXException(Messages.getMessage(
+ Messages.NO_NAME_ATTRIBUTE_ERROR, getTag()));
}
}
-
-/* (non-Javadoc)
- * @see
org.ajax4jsf.renderkit.compiler.ElementBase#getString(org.ajax4jsf.renderkit.compiler.TemplateContext)
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.ajax4jsf.renderkit.compiler.ElementBase#getString(org.ajax4jsf.renderkit
+ * .compiler.TemplateContext)
*/
public String getString(TemplateContext context) throws FacesException {
Object result = getValue(context);
- if (null == result || result.toString().length()==0) {
- result = "";
+ if (null == result || result.toString().length() == 0) {
+ result = "";
}
return result.toString();
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.ajax4jsf.renderkit.compiler.ElementBase#getAllowedClasses()
*/
- protected Class[] getAllowedClasses() {
- // TODO Auto-generated method stub
- return new Class[]{
- MethodParameterElement.class,
- ResourceElement.class
- };
+ @SuppressWarnings("unchecked")
+ protected Class<? extends ElementBase>[] getAllowedClasses() {
+ return new Class[] { MethodParameterElement.class,
+ ResourceElement.class };
}
}
-class InvokeData {
- TemplateContext context;
- Method method;
- Object object;
- Object[] arguments;
- InvokeData(TemplateContext context, Method method, Object object, Object[] arguments) {
- this.context = context;
- this.method = method;
- this.object = object;
- this.arguments = (Object[]) arguments.clone();
- }
-}
+abstract class Invoker {
-class Invoker {
- String methodName;
+ protected volatile Signature current;
- InvokeData invokeMethod(TemplateContext context, MethodCacheState state) {
- throw new FacesException(Messages.getMessage(Messages.RENDERER_METHOD_NOT_SET_ERROR));
+ protected String methodName;
+
+ public Invoker(String name) {
+ this.methodName = name;
}
- void handleInvocationTargetException(TemplateContext context, InvocationTargetException
e) {}
- void handleIllegalAccessException(TemplateContext context, IllegalAccessException e) {}
- void handleMethodNotFoundException(TemplateContext context) throws
MethodNotFoundException {}
-
- InvokeData invokeMethod(TemplateContext context, Map methods, Class cls, Object object,
MethodCacheState state) {
- Method method = provideMethod(methods, cls, object, state);
- return new InvokeData(context, method, object, state.current.arguments);
- }
-
- Object invokeMethod(InvokeData data) {
- if(data.method != null) {
+ public Object invokeMethod(TemplateContext context, Object[] parameters) {
+ Object result = null;
+ Class<?>[] parameterTypes = new Class[parameters.length];
+ for (int i = 0; i < parameters.length; i++) {
+ Object parameter = parameters[i];
+ if (null != parameter) {
+ parameterTypes[i] = parameter.getClass();
+ }
+ }
+ // Use a copy to avoid synchronization.
+ Signature signature = current;
+ if (null == signature
+ || !signature.isApplicable(context, getInvokedClass(context),
+ parameterTypes)) {
+ // Clalculate target signature
+ signature = provideMethod(context, parameterTypes);
+ current = signature;
+ }
try {
- return data.method.invoke(data.object, data.arguments);
+ result = signature.invoke(context, getInvokedObject(context),
+ parameters);
+ } catch (IllegalArgumentException e) {
+ throw new FacesException(e);
+ } catch (IllegalAccessException e) {
+ handleIllegalAccessException(context, e);
} catch (InvocationTargetException e) {
- handleInvocationTargetException(data.context, e);
- } catch (IllegalAccessException e) {
- handleIllegalAccessException(data.context, e);
+ handleInvocationTargetException(context, e);
}
- }
- handleMethodNotFoundException(data.context);
- return null;
+ return result;
}
-
- public Class getInvokedClass(TemplateContext context) {
- return null;
- }
-
- private Method provideMethod(Map methods, Class cls, Object object, MethodCacheState
state) {
- if(state.method != null) return state.method;
- if(methods.size() > 0) {
- for (int i = 0; i < state.signatures.length; i++) {
- state.method = (Method)methods.get(getClassesKey(state.signatures[i].arguments));
- if(state.method != null) {
- state.current = state.signatures[i];
- return state.method;
+ abstract void handleInvocationTargetException(TemplateContext context,
+ InvocationTargetException e);
+
+ abstract void handleIllegalAccessException(TemplateContext context,
+ IllegalAccessException e);
+
+ abstract void handleMethodNotFoundException(TemplateContext context);
+
+ public abstract Class<?> getInvokedClass(TemplateContext context);
+
+ public abstract Object getInvokedObject(TemplateContext context);
+
+ protected Signature provideMethod(TemplateContext context,
+ Class<?>[] parameterTypes) {
+ Class<?> cls = getInvokedClass(context);
+ if (null != cls) {
+ // TODO - cache signatures ?
+ Object object = getInvokedObject(context);
+ Method[] methods = cls.getMethods();
+ for (int m = 0; m < methods.length; m++) {
+ if (methods[m].getName().equals(methodName)
+ && (object != null || Modifier.isStatic(methods[m]
+ .getModifiers()))) {
+ Signature s = new Signature0(methods[m]);
+ if (s.isApplicable(context, cls, parameterTypes)) {
+ return s;
+ }
+ s = new Signature1(methods[m]);
+ if (s.isApplicable(context, cls, parameterTypes)) {
+ return s;
+ }
+ s = new Signature2(methods[m]);
+ if (s.isApplicable(context, cls, parameterTypes)) {
+ return s;
+ }
}
}
}
-
- if(cls == null && object != null) cls = object.getClass();
- Method[] ms = cls.getMethods();
- for (int m = 0; m < ms.length; m++) {
- if(!ms[m].getName().equals(methodName)) continue;
- if(object == null && !Modifier.isStatic(ms[m].getModifiers())) continue;
- Class[] cs = ms[m].getParameterTypes();
- Signature s = getMatchingArguments(cs, state.signatures);
- if(s == null) continue;
- state.current = s;
- state.method = ms[m];
- methods.put(getClassesKey(s.arguments), ms[m]);
- return state.method;
- }
-
+ handleMethodNotFoundException(context);
return null;
}
- private String getClassesKey(Object[] args) {
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < args.length; i++) {
- String dk = args[i] == null ? "null" : args[i].getClass().getName();
- sb.append(";").append(dk);
- }
- return sb.toString();
- }
-
- private Signature getMatchingArguments(Class[] cs, Signature[] sgs) {
- for (int i = 0; i < sgs.length; i++) {
- if(isMatching(cs, sgs[i].arguments)) return sgs[i];
- }
- return null;
- }
-
- static boolean isMatching(Class[] cs, Object[] args) {
- if(cs.length != args.length) return false;
+ static boolean isMatching(Class<?>[] cs, Class<?>[] args) {
+ if (cs.length != args.length)
+ return false;
for (int i = 0; i < cs.length; i++) {
- if(args[i] != null && !cs[i].isAssignableFrom(args[i].getClass())) return
false;
+ if (args[i] != null && !cs[i].isAssignableFrom(args[i]))
+ return false;
}
return true;
}
}
class RendererInvoker extends Invoker {
- boolean utils = false;
- Map renderers = new HashMap();
-
- public RendererInvoker(boolean utils, String methodName) {
- this.utils = utils;
- this.methodName = methodName;
+
+ public RendererInvoker(String methodName) {
+ super(methodName);
}
- public Class getInvokedClass(TemplateContext context) {
+ public Class<? extends Object> getInvokedClass(TemplateContext context) {
Object object = getInvokedObject(context);
- return (object != null) ? object.getClass() : null;
+ return (object != null) ? object.getClass() : Renderer.class;
}
-
- private Object getInvokedObject(TemplateContext context) {
- if(utils) {
- return context.getRenderer().getUtils();
- } else {
- return context.getRenderer();
- }
+
+ public Object getInvokedObject(TemplateContext context) {
+ return context.getRenderer();
}
-
- InvokeData invokeMethod(TemplateContext context, MethodCacheState state) {
+
+ void handleInvocationTargetException(TemplateContext context,
+ InvocationTargetException e) {
+ String logMessage = Messages.getMessage(Messages.METHOD_CALL_ERROR_1a,
+ methodName, context.getComponent().getId());
+ String excMessage = Messages.getMessage(Messages.METHOD_CALL_ERROR_2a,
+ new Object[] { methodName, context.getComponent().getId(),
+ e.getCause().getMessage() });
+ MethodCallElement._log.error(logMessage, e);
+ throw new FacesException(excMessage, e);
+ }
+
+ void handleIllegalAccessException(TemplateContext context,
+ IllegalAccessException e) {
+ String logMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_3a, methodName, context
+ .getComponent().getId()));
+ String excMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_4a, new Object[] { methodName,
+ context.getComponent().getId(),
+ e.getCause().getMessage() }));
+ MethodCallElement._log.error(logMessage, e);
+ throw new FacesException(excMessage, e);
+ }
+
+ void handleMethodNotFoundException(TemplateContext context)
+ throws MethodNotFoundException {
+ String logMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_5a, methodName, context
+ .getComponent().getId()));
+ String excMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_6a, methodName));
+ MethodCallElement._log.error(logMessage);
+ throw new FacesException(excMessage);
+ }
+}
+
+class RendererUtilsInvoker extends RendererInvoker {
+
+ public RendererUtilsInvoker(String methodName) {
+ super(methodName);
+ }
+
+ public Class<? extends Object> getInvokedClass(TemplateContext context) {
Object object = getInvokedObject(context);
- Map methods = getMethods(object);
- return invokeMethod(context, methods, null, object, state);
+ return (object != null) ? object.getClass() : RendererUtils.class;
}
-
- private Map getMethods(Object object) {
- if(object == null) return null;
- Map methods = (Map)renderers.get(object);
- if(methods == null) {
- methods = new HashMap();
- renderers.put(object, methods);
- }
- return methods;
+
+ public Object getInvokedObject(TemplateContext context) {
+ RendererBase renderer = context.getRenderer();
+ return null != renderer ? renderer.getUtils() : null;
}
- void handleInvocationTargetException(TemplateContext context, InvocationTargetException
e) {
- String logMessage = (utils)
- ? Messages.getMessage(Messages.METHOD_CALL_ERROR_1, methodName,
context.getComponent().getId())
- : Messages.getMessage(Messages.METHOD_CALL_ERROR_1a, methodName,
context.getComponent().getId());
- String excMessage = (utils)
- ? Messages.getMessage(Messages.METHOD_CALL_ERROR_2, new Object[]{methodName,
context.getComponent().getId(), e.getCause().getMessage()})
- : Messages.getMessage(Messages.METHOD_CALL_ERROR_2a, new Object[]{methodName,
context.getComponent().getId(), e.getCause().getMessage()});
+ void handleInvocationTargetException(TemplateContext context,
+ InvocationTargetException e) {
+ String logMessage = Messages.getMessage(Messages.METHOD_CALL_ERROR_1,
+ methodName, context.getComponent().getId());
+ String excMessage = Messages.getMessage(Messages.METHOD_CALL_ERROR_2,
+ new Object[] { methodName, context.getComponent().getId(),
+ e.getCause().getMessage() });
MethodCallElement._log.error(logMessage, e);
throw new FacesException(excMessage, e);
}
- void handleIllegalAccessException(TemplateContext context, IllegalAccessException e) {
- String logMessage = (utils)
- ? Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_3, methodName,
context.getComponent().getId()))
- : Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_3a, methodName,
context.getComponent().getId()));
- String excMessage = (utils)
- ? Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_4, new
Object[]{methodName, context.getComponent().getId(), e.getCause().getMessage()}))
- : Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_4a, new
Object[]{methodName, context.getComponent().getId(), e.getCause().getMessage()}));
+
+ void handleIllegalAccessException(TemplateContext context,
+ IllegalAccessException e) {
+ String logMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_3, methodName, context
+ .getComponent().getId()));
+ String excMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_4, new Object[] { methodName,
+ context.getComponent().getId(),
+ e.getCause().getMessage() }));
MethodCallElement._log.error(logMessage, e);
throw new FacesException(excMessage, e);
}
-
- void handleMethodNotFoundException(TemplateContext context) throws
MethodNotFoundException {
- String logMessage = (utils)
- ? Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_5, methodName,
context.getComponent().getId()))
- : Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_5a, methodName,
context.getComponent().getId()));
- String excMessage = (utils)
- ? Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_6, methodName))
- : Messages.getMessage(Messages.getMessage(Messages.METHOD_CALL_ERROR_6a,
methodName));
- MethodCallElement._log.error(logMessage);
+
+ void handleMethodNotFoundException(TemplateContext context)
+ throws MethodNotFoundException {
+ String logMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_5, methodName, context
+ .getComponent().getId()));
+ String excMessage = Messages.getMessage(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_6, methodName));
+ MethodCallElement._log.error(logMessage);
throw new FacesException(excMessage);
}
}
class StaticInvoker extends Invoker {
String className;
- Class cls;
- Map methods = new HashMap();
-
+ Class<?> cls;
+ Map<String, Method> methods = new HashMap<String, Method>();
+
StaticInvoker(String methodName) {
- this.methodName = methodName;
+ super(methodName);
int i = methodName.lastIndexOf('.');
className = methodName.substring(0, i);
this.methodName = methodName.substring(i + 1);
try {
- cls = Thread.currentThread().getContextClassLoader().loadClass(className);
+ cls = Thread.currentThread().getContextClassLoader().loadClass(
+ className);
} catch (ClassNotFoundException e) {
- //ignore, throw exception when invoking
+ // ignore, throw exception when invoking
}
}
- InvokeData invokeMethod(TemplateContext context, MethodCacheState state) {
- if(cls == null) throw new FacesException(className, new
ClassNotFoundException(className));
- return invokeMethod(context, methods, cls, null, state);
+ @Override
+ public Class<?> getInvokedClass(TemplateContext context) {
+ return cls;
}
- void handleInvocationTargetException(TemplateContext context, InvocationTargetException
e) {
- MethodCallElement._log.error(Messages.getMessage(Messages.METHOD_CALL_ERROR_1a,
methodName, context.getComponent().getId()), e);
- throw new FacesException(Messages.getMessage(Messages.METHOD_CALL_ERROR_2a, new
Object[]{methodName, context.getComponent().getId(), e.getCause().getMessage()}), e);
+ @Override
+ public Object getInvokedObject(TemplateContext context) {
+ return null;
}
- void handleIllegalAccessException(TemplateContext context, IllegalAccessException e) {
- MethodCallElement._log.error(Messages.getMessage(Messages.METHOD_CALL_ERROR_3a,
methodName, context.getComponent().getId()), e);
- throw new FacesException(Messages.getMessage(Messages.METHOD_CALL_ERROR_4a, new
Object[]{methodName, context.getComponent().getId(), e.getCause().getMessage()}), e);
- }
- void handleMethodNotFoundException(TemplateContext context) throws
MethodNotFoundException {
- MethodCallElement._log.error(Messages.getMessage(Messages.METHOD_CALL_ERROR_5a,
methodName, context.getComponent().getId()));
- throw new MethodNotFoundException(Messages.getMessage(Messages.METHOD_CALL_ERROR_6a,
methodName));
+
+ void handleInvocationTargetException(TemplateContext context,
+ InvocationTargetException e) {
+ MethodCallElement._log.error(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_1a, methodName, context
+ .getComponent().getId()), e);
+ throw new FacesException(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_2a, new Object[] { methodName,
+ context.getComponent().getId(),
+ e.getCause().getMessage() }), e);
}
+
+ void handleIllegalAccessException(TemplateContext context,
+ IllegalAccessException e) {
+ MethodCallElement._log.error(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_3a, methodName, context
+ .getComponent().getId()), e);
+ throw new FacesException(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_4a, new Object[] { methodName,
+ context.getComponent().getId(),
+ e.getCause().getMessage() }), e);
+ }
+
+ void handleMethodNotFoundException(TemplateContext context)
+ throws MethodNotFoundException {
+ MethodCallElement._log.error(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_5a, methodName, context
+ .getComponent().getId()));
+ throw new MethodNotFoundException(Messages.getMessage(
+ Messages.METHOD_CALL_ERROR_6a, methodName));
+ }
+
}
-class MethodCacheState {
- private MethodParameterElement[] elements;
- private Class[] parameterClasses;
- private Object[] parameterValues;
- private Class lastCallingClass = null;
- public Method method;
- public Signature current;
- public Signature[] signatures;
-
- public void init(List parameters) {
- if(elements != null) return;
- synchronized (this) {
- if(elements != null) return;
- int size = parameters.size();
- parameterClasses = new Class[size];
- parameterValues = new Object[size];
- signatures = new Signature[3];
- signatures[0] = new Signature2(size);
- signatures[1] = new Signature1(size);
- signatures[2] = new Signature0(size);
- elements = (MethodParameterElement[])parameters.toArray(new
MethodParameterElement[0]);
- }
+abstract class Signature {
+
+ Method method;
+
+ Signature(Method method) {
+ this.method = method;
}
-
- public Object[] computeParameterValues(TemplateContext context) {
- Object[] ps = new Object[elements.length];
- for (int i = 0; i < elements.length; i++) {
- ps[i] = elements[i].valueGetter.getValueOrDefault(context);
+
+ boolean isApplicable(TemplateContext context, Class targetClass,
+ Class<?>[] parameters) {
+ if (!method.getDeclaringClass().isAssignableFrom(targetClass)) {
+ return false;
}
- return ps;
- }
-
- public void update(TemplateContext context, Object[] values, Invoker invoker) {
- boolean changed = false;
- for (int i = 0; i < elements.length; i++) {
- Object parametr = values[i];
- Class c = (parametr == null) ? null : parametr.getClass();
- if(c != parameterClasses[i]) {
- parameterClasses[i] = c;
- changed = true;
- }
- parameterValues[i] = parametr;
+ Class<?>[] methodParameterTypes = this.method.getParameterTypes();
+ Class<?>[] parameterTypes = getParameterTypes(context, parameters);
+ if (methodParameterTypes.length != parameterTypes.length) {
+ return false;
}
- if(method != null && !changed && lastCallingClass !=
invoker.getInvokedClass(context)) {
- lastCallingClass = invoker.getInvokedClass(context);
- changed = true;
- }
- if(changed || current == null) {
- for (int i = 0; i < signatures.length; i++) {
- signatures[i].update(context, parameterValues);
+ for (int i = 0; i < parameterTypes.length; i++) {
+ if (null != parameterTypes[i]
+ && !methodParameterTypes[i]
+ .isAssignableFrom(parameterTypes[i])) {
+ return false;
}
- method = null;
- current = null;
- } else {
- current.update(context, parameterValues);
}
- }
-
-}
+ return true;
+ }
-abstract class Signature {
- Object[] arguments;
+ abstract Class<?>[] getParameterTypes(TemplateContext context,
+ Class<?>[] parameters);
- Signature() {}
+ abstract Object[] getParameterValues(TemplateContext context,
+ Object[] parameters);
- void update(TemplateContext context, Object[] parameters) {}
+ Object invoke(TemplateContext context, Object target, Object[] parameters)
+ throws IllegalArgumentException, IllegalAccessException,
+ InvocationTargetException {
+ return this.method.invoke(target, getParameterValues(context,
+ parameters));
+ }
+
}
class Signature0 extends Signature {
- Signature0(int size) {
- arguments = new Object[size];
+
+ Signature0(Method method) {
+ super(method);
}
- void update(TemplateContext context, Object[] parameters) {
- System.arraycopy(parameters, 0, arguments, 0, parameters.length);
+ @Override
+ Class<?>[] getParameterTypes(TemplateContext context, Class<?>[] parameters)
{
+ return parameters;
}
-
+
+ @Override
+ Object[] getParameterValues(TemplateContext context, Object[] parameters) {
+ return parameters;
+ }
+
}
class Signature1 extends Signature {
- Signature1(int size) {
- arguments = new Object[size + 1];
+ Signature1(Method method) {
+ super(method);
}
- void update(TemplateContext context, Object[] parameters) {
- arguments[0] = context;
- System.arraycopy(parameters, 0, arguments, 1, parameters.length);
+
+ @Override
+ Class<?>[] getParameterTypes(TemplateContext context, Class<?>[] parameters)
{
+ Class<?>[] types = new Class[parameters.length + 1];
+ types[0] = TemplateContext.class;
+ System.arraycopy(parameters, 0, types, 1, parameters.length);
+ return types;
}
-
+
+ @Override
+ Object[] getParameterValues(TemplateContext context, Object[] parameters) {
+ Object[] values = new Object[parameters.length + 1];
+ values[0] = context;
+ System.arraycopy(parameters, 0, values, 1, parameters.length);
+ return values;
+ }
+
}
class Signature2 extends Signature {
- Signature2(int size) {
- arguments = new Object[size + 2];
+ Signature2(Method method) {
+ super(method);
}
- void update(TemplateContext context, Object[] parameters) {
- arguments[0] = context.getFacesContext();
- arguments[1] = context.getComponent();
- System.arraycopy(parameters, 0, arguments, 2, parameters.length);
- }
+
+ @Override
+ Class<?>[] getParameterTypes(TemplateContext context, Class<?>[] parameters)
{
+ Class<?>[] types = new Class[parameters.length + 2];
+ types[0] = FacesContext.class;
+ types[1] = context.getComponent().getClass();
+ System.arraycopy(parameters, 0, types, 2, parameters.length);
+ return types;
+ }
+
+ @Override
+ Object[] getParameterValues(TemplateContext context, Object[] parameters) {
+ Object[] values = new Object[parameters.length + 2];
+ values[0] = context.getFacesContext();
+ values[1] = context.getComponent();
+ System.arraycopy(parameters, 0, values, 2, parameters.length);
+ return values;
+ }
}