/* PropertyExpression.java Purpose: Description: History: 12:25 PM 9/7/15, Created by jumperchen Copyright (C) 2015 Potix Corporation. All Rights Reserved. */ package org.zkoss.bind.impl; import org.zkoss.lang.Classes; import org.zkoss.lang.reflect.Fields; import org.zkoss.xel.ExpressionX; import org.zkoss.xel.ValueReference; import org.zkoss.xel.XelContext; import org.zkoss.xel.XelException; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.ext.DynamicPropertied; import org.zkoss.zk.ui.sys.ComponentCtrl; import org.zkoss.zk.ui.sys.PropertyAccess; /** * An implementation of component property expression to evaluate it with a reflection * method call instead of EL resolving. * <p>Note that this class is used for Data Binding internal only</p> * @author jumperchen * @since 8.0.0 */ public class PropertyExpression implements ExpressionX, java.io.Serializable { private Component cmp; private String field; public PropertyExpression(Component cmp, String field) { this.cmp = cmp; this.field = field; } public Object evaluate(XelContext ctx) throws XelException { try { if (cmp instanceof ComponentCtrl) { PropertyAccess propertyAccess = ((ComponentCtrl) cmp).getPropertyAccess(field); if (propertyAccess != null) return propertyAccess.getValue(cmp); } return Fields.get(cmp, field); } catch (NoSuchMethodException e) { if (cmp instanceof DynamicPropertied) { return ((DynamicPropertied) cmp).getDynamicProperty(field); } return null; } } public boolean isReadOnly(XelContext ctx) throws XelException { return false; } public void setValue(XelContext ctx, Object value) throws XelException { try { if (cmp instanceof ComponentCtrl) { PropertyAccess propertyAccess = ((ComponentCtrl) cmp).getPropertyAccess(field); if (propertyAccess != null) { try { propertyAccess.setValue(cmp, Classes.coerce(propertyAccess.getType(), value)); return; // done } catch (ClassCastException cce) { // yes, ignore it here and use the old EL way. } } } Fields.set(cmp, field, value, true); } catch (NoSuchMethodException e) { if (cmp instanceof DynamicPropertied) { ((DynamicPropertied) cmp).setDynamicProperty(field, value); } } } public String getExpressionString() { return "self." + field; } public Class getType(XelContext xelc) { return Object.class; } public ValueReference getValueReference(XelContext xelc) { return null; } }