View Javadoc
1   /**
2    * Copyright By Grandsoft Company Limited.  
3    * 2014年4月25日 下午4:32:15
4    */
5   package gboat2.base.view.components;
6   
7   import gboat2.base.bridge.util.BundleUtil;
8   import gboat2.base.view.GboatViewUtil;
9   
10  import java.io.Writer;
11  import java.util.HashSet;
12  import java.util.Set;
13  
14  import javax.servlet.http.HttpServletRequest;
15  import javax.servlet.http.HttpServletResponse;
16  
17  import org.apache.struts2.JSPRuntime;
18  import org.apache.struts2.ServletActionContext;
19  import org.apache.struts2.StrutsConstants;
20  import org.apache.struts2.components.Component;
21  import org.apache.struts2.components.Include;
22  import org.apache.struts2.views.annotations.StrutsTag;
23  import org.apache.struts2.views.annotations.StrutsTagAttribute;
24  import org.osgi.framework.Bundle;
25  
26  import com.opensymphony.xwork2.ActionContext;
27  import com.opensymphony.xwork2.ActionInvocation;
28  import com.opensymphony.xwork2.inject.Inject;
29  import com.opensymphony.xwork2.util.ValueStack;
30  import com.opensymphony.xwork2.util.logging.Logger;
31  import com.opensymphony.xwork2.util.logging.LoggerFactory;
32  
33  /**
34   * JSP 页面标签,设置页面级全局参数
35   * @author <a href="mailto:[email protected]">何明旺</a>
36   * @since 3.0
37   * @date 2014年4月25日
38   */
39  @StrutsTag(
40          name="page",
41          tldTagClass="gboat2.base.view.jsp.PageTag",
42          description="JSP 页面标签,处理页面继承和设置页面全局参数")
43  public class Page extends Component{
44      
45      private static final Logger LOG = LoggerFactory.getLogger(Page.class);
46      
47      protected HttpServletRequest request;
48      protected HttpServletResponse response;
49      protected Set<String> requestAttrNames = new HashSet<String>();
50  
51      protected String extend;
52      protected String encoding;
53      protected String readonly;
54      
55      public Page(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
56          super(stack);
57          this.request = request;
58          this.response = response;
59      }
60  
61      protected void evaluateParams() {
62          request.setAttribute("contextPath", request.getContextPath());
63          addParameterWithRequest("readonly", readonly, Boolean.class, GboatViewUtil.PAGE_READONLY_KEY);
64          if (extend != null) {
65              addParameter("extend", findString(extend));
66          }
67      }
68  
69      protected void addParameterWithRequest(String fieldName, String expr, Class<?> valueType, String attrName) {
70          Object obj = request.getAttribute(attrName); // 从 request 中获取
71          
72          if (obj == null && expr != null) {
73              obj = findValue(expr, valueType);
74              request.setAttribute(attrName, obj);
75              requestAttrNames.add(attrName);
76          }
77  
78          if (obj != null) {
79              addParameter(fieldName, obj);
80          }
81      } 
82    
83      @Override
84      public boolean end(Writer writer, String body) {
85          evaluateParams();
86          if (extend != null) {
87              String page = findString(extend);
88              page = Include.getContextRelativePath(request, page);
89              
90              ActionContext actionContext = ServletActionContext.getContext();
91              ActionInvocation invocation = actionContext.getActionInvocation();
92              
93              Bundle bundle = BundleUtil.getBundleForRequestJsp(page, invocation);
94              if(bundle != null && !page.startsWith("/" + bundle.getSymbolicName() + "/")) {
95                  page = "/" + bundle.getSymbolicName() + page;
96              }
97              /*
98              // 使用 struts2-convention-plugin 的 ConventionsService 对路径 进行转换处理
99              Container container = actionContext.getContainer();
100             ConventionsService conventionsService = container.getInstance(ConventionsService.class,
101                   container.getInstance(String.class, ConventionConstants.CONVENTION_CONVENTIONS_SERVICE));
102             page = (conventionsService.determineResultPath(invocation.getAction().getClass()) + "/" + page).replaceAll("/+", "/");
103            */
104    
105             try {
106                 // 编译、执行 JSP
107                 JSPRuntime.handle(page, false, invocation, bundle);
108             } catch (Exception e1) {
109                 LOG.error("解析继承的 JSP 文件[#0] 发生错误。", e1, page);
110             }
111         }
112         
113         // 调用父类中的实现
114         boolean result = super.end(writer, body);
115         
116         // 将当前标签设置在 request 中的 Attribute 全部移除
117         for (String key : requestAttrNames) {
118             request.removeAttribute(key);
119         }
120         
121         return result;
122     }
123 
124     @StrutsTagAttribute(description="继承页面(父页面)")
125     public void setExtend(String extend) {
126         this.extend = extend;
127     }
128 
129     @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
130     @StrutsTagAttribute(description = "父页面的字符编码,如:UTF-8。如果不指定,则默认为 struts.xml 中常量“struts.i18n.encoding” 设置的值")
131     public void setEncoding(String encoding) {
132         this.encoding = encoding;
133     }
134    
135     @StrutsTagAttribute(description="页面中的表单元素是否为不可编辑(适用于 查看、打印 等页面)", type="Boolean", defaultValue="false")
136     public void setReadonly(String readonly) {
137         this.readonly = readonly;
138     }
139 }