All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zkoss.bind.impl.ChildrenBindingImpl Maven / Gradle / Ivy

There is a newer version: 10.0.0-jakarta
Show newest version
/* ChildrenBindingImpl.java

	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.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.ChildrenBinding;
import org.zkoss.bind.sys.ConditionType;
import org.zkoss.xel.ExpressionX;
import org.zkoss.zk.ui.Component;

/**
 * A base implementation of {@link ChildrenBinding}.
 * @author dennis
 * @since 6.0.0
 */
public abstract class ChildrenBindingImpl extends BindingImpl implements ChildrenBinding {
	private static final long serialVersionUID = 1463169907348730644L;
	protected final AccessInfo _accessInfo;
	private final ExpressionX _converter;
	private final Map _converterArgs;

	/**
	 * @param binder
	 * @param comp
	 * @param accessExpr the binding expression , to access the bean
	 * @param conditionType the condition type
	 * @param command the command, if the conditionType is not prompt, then command must not null
	 * @param bindingArgs
	 */
	protected ChildrenBindingImpl(Binder binder, Component comp, String accessExpr, 
			ConditionType conditionType, String command, Map bindingArgs,
			String converterExpr, Map converterArgs) {
		super(binder,comp, bindingArgs);
		final BindEvaluatorX eval = binder.getEvaluatorX();
		final Class returnType = Object.class;
		this._accessInfo = AccessInfo.create(this, accessExpr, returnType, conditionType, command, ignoreTracker());
		_converterArgs = converterArgs;
		_converter = converterExpr==null?null:parseConverter(eval,converterExpr);
	}
	
	//should this binding set the ignore tracker attribute when evaluate the expression.
	protected boolean ignoreTracker(){
		return false;
	}
	
	private ExpressionX parseConverter(BindEvaluatorX eval, String converterExpr) {
		final BindContext ctx = BindContextUtil.newBindContext(getBinder(), this, false, null, getComponent(), null);
		//provide a bindcontext when pare expression of converter with this binding,
		//do so, the tracker will also tracking the converter dependence with this binding.
		return eval.parseExpressionX(ctx, converterExpr, Object.class);
	}
	
	public Converter getConverter() {
		if(_converter==null) return null;

		final BindContext ctx = BindContextUtil.newBindContext(getBinder(), this, false, null, getComponent(), null);
		final BindEvaluatorX eval = getBinder().getEvaluatorX();
		Object obj = eval.getValue(ctx, getComponent(), _converter);
		
		if(obj instanceof Converter){
			return (Converter)obj;
		}else if(obj instanceof String){
			return getBinder().getConverter((String)obj);//binder will throw exception if not found
		}else{
			throw new ClassCastException("result of expression '"+_converter.getExpressionString()+"' is not a Converter, is "+obj);
		}
	}
	
	public String getCommandName() {
		return this._accessInfo.getCommandName();
	}
	
	public String getPropertyString() {
		return BindEvaluatorXUtil.getExpressionString(this._accessInfo.getProperty());
	}
	
	public ConditionType getConditionType() {
		return this._accessInfo.getConditionType();
	}
	
	/*package*/ ExpressionX getProperty() {
		return this._accessInfo.getProperty();
	}
	
	public String toString(){
		return new StringBuilder().append(getClass().getSimpleName()).append("@").append(Integer.toHexString(hashCode()))
		.append(",component:").append(getComponent())
		.append(",access:").append(getProperty().getExpressionString())
		.append(",condition:").append(getConditionType())
		.append(",command:").append(getCommandName()).toString();
	}
}