/* InitChildrenBindingImpl Purpose: Description: History: 2012/1/2 Created by Dennis Chen Copyright (C) 2011 Potix Corporation. All Rights Reserved. */ package org.zkoss.bind.impl; import java.util.List; import java.util.Map; import org.zkoss.bind.BindContext; import org.zkoss.bind.Binder; import org.zkoss.bind.Converter; import org.zkoss.bind.sys.BindEvaluatorX; import org.zkoss.bind.sys.BinderCtrl; import org.zkoss.bind.sys.ConditionType; import org.zkoss.bind.sys.InitChildrenBinding; import org.zkoss.bind.sys.debugger.BindingExecutionInfoCollector; import org.zkoss.bind.sys.debugger.impl.info.LoadInfo; import org.zkoss.bind.xel.zel.BindELContext; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.UiException; import org.zkoss.zul.ListModel; import org.zkoss.zul.event.ListDataListener; /** * Implementation of {@link InitChildrenBinding}. * @author Dennis * @since 6.0.0 */ public class InitChildrenBindingImpl extends ChildrenBindingImpl implements InitChildrenBinding { private static final long serialVersionUID = 1463169907348730644L; public InitChildrenBindingImpl(Binder binder, Component comp, String initExpr, Map<String, Object> bindingArgs, String converterExpr, Map<String, Object> converterArgs) { super(binder, comp, initExpr, ConditionType.PROMPT, null, bindingArgs, converterExpr, converterArgs); } protected boolean ignoreTracker() { //init only loaded once, so it don't need to add to tracker. return true; } @SuppressWarnings("unchecked") public void load(BindContext ctx) { final Component comp = getComponent(); //ctx.getComponent(); final BindEvaluatorX eval = getBinder().getEvaluatorX(); final BindingExecutionInfoCollector collector = ((BinderCtrl) getBinder()).getBindingExecutionInfoCollector(); //get data from property Object value = eval.getValue(ctx, comp, _accessInfo.getProperty()); //use _converter to convert type if any final Converter conv = getConverter(); Object old = value; if (conv != null) { value = conv.coerceToUi(value, comp, ctx); if (value == Converter.IGNORED_VALUE) { if (collector != null) { collector.addInfo(new LoadInfo(LoadInfo.CHILDREN_INIT, comp, null, getPropertyString(), null, old, getArgs(), "*Converter.IGNORED_VALUE")); } return; } } comp.getChildren().clear(); BindELContext.removeModel(comp); if (value != null) { List<Object> data = null; if (value instanceof List) { data = (List<Object>) value; } else { throw new UiException(value + " is not a List, is " + value.getClass()); } BindChildRenderer renderer = new BindChildRenderer(); BindELContext.addModel(comp, data); //ZK-758. @see AbstractRenderer#addItemReference //ZK-2545 - Children binding support list model boolean isUsingListModel = old instanceof ListModel; if (isUsingListModel) { ListDataListener dataListener = new ChildrenBindingListDataListener(comp, ctx, conv); ((ListModel<?>) old).addListDataListener(dataListener); comp.setAttribute(BinderCtrl.CHILDREN_BINDING_MODEL, old); final Object attribute = comp.setAttribute(BinderCtrl.CHILDREN_BINDING_MODEL_LISTENER, dataListener); if (attribute instanceof ListDataListener) // B80-ZK-2927 ((ListModel<?>) old).removeListDataListener((ListDataListener) attribute); } int size = data.size(); for (int i = 0; i < size; i++) { renderer.render(comp, data.get(i), i, size, isUsingListModel); } } if (collector != null) { collector.addInfo(new LoadInfo(LoadInfo.CHILDREN_INIT, comp, null, getPropertyString(), null, value, getArgs(), null)); } } }