There is couple ways about doing that, you could use JBoss EL expression implementation they support method calls with parameters check out Seam, or use similar approach as @digitaljoel suggested.
This is what I created for that purpose, you can call static and static methods, not a great solution but it does the job.
<c:if test="#{t:call(null, '@Util.SecurityUtility', 'isPanelWorkbookEnabledForUser','')}"> Hello Panel </c:if> |
@Util is just an alias to com.mycomp.util where
**Example 2**
<c:if test="#{item != null and t:call(item, 'java.lang.String', 'indexOf', t:params(t:param('flash-alert',''))) == 0}"> #{t:call(session, 'org.apache.catalina.session.StandardSessionFacade', 'removeAttribute', t:params(t:param(item,'')))} </c:if> |
t:call, t:params, t:param are function defined in project-taglib.xml as so
<function> <function-name>call</function-name> <function-class>util.Functions</function-class> <function-signature>java.lang.Object call(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object[])</function-signature> </function> <function> <function-name>param</function-name> <function-class>.util.Functions</function-class> <function-signature>java.lang.String param(java.lang.Object, java.lang.String)</function-signature> </function> <function> <function-name>params</function-name> <function-class>util.Functions</function-class> <function-signature>java.lang.Object[] params(java.lang.String)</function-signature> </function> |
Here is the implementation
package mycompany.web.util; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectOutputStream; import java.io.StringWriter; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; import java.util.HashMap; import java.util.List; import javax.el.MethodNotFoundException; public class Functions { private static HashMap<String, String> alliasMap; static{ alliasMap=new HashMap<String, String>(); alliasMap.put("@DateUtil", "com.americanbanksystems.compliance.util.DateUtil"); //Match anything following the dot(.) alliasMap.put("@Util.*", "com.americanbanksystems.compliance.util"); alliasMap.put("@Application.*", "com.americanbanksystems.compliance.application"); } public static String param(Object obj, String cls) { //make sure that passed in object is not null if(obj==null){ obj=""; } ByteArrayOutputStream baut=new ByteArrayOutputStream(); XMLEncoder encoder=new XMLEncoder( baut ); //Bug in the JDK //http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=c993c9a3160fd7de44075a2a1fa?bug_id=6525396 if(obj instanceof java.sql.Timestamp){ Date o = new Date(((java.sql.Timestamp)obj).getTime()); obj=o; } //Checking if this is possible if(String.class.isAssignableFrom(obj.getClass())){ //removed trailing +" " because it was causing indexOf return invalid value //Unknown side effects obj=FacesUtil.get(obj.toString()); } encoder.writeObject( obj ); encoder.close(); return new String(baut.toByteArray()); } private static Object decode(String str){ ByteArrayInputStream bais=new ByteArrayInputStream(str.getBytes()); XMLDecoder decoder=new XMLDecoder(bais); return decoder.readObject(); } public static Object[] params(String str){ // (?<=</java>)\s*(?=<?) String[] obj=str.split("(?<=</java>)\\s*(?=<?)"); Object[] results=new Object[obj.length]; for(int i=0;i<obj.length;i++){ results[i]=decode(obj[i]); } return results; } @SuppressWarnings("unchecked") public static Object call(Object owningObject, String qualifiedClassname, String methodName, java.lang.Object... methodArguments) { if (null == methodName || methodName.equals("")) { throw new IllegalArgumentException("Method name can't be null or empty"); } if (null == methodArguments) { methodArguments = new Object[0]; } //Check for aliases if(qualifiedClassname.indexOf("@")>-1){ String subpackage=qualifiedClassname; String originalClass=qualifiedClassname; //Split at the dot boolean isPackageAllias=false; String[] sp=subpackage.split("\\."); if(sp.length>1){ subpackage=sp[0]+".*"; isPackageAllias=true; } if(alliasMap.containsKey(subpackage)){ String value = alliasMap.get(subpackage); if(isPackageAllias){ qualifiedClassname=subpackage.replace(sp[0], value); qualifiedClassname=qualifiedClassname.replace(".*", originalClass.replace(sp[0],"")); }else{ qualifiedClassname=value; } }else{ throw new IllegalArgumentException("Allias name '"+qualifiedClassname+"' not found"); } } Class clazz; try { clazz = Class.forName(qualifiedClassname); //Find method by methodName,Argument Types Class[] argumentTypes=new Class[methodArguments.length]; for(int i=0;i<methodArguments.length;i++){ argumentTypes[i]=methodArguments[i].getClass(); //Check if the passed in method argument is a string and if its represented as unicode char //if it is then convert it into a char and reassign to the original parameter //example 1: \u0022 == " //example 2: \u0027 == ' // Reason for this functionality is that we can't pass " and ' from within t:call method if (argumentTypes[i] == String.class && methodArguments[i].toString().indexOf("\\u") > -1) { String arg = methodArguments[i].toString(); arg = arg.substring(2, arg.length()); try { int outchar = Integer.parseInt(arg, 16); if (Character.isDefined(outchar)) { methodArguments[i] = String.valueOf((char) outchar); } } catch (NumberFormatException nfe) { // Suppress error and continue assuming this is a regular string } } } Method methodToInvoke = null; try{ methodToInvoke = clazz.getMethod(methodName, argumentTypes); }catch(NoSuchMethodException nsm){//Find by method name/ argument count for (Method method : clazz.getMethods()) { if (method.getName().equals(methodName) && method.getParameterTypes().length == methodArguments.length) { if (null == owningObject) { owningObject = clazz.newInstance(); } methodToInvoke=method; break; } } } if(methodToInvoke!=null){ return methodToInvoke.invoke(owningObject, methodArguments); }else{ throw new InstantiationException("method not found :" + methodName); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return null; } public static void main(String[] arg) { // StringBuffer buff=new StringBuffer(); // buff.append("Gregs init"); // Functions.call(java.lang.Class<T>, T, java.lang.String, java.lang.String, java.lang.Object...) /* * Functions.call(StringBuffer.class, buff, "java.lang.StringBuffer","append"," Init "); * Functions.call(StringBuffer.class, buff, "java.lang.StringBuffer","append"," greg "); * System.out.println("output="+ buff); */ //#{t:call(null, ".util.DateUtil", "normalizeDate", t:parametize(editRiskActionPlan.riskActionPlan.completionDate,",","java.lang.Object"))} // c(call(null, "util.DateUtil", "normalizeDate", new Date())); // #{t:parametize(editRiskActionPlan.riskActionPlan.completionDate,",","java.lang.Object")} //parametize((new Date()).toString(),",","java.lang.Object"); Date a=new Date(); Date b=new Date(); String rawString=param((Date)b, Date.class.toString() ); //System.out.println(rawString); //Replaced=#{t:call("Gregs ' car", 'java.lang.String', 'replace', t:params( parameter ))} String paramA=param("\\u0027",""); String paramB=param("\\u0022",""); String params=paramA+paramB; String in="I need to ' have a replaced single quote with double"; String out=(String)call(in, "java.lang.String", "replace", params(params)); System.out.println(out); /* Object[] obj=params(rawString); for(Object o:obj){ System.out.println(o); } //c(call(null, "@DateUtil", "normalizeDate", obj)); */ } } |
I hope this helps, btw this was copied/pasted from my project so not sure if I missed anything.