KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > module > sitemesh > taglib > page > ApplyDecoratorTag


1 /*
2  * Title: ApplyDecoratorTag
3  * Description:
4  *
5  * This software is published under the terms of the OpenSymphony Software
6  * License version 1.1, of which a copy has been included with this
7  * distribution in the LICENSE.txt file.
8  */

9
10 package com.opensymphony.module.sitemesh.taglib.page;
11
12 import com.opensymphony.module.sitemesh.*;
13 import com.opensymphony.module.sitemesh.filter.PageRequestWrapper;
14 import com.opensymphony.module.sitemesh.filter.PageResponseWrapper;
15
16 import javax.servlet.RequestDispatcher JavaDoc;
17 import javax.servlet.ServletException JavaDoc;
18 import javax.servlet.http.HttpServletRequest JavaDoc;
19 import javax.servlet.http.HttpServletResponse JavaDoc;
20 import javax.servlet.jsp.JspException JavaDoc;
21 import javax.servlet.jsp.tagext.BodyTagSupport JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.BufferedReader JavaDoc;
24 import java.io.InputStreamReader JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.net.URL JavaDoc;
29 import java.net.URLConnection JavaDoc;
30 import java.net.MalformedURLException JavaDoc;
31
32 /**
33  * This tag inserts an external resource as a panel into the current Page.
34  *
35  * <p>The page attribute should point to the panel resource
36  * which should expose an entire page (e.g. another JSP file producing
37  * HTML). This attribute can be relative to the page it is being called
38  * from or an absolute path from the context-root.</p>
39  *
40  * <p><strong>OR</strong></p>
41  *
42  * <p>If the page attribute is not specified, the body content is parsed
43  * into the {@link com.opensymphony.module.sitemesh.Page} object and has
44  * the {@link com.opensymphony.module.sitemesh.Decorator} applied.</p>
45  *
46  * <p>The (optional) decorator attribute is the name of the
47  * {@link com.opensymphony.module.sitemesh.Decorator}
48  * to apply to the included page. Note that the implementation of
49  * {@link com.opensymphony.module.sitemesh.DecoratorMapper} can overide this.</p>
50  *
51  * @author <a HREF="mailto:joe@truemesh.com">Joe Walnes</a>
52  * @version $Revision: 1.6 $
53  */

