Domanda

i have an managed bean(session scope) like this:

class Home {// as homeBean
  public void doSomething(ActionEvent ae, int a, int b){
    System.out.println("result="+(a+b));
  }
}

i like to call this

<a4j:commandLink actionListener="#{homeBean:doSomething(1,2)}"/>

what i know is: it isnt possible to use a and b parameter.

ok: this should be in example a "static" possibility to invoke this using an taglib:

public class CoolTaglib implements TagLibrary{
   ...
  public static void doSomething(int a, int b) {
    getHomeBeanFromSession().doSomething(a,b);
  }
}

what about to invoke it dynamicly? using bcel or URLClassLoader?

È stato utile?

Soluzione

This EL expression syntax is for static methods only and must be defined in a tag library and have the namespace defined in the view:

 #{namespacePrefix:fn(arg)}

This EL expression with invokes a parameterized method on an object instance:

#{someInstance.method(arg)}

The second form is available in Expression Language 2.2 or above (Java EE 6.) Similar expressions are supported in some 3rd party JSF libraries prior to this.

It is possible to look up a managed bean from a static method so long as it is executed within a JSF context:

FacesContext context = FacesContext.getCurrentInstance();
SomeBean someBean = context.getApplication()
                           .evaluateExpressionGet(context, 
                                                  "#{someBean}", SomeBean.class);

This is not the ideal approach however. This code was written against JSF 2; prior versions use different dynamic lookup calls.

If you need a bean in a static method, use an expression of the form:

#{namespacePrefix:fn(someBean, 1, 2)}

Altri suggerimenti

Oh cool, i found a way to work:

public class ... implements TagLibrary {

@Override
public Method createFunction(String taglib, String functionName) {
    if (!map.containsKey(functionName)) {

        String classname = "de.Test" + functionName;
        ClassGen _cg = new ClassGen(classname,
                "java.lang.Object", "Test.java", ACC_PUBLIC | ACC_SUPER,
                new String[] {});
        ConstantPoolGen _cp = _cg.getConstantPool();
        InstructionFactory _factory = new InstructionFactory(_cg, _cp);

        Method meth = find(functionName, getNavigation());
        Class<?>[] parameterTypes = meth.getParameterTypes();
        int countParams = parameterTypes.length;
        Type[] types = new Type[countParams];
        String[] names = new String[countParams];
        for (int i = 0; i < countParams; i++) {
            types[i] = new ObjectType(parameterTypes[i].getName());
            names[i] = "arg" + i;
        }

        InstructionList il = new InstructionList();

        MethodGen staticMethod = new MethodGen(ACC_PUBLIC | ACC_STATIC,
                Type.OBJECT, types, names, functionName, getClass()
                        .getName(), il, _cp);

        InstructionHandle ih_1 = il.append(new PUSH(_cp, functionName));
        il.append(new PUSH(_cp, countParams));

        il.append(_factory.createNewArray(Type.OBJECT, (short) 1));
        il.append(InstructionConstants.DUP);

        for (int i = 0; i < countParams; i++) {
            il.append(new PUSH(_cp, i));

            il.append(_factory.createLoad(Type.OBJECT, i));
            il.append(InstructionConstants.AASTORE);
            if (i != countParams - 1)
                il.append(InstructionConstants.DUP);
        }

        il.append(_factory.createInvoke(getClass().getName(),
                "call", Type.OBJECT, new Type[] { Type.STRING,
                        new ArrayType(Type.OBJECT, 1) },
                Constants.INVOKESTATIC));
        InstructionHandle ih_25 = il.append(_factory
                .createReturn(Type.OBJECT));
        staticMethod.setMaxStack();
        staticMethod.setMaxLocals();
        _cg.addMethod(staticMethod.getMethod());
        il.dispose();

        try {

            byte[] bytes = _cg.getJavaClass().getBytes();

            InjectingClassLoader icl = new InjectingClassLoader();

            Method find = 
                    find(functionName, icl.load(classname, bytes));

            map.put(functionName, find);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    Method method = map.get(functionName);
    return method;

}

public static Object call(String functionname, Object[] arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Navigation myTargetBean = getNavigation();
    Method proxyMethod = find(functionname,myTargetBean);

    Object result = proxyMethod.invoke(myTargetBean, arguments);

    return result;
}

Now, i am able to call #{cms:doSomething(1,2)}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top