/* TreeModelELResolver.java Purpose: Description: History: Jan 12, 2012 3:18:34 PM, Created by henrichen Copyright (C) 2012 Potix Corporation. All Rights Reserved. */ package org.zkoss.bind.xel.zel; import java.beans.FeatureDescriptor; import java.lang.reflect.Array; import java.util.Iterator; import org.zkoss.lang.Classes; import org.zkoss.zel.ELContext; import org.zkoss.zel.ELException; import org.zkoss.zel.ELResolver; import org.zkoss.zel.PropertyNotFoundException; import org.zkoss.zel.PropertyNotWritableException; import org.zkoss.zul.TreeModel; /** * ELResolver for {@link TreeModel}. * @author dennis * @since 6.0.0 */ public class TreeModelELResolver extends ELResolver { private static final Class<?> INTEGER_ARRAY = new int[0].getClass(); public Object getValue(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException { if (context == null) { throw new NullPointerException(); } if (base instanceof TreeModel<?>) { TreeModel<?> treemodel = (TreeModel<?>) base; int[] path = coerce(property); if (path == null) { return null; } context.setPropertyResolved(true); return treemodel.getChild(path); } return null; } public Class<?> getType(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException { if (context == null) { throw new NullPointerException(); } if (base instanceof TreeModel<?>) { int[] path = coerce(property); if (path == null) return null; context.setPropertyResolved(true); return Object.class; } return null; } public void setValue(ELContext context, Object base, Object property, Object value) throws NullPointerException, PropertyNotFoundException, PropertyNotWritableException, ELException { if (context == null) { throw new NullPointerException(); } } public boolean isReadOnly(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException { return true; } public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) { // if (base instanceof TreeModel<?>) { // FeatureDescriptor[] descs = new FeatureDescriptor[1]; // descs[0] = new FeatureDescriptor(); // descs[0].setDisplayName("["+0+"]"); // descs[0].setExpert(false); // descs[0].setHidden(false); // descs[0].setName("0"); // descs[0].setPreferred(true); // descs[0].setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.FALSE); // descs[0].setValue(TYPE, _pathClass.getClass()); // return Arrays.asList(descs).iterator(); // } return null; } public Class<?> getCommonPropertyType(ELContext context, Object base) { if (base instanceof TreeModel<?>) { // implies base != null return INTEGER_ARRAY.getClass(); } return null; } private static final int[] coerce(Object property) { if (INTEGER_ARRAY.isInstance(property)) { //quick casting for int[] return (int[]) property; } final Class<?> clz = property.getClass(); if (clz.isArray()) { int s = Array.getLength(property); int[] path = new int[s]; for (int i = 0; i < s; i++) { try { path[i] = ((Integer) Classes.coerce(Integer.class, Array.get(property, i))).intValue(); } catch (Exception x) { throw new PropertyNotFoundException(x.getMessage(), x); } } return path; } //just ignore other types (especially a string) return null; } }