54 public class ApplyDecoratorTag extends BodyTagSupport JavaDoc implements RequestConstants {
55     private String JavaDoc page = null;
56     private String JavaDoc decorator = null;
57
58     private String JavaDoc contentType = null;
59     private String JavaDoc encoding = null;
60
61     private Map JavaDoc params = new HashMap JavaDoc(6);
62     private Config config = null;
63     private DecoratorMapper decoratorMapper = null;
64     private Factory factory;
65
66     /**
67      * Tag attribute: URI of page to include.
68      * Can be relative to page being called from, or absolute
69      * path from context-root of web-app.
70      */

71     public void setPage(String JavaDoc page) {
72         this.page = page;
73     }
74
75     /**
76      * Add a parameter to the page. This has a package level
77      * access modifier so ParamTag can also call it.
78      */

79     void addParam(String JavaDoc name, String JavaDoc value) {
80         params.put(name, value);
81     }
82
83     /**
84      * Tag attribute: If set, this value will override the 'title'
85      * property of the page. This is a convenience utility and is
86      * identical to specifing a 'page:param name=title' tag.
87      */

88     public void setTitle(String JavaDoc title) {
89         addParam("title", title);
90     }
91
92     /**
93      * Tag attribute: If set, this value will override the 'id'
94      * property of the page. This is a convenience utility and is
95      * identical to specifing a 'page:param name=id' tag.
96      */

97     public void setId(String JavaDoc id) {
98         addParam("id", id);
99     }
100
101     /**
102      * Tag attribute: Name of Decorator to apply to Page.
103      * This is passed to DecoratorMapper to retrieve appropriate
104      * Decorator. DecoratorMapper may override if needed.
105      *
106      * @see com.opensymphony.module.sitemesh.DecoratorMapper
107      */

108     public void setName(String JavaDoc decorator) {
109         if (decorator != null) this.decorator = decorator;
110     }
111
112     /** @deprecated Use setName() instead. */
113     public void setDecorator(String JavaDoc decorator) {
114         setName(decorator);
115     }
116
117     public void setContentType(String JavaDoc contentType) {
118         this.contentType = contentType;
119     }
120
121     public void setEncoding(String JavaDoc encoding) {
122         this.encoding = encoding;
123     }
124
125     public int doStartTag() {
126         if (config == null) {
127             // set context if not already set
128
config = new Config(pageContext.getServletConfig());
129             factory = Factory.getInstance(config);
130             decoratorMapper = factory.getDecoratorMapper();
131         }
132         // return page == null ? EVAL_BODY_BUFFERED : SKIP_BODY;
133
return EVAL_BODY_BUFFERED;
134     }
135
136     /** Ensure that external page contents are included in bodycontent. */
137     public int doAfterBody() throws JspException JavaDoc {
138         return SKIP_BODY;
139     }
140
141     /** Standard taglib method: apply decorator to page. */
142     public int doEndTag() throws JspException JavaDoc {
143         try {
144             // if composite decorator, remember last page
145
Page oldPage = (Page) pageContext.getRequest().getAttribute(PAGE);
146
147             // parse bodycontent into Page object
148
PageParser parser = Factory.getInstance(config).getPageParser(contentType != null ? contentType : "text/html");
149             Page pageObj = null;
150
151             if (page == null) {
152                 // inline content
153
pageObj = parser.parse(bodyContent.getString().toCharArray());
154             }
155             else if (page.startsWith("http://") || page.startsWith("https://")) {
156                 try {
157                     URL JavaDoc url = new URL JavaDoc(page);
158                     URLConnection JavaDoc urlConn = url.openConnection();
159                     urlConn.setUseCaches(true);
160                     BufferedReader JavaDoc in = new BufferedReader JavaDoc(
161                             new InputStreamReader JavaDoc(urlConn.getInputStream()));
162
163                     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
164                     char[] buf = new char[1000];
165                     for (; ;) {
166                         int moved = in.read(buf);
167                         if (moved < 0) break;
168                         sbuf.append(buf, 0, moved);
169                     }
170                     in.close();
171                     pageObj = parser.parse(sbuf.toString().toCharArray());
172                 }
173                 catch (MalformedURLException JavaDoc e) {
174                     trace(e);
175                     throw new JspException JavaDoc(e.toString());
176                 }
177                 catch (IOException JavaDoc e) {
178                     trace(e);
179                     throw new JspException JavaDoc(e.toString());
180                 }
181             }
182             else {
183                 // external content
184
String JavaDoc fullPath = page;
185                 if (fullPath.length() > 0 && fullPath.charAt(0) != '/') {
186                     HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
187
188                     // find absolute path if relative supplied
189
String JavaDoc thisPath = request.getServletPath();
190
191                     // check if it did not return null (could occur when the servlet container
192
// does not use a servlet to serve the requested resouce)
193
if (thisPath == null) {
194                         String JavaDoc requestURI = request.getRequestURI();
195                         if (request.getPathInfo() != null) {
196                             // strip the pathInfo from the requestURI
197
thisPath = requestURI.substring(0, requestURI.indexOf(request.getPathInfo()));
198                         }
199                         else {
200                             thisPath = requestURI;
201                         }
202                     }
203
204                     fullPath = thisPath.substring(0, thisPath.lastIndexOf('/') + 1) + fullPath;
205                     int dotdot;
206                     while ((dotdot = fullPath.indexOf("..")) > -1) {
207                         int prevSlash = fullPath.lastIndexOf('/', dotdot - 2);
208                         fullPath = fullPath.substring(0, prevSlash) + fullPath.substring(dotdot + 2);
209                     }
210                 }
211
212                 // include page using filter response
213
RequestDispatcher JavaDoc rd = pageContext.getServletContext().getRequestDispatcher(fullPath);
214                 PageRequestWrapper pageRequest = new PageRequestWrapper((HttpServletRequest JavaDoc) pageContext.getRequest());
215                 PageResponseWrapper pageResponse = new PageResponseWrapper((HttpServletResponse JavaDoc) pageContext.getResponse(), factory);
216
217                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc(contentType != null ? contentType : "text/html");
218                 if (encoding != null) {
219                     sb.append(";charset=").append(encoding);
220                 }
221                 pageResponse.setContentType(sb.toString());
222
223                 // if rd == null, then the panel was not found, but this isn't correct, so we need to spit out
224
// something appropriate. What this is, well...I don't know yet.
225
if (rd == null) {
226                     throw new ApplyDecoratorException("The specified resource in applyDecorator tag (" + fullPath + ") was not found.");
227                 }
228                 rd.include(pageRequest, pageResponse);
229                 pageObj = pageResponse.getPage();
230             }
231
232             // If pageObj == null, then the panel source had some weird error in
233
// it. Stop writing bugs like this. They're ugly and they make you smell funny.
234
if (pageObj == null) {
235                 throw new ApplyDecoratorException(page + " did not create a valid page to decorate.");
236             }
237
238             // add extra params to Page
239
Iterator JavaDoc paramKeys = params.keySet().iterator();
240             while (paramKeys.hasNext()) {
241                 String JavaDoc k = (String JavaDoc) paramKeys.next();
242                 String JavaDoc v = (String JavaDoc) params.get(k);
243                 pageObj.addProperty(k, v);
244             }
245
246             // get decorator
247
if (decorator == null) decorator = "";
248             pageObj.setRequest((HttpServletRequest JavaDoc) pageContext.getRequest());
249             pageContext.getRequest().setAttribute(DECORATOR, decorator);
250             Decorator d = decoratorMapper.getDecorator(((HttpServletRequest JavaDoc) pageContext.getRequest()), pageObj);
251             pageContext.getRequest().removeAttribute(DECORATOR);
252
253             // apply decorator
254
if (d != null && d.getPage() != null) {
255                 pageContext.getRequest().setAttribute(PAGE, pageObj);
256                 pageContext.include(d.getPage());
257             }
258             else {
259                 throw new JspException JavaDoc("Cannot locate inline Decorator: " + decorator);
260             }
261
262             // clean up
263
pageContext.getRequest().setAttribute(PAGE, oldPage);
264         }
265         catch (IOException JavaDoc e) {
266             trace(e);
267             throw new JspException JavaDoc(e.toString());
268         }
269         catch (ServletException JavaDoc e) {
270             trace(e);
271             throw new JspException JavaDoc(e.toString());
272         }
273         catch (ApplyDecoratorException e) {
274             try {
275                 pageContext.getOut().println(e.getMessage());
276             }
277             catch (IOException JavaDoc ioe) {
278                 System.err.println("IOException thrown in applyDecorator tag: " + e.toString());
279             }
280         }
281         return EVAL_PAGE;
282     }
283
284     /** Release all attributes */
285     public void release() {
286         params.clear();
287         super.release();
288     }
289
290     /** Log exception generated by taglib. */
291     public static void trace(Exception JavaDoc e) {
292         e.printStackTrace();
293     }
294
295     class ApplyDecoratorException extends Exception JavaDoc {
296         public ApplyDecoratorException(String JavaDoc s) {
297             super(s);
298         }
299     }
300 }
Popular Tags