/* BindEvaluatorXUtil Purpose: Description: History: Oct 19, 2011 5:17:48 PM, Created by dennis Copyright (C) 2011 Potix Corporation. All Rights Reserved. */ package org.zkoss.bind.impl; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import org.zkoss.bind.BindContext; import org.zkoss.bind.sys.BindEvaluatorX; import org.zkoss.bind.xel.zel.ImplicitObjectELResolver; import org.zkoss.lang.Classes; import org.zkoss.lang.Library; import org.zkoss.lang.Strings; import org.zkoss.xel.ExpressionX; import org.zkoss.xel.FunctionMapper; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.UiException; /** * an internal utility to help doing evaluation. * @author dennis * @since 6.0.0 */ public class BindEvaluatorXUtil { //eval args, it it is an ExpressionX, than evaluate the value to instance public static Map<String, Object> evalArgs(BindEvaluatorX eval, Component comp, Map<String, Object> args) { return evalArgs(eval, comp, args, null); } public static Map<String, Object> evalArgs(BindEvaluatorX eval, Component comp, Map<String, Object> args, Map<String, Object> implicit) { if (args == null) { return null; } //ZK-1032 Able to wire Event to command method //for implicit objects, see ImplicitObjectELResolver BindContext ctx = null; if (implicit != null) { ctx = new BindContextImpl(null, null, false, null, null, null); ctx.setAttribute(ImplicitObjectELResolver.IMPLICIT_OBJECTS, implicit); } final Map<String, Object> result = new LinkedHashMap<String, Object>(args.size()); for (final Iterator<Entry<String, Object>> it = args.entrySet().iterator(); it.hasNext();) { final Entry<String, Object> entry = it.next(); final String key = entry.getKey(); final Object value = entry.getValue(); //evaluate the arg if it is an ExpressionX final Object evalValue = value == null ? null : (value instanceof ExpressionX) ? eval.getValue(ctx, comp, (ExpressionX) value) : value; result.put(key, evalValue); } return result; } // parse args , if it is a string, than parse it to an ExpressionX public static Map<String, Object> parseArgs(BindEvaluatorX eval, Map<String, String[]> args) { final Map<String, Object> result = AllocUtil.inst.newLinkedHashMap(args.size()); //ZK-2289 for (final Iterator<Entry<String, String[]>> it = args.entrySet().iterator(); it.hasNext();) { final Entry<String, String[]> entry = it.next(); final String key = entry.getKey(); final String[] value = entry.getValue(); addArg(eval, result, key, value); } return result; } private static void addArg(BindEvaluatorX eval, Map<String, Object> result, String key, String[] valueScript) { Object val = null; if (valueScript.length == 1) { val = eval.parseExpressionX(null, valueScript[0], Object.class); } else { //TODO support multiple value of a arg val = valueScript; } result.put(key, val); } @SuppressWarnings("unchecked") public static BindEvaluatorX createEvaluator(FunctionMapper fnampper) { String clznm = Library.getProperty("org.zkoss.bind.BindEvaluatorX.class"); if (clznm != null) { Class<BindEvaluatorX> clz; try { clz = (Class<BindEvaluatorX>) Classes.forNameByThread(clznm); return clz.getConstructor(FunctionMapper.class).newInstance(fnampper); } catch (Exception e) { UiException.Aide.wrap(e, "Can't initialize BindEvaluatorX"); } } return new BindEvaluatorXImpl(fnampper, org.zkoss.bind.xel.BindXelFactory.class); } public static <T> T eval(BindEvaluatorX evalx, Component comp, String expression, Class<T> expectedType) { return eval(evalx, comp, expression, expectedType, null); } @SuppressWarnings("unchecked") public static <T> T eval(BindEvaluatorX evalx, Component comp, String expression, Class<T> expectedType, Map<String, Object> implicit) { if (Strings.isBlank(expression)) return null; final int len = expression.length(); if (len > 2) { // string only if (expression.charAt(0) == '\'' && expression.charAt(len - 1) == '\'') { String result = expression.substring(1, len - 1); if (!result.contains("'")) return (T) result; } } BindContext ctx = null; ctx = new BindContextImpl(null, null, false, null, comp, null); if (implicit != null) { ctx.setAttribute(ImplicitObjectELResolver.IMPLICIT_OBJECTS, implicit); } ExpressionX expr = evalx.parseExpressionX(ctx, expression, expectedType); Object obj = evalx.getValue(ctx, comp, expr); return (T) obj; } //remove ${ and } public static String getExpressionString(ExpressionX expr) { if (expr == null) { return null; } final String evalstr = expr.getExpressionString(); return evalstr.substring(2, evalstr.length() - 1); } }