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

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

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

	Purpose:
		
	Description:
		
	History:
		2012/1/4 Created by Dennis Chen

Copyright (C) 2011 Potix Corporation. All Rights Reserved.
*/
package org.zkoss.bind.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.zkoss.bind.BindContext;
import org.zkoss.bind.Binder;
import org.zkoss.bind.sys.BindEvaluatorX;
import org.zkoss.bind.sys.BinderCtrl;
import org.zkoss.bind.sys.Binding;
import org.zkoss.bind.sys.TemplateResolver;
import org.zkoss.xel.ExpressionX;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.util.Template;

/**
 * The resolver resolves template and handles template changes
 * @author dennis
 * @since 6.0.0
 */
@SuppressWarnings("deprecation")
public class TemplateResolverImpl implements TemplateResolver, /*Binding,*/ Serializable{//implement binding for tieValue
	private static final long serialVersionUID = 1L;
	private final String _templateExpr;
	private final Map _templateArgs;
	private final Binder _binder;
	private final String _attr;
	private final Component _comp;
	private final ExpressionX _expression;
	
	public TemplateResolverImpl(Binder binder, Component comp, String attr, String templateExpr, Map templateArgs) {
		_binder = binder;
		_comp = comp;
		_templateExpr = templateExpr;
		_templateArgs = templateArgs;
		_attr = attr;
		//don't need to pass this, since add tracker was do by loadbinding
		final BindContext ctx = BindContextUtil.newBindContext(binder, null, false, null, _comp, null);
		_expression = binder.getEvaluatorX().parseExpressionX(ctx, templateExpr, Object.class);
	}
	
	public Binder getBinder(){
		return _binder;
	}
	
	public Component getComponent(){
		return _comp;
	}
	
	public String getExpression(){
		return _templateExpr;
	}
	

	public Map getTemplateArgs() {
		return _templateArgs;
	}

	public String getAttr() {
		return _attr;
	}

	private Template lookupTemplate(Component comp, String name) {
		if(comp==null) return null;
		Template template = comp.getTemplate(name);
		return template==null?lookupTemplate(comp.getParent(),name):template;
	}
	protected Object evaluateTemplate(Component eachComp,final Object eachData, final int index, final int size){
		return evaluateTemplate(eachComp, eachData, index, size, null);
	}
	protected Object evaluateTemplate(Component eachComp,final Object eachData, final int index, final int size, final String subType){
		Object oldEach = null;
		Object oldStatus = null;
		try {
			//TODO set subtype to evaluation context, so can use it as a condition.
			
			//prepare each and eachStatus
			oldEach = eachComp.setAttribute(EACH_VAR, eachData);
			oldStatus = eachComp.setAttribute(EACH_STATUS_VAR, new AbstractForEachStatus(){
				private static final long serialVersionUID = 1L;
				
				public int getIndex() {
					return index;
				}
				
				public Object getEach(){
					return eachData;
				}
				
				public Integer getEnd(){
					if(size<0){
						throw new UiException("end attribute is not supported");// the tree case
					}
					return size;
				}
			});
			
			final BindEvaluatorX eval = _binder.getEvaluatorX();
			final BindContext ctx = BindContextUtil.newBindContext(_binder, null, false, null, eachComp, null);
			final Object value = eval.getValue(ctx, eachComp, _expression);
			return value;
		} finally {
			eachComp.setAttribute(EACH_VAR, oldEach);
			eachComp.setAttribute(EACH_STATUS_VAR, oldStatus);
		}
	}
	
	public Template resolveTemplate(Component eachComp, final Object eachData, final int index, final int size) {
		return resolveTemplate(eachComp, eachData, index, size, null);
	}
	
	public Template resolveTemplate(Component eachComp, final Object eachData, final int index, final int size, final String subType) {
			final Object value = evaluateTemplate(eachComp,eachData,index,size,subType);
			if(value instanceof Template){
				return (Template) value;
			}else if(value instanceof String){
				//lookup from each, to allow put template in rows
				Template template = lookupTemplate(eachComp,subType==null?(String)value:(String)value+":"+subType);
				if (template == null && ((String)value).indexOf('.') > 0) { //might be a class path
					try {
						template = (Template) _comp.getPage().resolveClass(((String)value)).newInstance();
					} catch (Exception e) {
						//ignore;
					}
				}
				return template;
			}else{
				throw new UiException("unknow template type "+value);
			}
	}
	
    //ZK-739: Allow dynamic template for collection binding.	
	//Tracking template expression to trigger load binding of the template component
	@Deprecated
	public void addTemplateTracking(final Component eachComp) {
		List bindings = ((BinderCtrl)_binder).getLoadPromptBindings(_comp,_attr);
		final Binding binding = bindings.size()>0?bindings.get(bindings.size()-1):null;
		if(binding!=null){
			//following is for making tracker traces _teamplateExpr with binding
			final BindContext ctx = BindContextUtil.newBindContext(_binder, binding, false, null, eachComp, null);
			final BindEvaluatorX eval = _binder.getEvaluatorX();
			final ExpressionX exprX = eval.parseExpressionX(ctx, _templateExpr, Object.class); 
			eval.getValue(ctx, eachComp, exprX);
		}
	}
	
    //ZK-739: Allow dynamic template for collection binding.	
	//Tracking template expression to trigger load binding of the template component
	public void addTemplateTracking(final Component eachComp,final Object eachData, final int index, final int size) {
		Binding binding = getTemplateBinding(eachComp,eachData, index, size);
		if(binding!=null){
			//following is for making tracker traces _teamplateExpr with binding
			final BindContext ctx = BindContextUtil.newBindContext(_binder, binding, false, null, eachComp, null);
			final BindEvaluatorX eval = _binder.getEvaluatorX();
			final ExpressionX exprX = eval.parseExpressionX(ctx, _templateExpr, Object.class); 
			eval.getValue(ctx, eachComp, exprX);
		}
	}
	
	//Gets the binding that will be tacker when template change.
	protected Binding getTemplateBinding(Component eachComp, Object eachData, int index, int size) {
		List bindings = ((BinderCtrl)_binder).getLoadPromptBindings(_comp,_attr);
		final Binding loadbinding = bindings.size()>0?bindings.get(bindings.size()-1):null;
		return loadbinding;
	}

	public String toString(){
		StringBuilder sb = new StringBuilder();
		sb.append("[").append(_templateExpr).append("]").append(super.toString());
		return sb.toString();
	}
	
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy