JeredM
JeredM

Reputation: 997

Is it possible to pass arguments in the expression of a PropertyModel?

I have a model object that has a getter/setter that accepts a String.

public String getStringValue(String key)

I need to know if it is possible to use that getter with a PropertyModel and if so how do I do it? An example might look something like this:

new PropertyModel<String>(myObj, "StringValue[key]");

Upvotes: 0

Views: 532

Answers (2)

martin-g
martin-g

Reputation: 17533

As answered by @merz this is not supported by Wicket's PropertyModel, actually by PropertyResolver.

PropertyResolver supports such access if you use a java.util.Map:

public Map<String, String> getProperty() {return theMap;}

Check org.apache.wicket.core.util.lang.PropertyResolver's javadoc.

Upvotes: 2

merz
merz

Reputation: 228

There isn't built in way to do it. But you can define your own Wicket Model to do it via reflection. For example:

public class FunctionReflectionReadOnlyModel<T, R> extends AbstractReadOnlyModel<T> {

    private Object object;
    private String functionName;
    private R key;
    private Class<R> keyClass;

    public FunctionReflectionReadOnlyModel(Object object, String expression, Class<R> keyClass) {
        this.object = object;
        this.functionName = getFunctionName(expression);
        this.key = getKey(expression);
        this.keyClass = keyClass;
    }

    @Override
    public T getObject() {
        try {
            Method method = object.getClass().getMethod(functionName, keyClass);
            return (T)method.invoke(object, key);
        } catch (Exception ex) {
            //process exception
            return null;
        }
    }
}

You just need implement getFunctionName(String expression) and getKey(String expression) on your needs.

But I think that is better use another variant. It's not particularly what you ask, but it is typified. Also required Java 8.

public class FunctionWithKeyReadOnlyModel<T, R> extends AbstractReadOnlyModel<T> {

    private Function<R, T> function;
    private R key;

    public FunctionWithKeyReadOnlyModel(Function<R, T> function, R key) {
        this.function = function;
        this.key = key;
    }

    @Override
    public T getObject() {
        return function.apply(key);
    }
}

And then you can use it like this:

new FunctionWithKeyReadOnlyModel(obj::getStringValue, "key");

I've read about usage only PropertyModel too late. In this case you can inherit your class from PropertyModel and change getModel/setModel like in example FunctionReflectionReadOnlyModel. So you don't need change other classes API. But if you want all features of PropertyModel (nested objects) you need implement it.

Upvotes: 2

Related Questions