1. 程式人生 > >自定義—擴充套件struts2的標籤

自定義—擴充套件struts2的標籤

package com.jdgm.platform.common.tag;

import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

import com.jdgm.framework.utils.BeanUtils;
import com.jdgm.framework.utils.ResourceUtil;
import com.jdgm.framework.utils.Utils;
import com.jdgm.platform.ConstantsPF;
import com.jdgm.platform.components.log.LogUtil;
import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.ValueStack;


/**
 * 
 * struts的標籤擴充套件從這裡繼承
 * 相比於從BodyTagSupport擴充套件,具有以下優勢:
 * 1)國際化的解決:CommonStrutsTag的子類可以享有和struts自帶標籤一樣的國際化解決方案
 * 2)值棧:CommonStrutsTag的子類,可以獲取valuestack的例項,也可以通過類屬性<valueproperty>
 *       來做與action對應屬性的雙向繫結,即值提交與值填充<具體參見屬性valueproperty的說明>
 *   
 * @author zhangpf
 * 
 */
public abstract class CommonStrutsTag extends ComponentTagSupport {
	
	/**
	 * 網站的URL地址,系統賦值。
	 */
	protected  String ctx;
	
	protected String id;

	protected String templateFile;
	
	protected String showdiv;
	
	public String getShowdiv() {
		return showdiv;
	}

	public void setShowdiv(String showdiv) {
		this.showdiv = showdiv;
	}

	/**
	 * 所有屬性列表
	 */
	protected List<String> propertys = new ArrayList<String>();
	{
		propertys.add("ctx");
		propertys.add("id");
		propertys.add("showdiv");

	}
	/**
	 * 需要在字類中特殊處理的屬性集合
	 */
	protected List<String> specproperty = new ArrayList<String>();

	/**
	 * URL相關的屬性
	 */
	protected List<String> urlproperty = new ArrayList<String>();
	
	/**
	 * 需要從valuestack中取值的相關的屬性  <br/>
	 * 比如:控制元件具有一屬性:titlefield,值為"model.title" <br/>
	 * 對應的控制元件原始碼為:< input  name="%{titlefield}" /> <br/>
	 * 這樣的話,就完成了與action中屬性model.title的單向繫結,即提交表單時<br/>
	 * input的值會自動填充到action中的對應屬性。但是卻無法做到把action中屬性的值<br/>
	 * 反向填充到input控制元件。若想做到這一點,可修改控制元件原始碼為:<br/>
	 * < input  name="%{titlefield}"  value="%{title}"/><br/>
	 * 同時,在tag子類中,再定義一屬性title,並把新增到valueproperty中,<br/>
	 * 然後在init()中,為title賦值為:"model.title",這樣就完成了action屬性值與input控制元件的反向繫結<br/>
	 * 即通過action地址開啟jsp頁面時,若action中model.title不為空,則會把該屬性的值自動賦給控制元件 <br/>
	 */
	protected List<String> valueproperty = new ArrayList<String>();
	
	
	
	@Override
	public Component getBean(ValueStack arg0, HttpServletRequest arg1,
			HttpServletResponse arg2) {
		init();
		CommonStrutsComponent cmp=new CommonStrutsComponent(arg0);
		
		return cmp;
	}
	@Override
	 protected void populateParams() {
		  super.populateParams();
		  
		  CommonStrutsComponent cmp=(CommonStrutsComponent)component;
		  cmp.setHtmlContent(toHTML());
	}
	/**
	 * 該方法用於在構建標籤前,對標籤內的各屬性做預處理用的
	 * 主要方便子類擴充套件
	 */
    protected  void init(){
    	
    }
    final protected String toHTML() {
		ctx=ConstantsPF.URL_WEBSITE;
		try {
			StringBuilder string = new StringBuilder(IOUtils.toString(
					CommonTag.class.getResourceAsStream(templateFile), "UTF-8"));
			
			for (String pro : propertys) {
				if(specproperty.contains(pro)
					||valueproperty.contains(pro)
					||urlproperty.contains(pro))
					continue;
				
				String regex = "%{" + pro + "}";
				while (string.indexOf(regex) != -1) {
					int index = string.indexOf(regex);
					String provalue = String.valueOf( PropertyUtils.getProperty(this,pro));
					if (StringUtils.isNotBlank(provalue)) {
												
						string.replace(index, index + regex.length(),provalue);
						
					} else {
						provalue = "";
						string.replace(index, index + regex.length(), provalue);
					}
				}
			}
			dealUrlProperty(string);
			dealValueProperty(string);
			dealSpecProperty(string);
			return string.toString();	

		} catch (Exception e) {
			LogUtil.error("生成控制元件失敗", e);
		}
		 return "";
	 }
    /**
     * url 相關的處理
     * @param string
     * @throws Exception
     */
     protected void dealUrlProperty(StringBuilder string)throws Exception
     {
    	 for (String pro : urlproperty) {
 			
 			String regex = "%{" + pro + "}";
 			
			while (string.indexOf(regex) != -1) {
				int index = string.indexOf(regex);
				String provalue = String.valueOf( PropertyUtils.getProperty(this,pro));
				if (StringUtils.isNotBlank(provalue)) {
					
					provalue = ctx + provalue;
					string.replace(index, index + regex.length(),provalue);
	
				} else {
					provalue = "";
					string.replace(index, index + regex.length(), provalue);
				}
			}
 		}
     }
 	/**
 	 * 需要從valuestack中取值的相關的屬性
 	 */
	 protected void dealValueProperty(StringBuilder string) throws Exception
	 {
		
		for (String pro : valueproperty) {
			
			String regex = "%{" + pro + "}";
			while (string.indexOf(regex) != -1) {
				int index = string.indexOf(regex);
				String field = String.valueOf(PropertyUtils.getProperty(this,pro));
				
				if (StringUtils.isNotBlank(field)) {
					String fieldValue=this.getStack().findString(field);
					if(fieldValue==null)
						fieldValue="";
						string.replace(index, index + regex.length(),fieldValue);
				}
				else {
					
					string.replace(index, index + regex.length(), "");
				}
			}
		}
	 }
	 
	 /**
	 * 處理特殊屬性,主要用於子類擴充套件
	 */
	protected  void dealSpecProperty(StringBuilder string) throws Exception{
		
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public  String getCtx() {
		return ctx;
	}

	public  void setCtx(String ctx1) {
		ctx = ctx1;
	}

	

}
class CommonStrutsComponent extends Component {
	private String htmlContent;

	public String getHtmlContent() {
		return htmlContent;
	}

	public void setHtmlContent(String htmlContent) {
		this.htmlContent = htmlContent;
	}

	public CommonStrutsComponent(ValueStack stack) {
		super(stack);
		
	}
	public boolean start(Writer writer) {
		
		 boolean result = super.start(writer);
		 try
		 {
			 
			 writer.write(htmlContent);
		 }
	    catch (Exception ex) {
	    	ex.printStackTrace();
	    }
		 return result;
	}
}