View Javadoc

1   /*
2    * $Id: IncludeTag.java 421129 2006-07-12 05:13:54Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.struts.taglib.bean;
19  
20  import org.apache.struts.taglib.TagUtils;
21  import org.apache.struts.util.MessageResources;
22  import org.apache.struts.util.RequestUtils;
23  
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.jsp.JspException;
26  import javax.servlet.jsp.tagext.TagSupport;
27  
28  import java.io.BufferedInputStream;
29  import java.io.InputStreamReader;
30  
31  import java.net.HttpURLConnection;
32  import java.net.MalformedURLException;
33  import java.net.URL;
34  import java.net.URLConnection;
35  
36  import java.util.Map;
37  
38  /***
39   * Define the contents of a specified intra-application request as a page
40   * scope attribute of type <code>java.lang.String</code>.  If the current
41   * request is part of a session, the session identifier will be included in
42   * the generated request, so it will be part of the same session. <p>
43   * <strong>FIXME</strong>:  In a servlet 2.3 environment, we can use a wrapped
44   * response passed to RequestDispatcher.include().
45   *
46   * @version $Rev: 421129 $ $Date: 2005-08-21 19:08:45 -0400 (Sun, 21 Aug 2005)
47   *          $
48   */
49  public class IncludeTag extends TagSupport {
50      // ------------------------------------------------------------- Properties
51  
52      /***
53       * Buffer size to use when reading the input stream.
54       */
55      protected static final int BUFFER_SIZE = 256;
56  
57      /***
58       * The message resources for this package.
59       */
60      protected static MessageResources messages =
61          MessageResources.getMessageResources(
62              "org.apache.struts.taglib.bean.LocalStrings");
63  
64      /***
65       * The anchor to be added to the end of the generated hyperlink.
66       */
67      protected String anchor = null;
68  
69      /***
70       * The name of the global <code>ActionForward</code> that contains a path
71       * to our requested resource.
72       */
73      protected String forward = null;
74  
75      /***
76       * The absolute URL to the resource to be included.
77       */
78      protected String href = null;
79  
80      /***
81       * The name of the scripting variable that will be exposed as a page scope
82       * attribute.
83       */
84      protected String id = null;
85  
86      /***
87       * The context-relative URI of the page or servlet to be included.
88       */
89      protected String page = null;
90  
91      /***
92       * Include transaction token (if any) in the hyperlink?
93       */
94      protected boolean transaction = false;
95      protected boolean useLocalEncoding = false;
96  
97      public String getAnchor() {
98          return (this.anchor);
99      }
100 
101     public void setAnchor(String anchor) {
102         this.anchor = anchor;
103     }
104 
105     public String getForward() {
106         return (this.forward);
107     }
108 
109     public void setForward(String forward) {
110         this.forward = forward;
111     }
112 
113     public String getHref() {
114         return (this.href);
115     }
116 
117     public void setHref(String href) {
118         this.href = href;
119     }
120 
121     public String getId() {
122         return (this.id);
123     }
124 
125     public void setId(String id) {
126         this.id = id;
127     }
128 
129     public String getPage() {
130         return (this.page);
131     }
132 
133     public void setPage(String page) {
134         this.page = page;
135     }
136 
137     public boolean getTransaction() {
138         return (this.transaction);
139     }
140 
141     public void setTransaction(boolean transaction) {
142         this.transaction = transaction;
143     }
144 
145     public boolean isUseLocalEncoding() {
146         return useLocalEncoding;
147     }
148 
149     public void setUseLocalEncoding(boolean b) {
150         useLocalEncoding = b;
151     }
152 
153     // --------------------------------------------------------- Public Methods
154 
155     /***
156      * Define the contents returned for the specified resource as a page scope
157      * attribute.
158      *
159      * @throws JspException if a JSP error occurs
160      */
161     public int doStartTag() throws JspException {
162         // Set up a URLConnection to read the requested resource
163         Map params =
164             TagUtils.getInstance().computeParameters(pageContext, null, null,
165                 null, null, null, null, null, transaction);
166 
167         // FIXME - <html:link> attributes
168         String urlString = null;
169         URL url = null;
170 
171         try {
172             urlString =
173                 TagUtils.getInstance().computeURLWithCharEncoding(pageContext,
174                     forward, href, page, null, null, params, anchor, false,
175                     useLocalEncoding);
176 
177             if (urlString.indexOf(':') < 0) {
178                 HttpServletRequest request =
179                     (HttpServletRequest) pageContext.getRequest();
180 
181                 url = new URL(RequestUtils.requestURL(request), urlString);
182             } else {
183                 url = new URL(urlString);
184             }
185         } catch (MalformedURLException e) {
186             TagUtils.getInstance().saveException(pageContext, e);
187             throw new JspException(messages.getMessage("include.url",
188                     e.toString()));
189         }
190 
191         URLConnection conn = null;
192 
193         try {
194             // Set up the basic connection
195             conn = url.openConnection();
196             conn.setAllowUserInteraction(false);
197             conn.setDoInput(true);
198             conn.setDoOutput(false);
199 
200             // Add a session id cookie if appropriate
201             HttpServletRequest request =
202                 (HttpServletRequest) pageContext.getRequest();
203 
204             addCookie(conn, urlString, request);
205 
206             // Connect to the requested resource
207             conn.connect();
208         } catch (Exception e) {
209             TagUtils.getInstance().saveException(pageContext, e);
210             throw new JspException(messages.getMessage("include.open",
211                     url.toString(), e.toString()));
212         }
213 
214         // Copy the contents of this URL
215         StringBuffer sb = new StringBuffer();
216 
217         try {
218             BufferedInputStream is =
219                 new BufferedInputStream(conn.getInputStream());
220             InputStreamReader in = new InputStreamReader(is); // FIXME- encoding
221             char[] buffer = new char[BUFFER_SIZE];
222             int n = 0;
223 
224             while (true) {
225                 n = in.read(buffer);
226 
227                 if (n < 1) {
228                     break;
229                 }
230 
231                 sb.append(buffer, 0, n);
232             }
233 
234             in.close();
235         } catch (Exception e) {
236             TagUtils.getInstance().saveException(pageContext, e);
237             throw new JspException(messages.getMessage("include.read",
238                     url.toString(), e.toString()));
239         }
240 
241         // Define the retrieved content as a page scope attribute
242         pageContext.setAttribute(id, sb.toString());
243 
244         // Skip any body of this tag
245         return (SKIP_BODY);
246     }
247 
248     /***
249      * Add a session id cookie if appropriate. Can be overloaded to support a
250      * cluster.
251      *
252      * @param conn
253      * @param urlString
254      * @param request
255      * @since Struts 1.2.0
256      */
257     protected void addCookie(URLConnection conn, String urlString,
258         HttpServletRequest request) {
259         if ((conn instanceof HttpURLConnection)
260             && urlString.startsWith(request.getContextPath())
261             && (request.getRequestedSessionId() != null)
262             && request.isRequestedSessionIdFromCookie()) {
263             StringBuffer sb = new StringBuffer("JSESSIONID=");
264 
265             sb.append(request.getRequestedSessionId());
266             conn.setRequestProperty("Cookie", sb.toString());
267         }
268     }
269 
270     /***
271      * Release all allocated resources.
272      */
273     public void release() {
274         super.release();
275         anchor = null;
276         forward = null;
277         href = null;
278         id = null;
279         page = null;
280         transaction = false;
281     }
282 }