/** * Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved. * EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * http://www.ewcms.com */ package com.ewcms.publication.freemarker.directive; import java.io.IOException; import java.io.Writer; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; import com.ewcms.common.lang.EmptyUtil; import com.ewcms.publication.freemarker.FreemarkerUtil; import freemarker.core.Environment; import freemarker.template.TemplateDirectiveBody; import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; /** * 得到对象属性值 * * <p>通过设置指定属性名,得到该属性的值</p> * * @author wangwei */ public class PropertyDirective implements TemplateDirectiveModel { private static Logger logger = LoggerFactory.getLogger(PropertyDirective.class); private static final String VALUE_PARAM_NAME = "value"; private static final String NAME_PARAM_NAME = "name"; private static final String DEFAULT_LOOP_NAME = "o"; protected String valueParam = VALUE_PARAM_NAME; protected String nameParam = NAME_PARAM_NAME; protected String defaultLoop = DEFAULT_LOOP_NAME; @Override @SuppressWarnings("rawtypes") public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { String propertyName = getPropertyName(env,params); Object objectValue = getObjectValue(env, params); if(EmptyUtil.isNull(propertyName)){ logger.error("\"name\" parameter must set"); throw new TemplateModelException("\"name\" parameter must set"); } try { if(EmptyUtil.isArrayNotEmpty(loopVars)){ Object value = loopValue(objectValue,propertyName,env,params); if(EmptyUtil.isNotNull(value)){ loopVars[0] = env.getObjectWrapper().wrap(value); if(EmptyUtil.isNull(body)){ logger.warn("body is empty"); }else{ body.render(env.getOut()); } } }else if(EmptyUtil.isNotNull(body)){ Object value = loopValue(objectValue,propertyName,env,params); if(EmptyUtil.isNotNull(value)){ FreemarkerUtil.setVariable(env, defaultLoop, value); body.render(env.getOut()); FreemarkerUtil.removeVariable(env, defaultLoop); } }else{ String outValue = constructOut(objectValue,propertyName,env,params); if(EmptyUtil.isNotNull(outValue)){ Writer out = env.getOut(); out.write(outValue.toString()); out.flush(); } } } catch (NoSuchMethodException e) { Writer out = env.getOut(); out.write(e.toString()); out.flush(); throw new TemplateModelException(e.getMessage()); } } /** * 标签返回值 * * @param objectValue * 属性所属对象的值 * @param propertyName * 属性名 * @param evn * freemarker 环境 * @param params * 标签参数集合 * @return 输出返回值 * @throws TemplateModelException,NoSuchMethodException */ @SuppressWarnings("rawtypes") protected Object loopValue(Object objectValue,String propertyName,Environment env,Map params)throws TemplateException,NoSuchMethodException{ return getValue(objectValue,propertyName); } /** * 构造标签输出内容 * * @param objectValue * 属性所属对象的值 * @param propertyName * 属性名 * @param evn * freemarker 环境 * @param params * 标签参数集合 * * @return 标签输出字符串 * @throws TemplateModelException,NoSuchMethodException */ @SuppressWarnings("rawtypes") protected String constructOut(Object objectValue,String propertyName,Environment env, Map params)throws TemplateException,NoSuchMethodException{ Assert.notNull(objectValue); Object value = getValue(objectValue,propertyName); return value == null ? null : value.toString(); } /** * 缺省值对象在freemarker变量中的名称 * * @return */ protected String defaultValueParamValue(){ return null; } /** * 缺省对象值 * * @param env 环境变量 * @param param 参数列表 * @return * @throws TemplateModelException */ @SuppressWarnings("rawtypes") protected Object defaultObjectValue(Environment env, Map params)throws TemplateException{ return null; } /** * 得到对象的值 * * @param env * 环境 * @param params * 标签参数集合 * @return * @throws TemplateModelException */ @SuppressWarnings("rawtypes") protected Object getObjectValue(final Environment env, final Map params)throws TemplateException { Object object = FreemarkerUtil.getBean(params, valueParam); if (EmptyUtil.isNotNull(object)) { logger.debug("Get value is {}",object); return object; } String name = FreemarkerUtil.getString(params, valueParam); logger.debug("Get variable is {} in params",name); if(EmptyUtil.isNull(name)){ name = defaultValueParamValue(); logger.debug("Get default variable is {} in env",name); } if (EmptyUtil.isNotNull(name)) { logger.debug("Get value param is {}", name); object = FreemarkerUtil.getBean(env, name); if (EmptyUtil.isNotNull(object)) { logger.debug("Get value is {}",object); return object; } } object = defaultObjectValue(env,params); if(object != null){ return object; } logger.error("\"{}\" has not value",valueParam); throw new TemplateModelException("Object value not exist"); } /** * 得到属性名 * * @param params * 标签参数集合 * @return * @throws TemplateModelException */ @SuppressWarnings("rawtypes") protected String getPropertyName(final Environment env, final Map params)throws TemplateException { String property = FreemarkerUtil.getString(params, nameParam); if(property == null){ property = FreemarkerUtil.getString(env, nameParam); } logger.debug("Property name is {}",property); return property; } /** * 得到对象属性值 * * @param objectValue * 对象 * @param property * 属性名 * @return */ protected Object getValue(Object objectValue,String property)throws NoSuchMethodException{ try{ return PropertyUtils.getProperty(objectValue, property); }catch(NoSuchMethodException e){ throw e; }catch(Exception e){ throw new NoSuchMethodException(e.toString()); } } /** * 设置值对象参数名 * * @param name 参数名 */ public void setValueParam(String name) { valueParam = name; } /** * 设置对象属性参数名 * * @param name 参数名 */ public void setNameParam(String name){ nameParam = name; } /** * 属性值放入freemarker环境中的变量名 * * @param name 缺省loop名 */ public void setDefaultLoop(String name){ defaultLoop = name; } }