KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > tags > template > Template


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.tags.template;
19
20 import org.apache.beehive.netui.tags.AbstractClassicTag;
21 import org.apache.beehive.netui.tags.AbstractPageError;
22 import org.apache.beehive.netui.tags.IErrorReporter;
23 import org.apache.beehive.netui.tags.html.Html;
24 import org.apache.beehive.netui.tags.rendering.TagRenderingBase;
25 import org.apache.beehive.netui.util.Bundle;
26 import org.apache.beehive.netui.util.logging.Logger;
27 import org.apache.beehive.netui.pageflow.internal.InternalUtils;
28
29 import javax.servlet.RequestDispatcher JavaDoc;
30 import javax.servlet.ServletException JavaDoc;
31 import javax.servlet.ServletRequest JavaDoc;
32 import javax.servlet.ServletResponse JavaDoc;
33 import javax.servlet.http.HttpServletRequest JavaDoc;
34 import javax.servlet.jsp.JspException JavaDoc;
35 import javax.servlet.jsp.JspWriter JavaDoc;
36 import javax.servlet.jsp.tagext.Tag JavaDoc;
37 import java.io.IOException JavaDoc;
38 import java.net.MalformedURLException JavaDoc;
39 import java.net.URL JavaDoc;
40 import java.util.ArrayList JavaDoc;
41 import java.util.HashMap JavaDoc;
42
43 /**
44  * This tags defines the template to use within a content page. The
45  * content page interacts with the template page through children tags
46  * of the
47  * <code>Template</code> tag. The legal children are as follows:
48  * <ul>
49  * <li> <code>setAttribute</code> -- A Tag that will set an Attribute on the
50  * template.
51  * <li> <code>section</code> -- A tag that defines the content of a section
52  * defined in the template.
53  * </ul>
54  * The URL of the template file is set as the <code>templatePage</code>
55  * attribute on the
56  * <code>Template</code> tag. The Template file is included from
57  * the <code>Template</code> tag and will include sections defined
58  * in the content page. The content is contained in one or more
59  * <code>Section</code> tags, which are children of the
60  * <code>Template</code> tag. In addition, the content page can set
61  * attributes of the template page.
62
63  * @jsptagref.tagdescription
64  * Points a content page at its template page. A
65  * content page interacts with its template page through children tags
66  * of the
67  * &lt;netui-template:template> tag. The legal children are as follows:
68  * <blockquote>
69  * <ul>
70  * <li> {@link SetAttribute} -- a tag that fills a
71  * {@link Attribute} placeholder with content.
72  * <li> {@link Section} -- a tag that fills a
73  * {@link IncludeSection} placeholder with content.
74  * </ul>
75  * </blockquote>
76  * <p>The URL of the template page is specified by the <code>templatePage</code>
77  * attribute on the
78  * &lt;netui-template:template> tag.
79  *
80  * @example
81  * The following example shows a content page that adopts the template.jsp page as its template.
82  * The content page also sets the "title" attribute on the template.
83  *
84  * <pre> &lt;netui-template:template templatePage="./template.jsp">
85  * ...
86  * &lt;netui-template:setAttribute name="title" value="Template Tags Sample"/>
87  * ...
88  * &lt;/netui-template:template></pre>
89  *
90  * @netui:tag name="template"
91  * description="Use this tag to associate a JSP page with a particular template file."
92  */

93 public class Template extends AbstractClassicTag
94         implements TemplateConstants, IErrorReporter
95 {
96     private static final Logger logger = Logger.getInstance(Template.class);
97
98     public static class TemplateContext
99     {
100         HashMap JavaDoc secs = null;
101     }
102
103     /**
104      * Saved context for the nested case
105      */

106     private TemplateContext _savedContext = null;
107
108     private boolean _fatalError = false;
109
110     /**
111      * Inner class that is exposed to handle errors
112      */

113     private org.apache.beehive.netui.tags.IErrorReporter _innerErrors;
114
115     /**
116      * Returns the name of the Tag. This is used to
117      * identify the type of tag reporting errors.
118      */

119     public String JavaDoc getTagName() {
120         return "Template";
121     }
122
123     /**
124      * The URL of the template file...
125      */

126     private String JavaDoc _templatePage;
127
128     /**
129      * boolean indicating the error reporting.
130      */

131     private boolean _reportErrors = false;
132
133     /**
134      * Set the boolean indicating that the template should report errors. The
135      * errors will be reported through a HTML tag that must be found
136      * in the template JSP.
137      * @param reportErrors boolean indicating that errors should be reported
138      *
139      * @jsptagref.attributedescription
140      * Boolean. Determines if the template should report errors.
141      * The errors will be reported inline on the JSP page.
142      *
143      * @jsptagref.databindable false
144      *
145      * @jsptagref.attributesyntaxvalue <i>boolean_reportErrors</i>
146      *
147      * @netui:attribute required="false" rtexprvalue="true"
148      * description="Determines if the template should report errors.
149      * The errors will be reported inline on the JSP page."
150      */

151     public void setReportErrors(boolean reportErrors) {
152         _reportErrors = reportErrors;
153     }
154
155     /**
156      * Set the URL of the template to use. The <code>templatePage</code>
157      * is an URL which
158      * identifies the JSP template page.
159      * @param templatePage - a URL pointing to a JSP page that represents the
160      * template.
161      *
162      * @jsptagref.attributedescription
163      * The URL of the template page to use.
164      *
165      * @jsptagref.databindable false
166      *
167      * @jsptagref.attributesyntaxvalue <i>string_urlToTemplatePage</i>
168      *
169      * @netui:attribute required="true" rtexprvalue="true"
170      * description="The URL of the template page to use."
171      */

172     public void setTemplatePage(String JavaDoc templatePage) {
173         _templatePage = templatePage;
174     }
175
176     /**
177      * @netui:attribute required="false" rtexprvalue="true"
178      * description="Set the document type (html4-loose or xhtml1-transitional) of the document."
179      */

180     public void setDocumentType(String JavaDoc docType)
181     {
182         int rendering = 0;
183         if (docType != null) {
184             if (docType.equals(Html.HTML_401))
185                 rendering = TagRenderingBase.HTML_RENDERING;
186             else if (docType.equals(Html.HTML_401_QUIRKS))
187                 rendering = TagRenderingBase.HTML_RENDERING_QUIRKS;
188             else if (docType.equals(Html.XHTML_10))
189                 rendering = TagRenderingBase.XHTML_RENDERING;
190             else
191                 rendering = TagRenderingBase.getDefaultDocType();
192         }
193         else {
194             rendering = TagRenderingBase.getDefaultDocType();
195         }
196         pageContext.getRequest().setAttribute(Html.DOC_TYPE_OVERRIDE, new Integer JavaDoc(rendering));
197     }
198
199     /**
200      * the tag extension lifecycle method called when the tag is first
201      * encountered. This will cause the body of
202      * the tag to be evaluated.
203      * @return int indicating that the body should be evaluated.
204      * @throws JspException on errors.
205      */

206     public int doStartTag()
207             throws JspException JavaDoc {
208
209         Tag parent = getParent();
210         if (parent != null) {
211             String JavaDoc s = Bundle.getString("TempExcp_ContainedTemplate");
212             registerTagError(s,null);
213             reportErrors();
214             _fatalError = true;
215             return SKIP_BODY;
216         }
217
218         ServletRequest JavaDoc req = pageContext.getRequest();
219         _savedContext = (TemplateContext) req.getAttribute(TEMPLATE_SECTIONS);
220         TemplateContext ctxt = new TemplateContext();
221         req.setAttribute(TEMPLATE_SECTIONS,ctxt);
222
223         return EVAL_BODY_INCLUDE;
224     }
225
226     /**
227      * The tag extension lifecycle method called after the tag has
228      * processed the body. This method will include the template
229      * JSP page specified by the <code>templatePage</code> attribute. The
230      * contents of the template are made available to the template page.
231      * @return SKIP_PAGE to skip all processing after the template.
232      * @throws JspException on all errors. The most common error is
233      * an error indicating that the JSP page representing the Template
234      * isn't found.
235      */

236     public int doEndTag()
237             throws JspException JavaDoc {
238
239         // if there was an error, exit
240
if (_fatalError) {
241             localRelease();
242             return EVAL_PAGE;
243         }
244
245         // get the request and response
246
ServletRequest JavaDoc req = pageContext.getRequest();
247         ServletResponse JavaDoc resp = pageContext.getResponse();
248
249         if (_innerErrors != null) {
250             req.setAttribute(CONTAINER_ERRORS,_innerErrors);
251         }
252
253         String JavaDoc realURI = getRealURI((HttpServletRequest JavaDoc) req,_templatePage);
254         if (!templateExists(realURI)) {
255             String JavaDoc s = Bundle.getString("TempExcp_MissingTemplate",
256                     new Object JavaDoc[]{_templatePage});
257             registerTagError(s,null);
258             reportErrors();
259             localRelease();
260             return SKIP_BODY;
261         }
262
263         RequestDispatcher JavaDoc rd = req.getRequestDispatcher(realURI);
264         if (rd == null) {
265             String JavaDoc s = Bundle.getString("Temp_RequestDispatcherReturnNull",new Object JavaDoc[]{"realURI"});
266             registerTagError(s,null);
267             reportErrors();
268             localRelease();
269             return SKIP_PAGE;
270         }
271         try {
272             // dispatch to the template itself...
273
JspWriter JavaDoc out = pageContext.getOut();
274             out.flush();
275             // We have to make sure that the Page Flow framework doesn't use the Servlet Include path as the request
276
// URI while we're rendering a template page. This is so that rendered URLs are relative to the current
277
// page, not the included template page.
278
InternalUtils.setIgnoreIncludeServletPath( req, true );
279             try {
280                 rd.include(req,resp);
281             }
282             finally {
283                 InternalUtils.setIgnoreIncludeServletPath( req, false );
284             }
285         }
286         catch (IOException JavaDoc e) {
287             String JavaDoc s = Bundle.getString("TempExcp_ExceptIncludeTemplate",
288                     new Object JavaDoc[]{"IOException",
289                                  _templatePage});
290             registerTagError(s,null);
291             reportErrors();
292             localRelease();
293             return SKIP_PAGE;
294         }
295         catch (ServletException JavaDoc se) {
296
297             System.err.println("Servlet Excepiton");
298
299             // Report the servlet exception
300
String JavaDoc s = Bundle.getString("TempLog_ServletException",
301                     new Object JavaDoc[]{se.getMessage()});
302             registerTagError(s,null);
303
304             // walk the servlet hierarchy
305
Throwable JavaDoc t = se.getRootCause();
306             if (t == null) {
307                 s = Bundle.getString("TempLog_ServletError",
308                         new Object JavaDoc[]
309                         {_templatePage,
310                          se.getMessage()
311                         });
312                 registerTagError(s,null);
313                 reportErrors();
314                 localRelease();
315                 return SKIP_PAGE;
316             }
317
318             // Walk all of the errors
319
while (t != null && (t instanceof ServletException JavaDoc ||
320                     t instanceof JspException JavaDoc)) {
321
322                 s = Bundle.getString("TempLog_Cause",
323                         new Object JavaDoc[]
324                         {t.getClass().getName(),
325                          t.getMessage()
326                         });
327                 logger.error(s);
328
329                 if (t.getMessage() == null) {
330                     logger.error("Unwinding Servlet Exception",t);
331                     t.printStackTrace();
332                 }
333                 if (t instanceof ServletException JavaDoc)
334                     t = ((ServletException JavaDoc) t).getRootCause();
335                 else
336                     t = ((JspException JavaDoc) t).getRootCause();
337             }
338             if (t == null) {
339                 s = Bundle.getString("TempLog_ServletError",
340                         new Object JavaDoc[]
341                         {_templatePage,
342                          se.getMessage()
343                         });
344                 registerTagError(s,null);
345                 reportErrors();
346                 logger.error(s);
347                 localRelease();
348                 return SKIP_PAGE;
349             }
350             if (t instanceof AssertionError JavaDoc) {
351                 s = Bundle.getString("TempLog_AssertCause",
352                         new Object JavaDoc[]
353                         {t.getStackTrace().toString(),
354                         });
355                 registerTagError(s,null);
356             }
357             else {
358                 s = Bundle.getString("TempLog_Cause",
359                         new Object JavaDoc[]
360                         {t.getClass().getName(),
361                          t.getMessage()
362                         });
363                 registerTagError(s,null);
364             }
365             s = Bundle.getString("TempExcp_ExceptIncludeTemplate",
366                     new Object JavaDoc[]{"ServletException",
367                                  _templatePage});
368             registerTagError(s,null);
369             reportErrors();
370             localRelease();
371             return SKIP_PAGE;
372         }
373
374         // skip the page because on this pass we forwarded to the template
375
// for rendering...
376
req.setAttribute(TEMPLATE_SECTIONS,_savedContext);
377         localRelease();
378         return SKIP_PAGE;
379     }
380
381     private boolean templateExists(String JavaDoc realURI)
382         throws JspException JavaDoc
383     {
384         try {
385             URL JavaDoc uri = pageContext.getServletContext().getResource(realURI);
386             return (uri != null);
387         }
388         catch (MalformedURLException JavaDoc e) {
389             String JavaDoc s = Bundle.getString("TempExcp_ExceptIncludeDefault",
390                      new Object JavaDoc[]{"MalformedURLException",
391                                   realURI});
392              logger.error(s,e);
393              throw new JspException JavaDoc(s,e);
394         }
395     }
396
397     static String JavaDoc getRealURI(HttpServletRequest JavaDoc req,String JavaDoc uri) {
398         if (uri.charAt(0) == '/') {
399             return uri;
400         }
401         String JavaDoc path = req.getServletPath();
402         int pos = path.lastIndexOf('/');
403         if (pos != -1) {
404             path = path.substring(0,pos+1);
405         }
406         return path+uri;
407     }
408
409     /**
410      * Reset all of the fields of the tag.
411      */

412     protected void localRelease() {
413         super.localRelease();
414         _fatalError = false;
415         _templatePage = null;
416         _innerErrors = null;
417         _reportErrors = false;
418         _savedContext = null;
419     }
420
421     /**
422      * Add an error to the errors being reported by this tag.
423      * @param ape - The AbstractPageError to add
424      */

425     public void addError(AbstractPageError ape) {
426         if (_innerErrors == null) {
427             _innerErrors = new InnerErrorReporter();
428         }
429         _innerErrors.addError(ape);
430     }
431
432     /**
433      * Return an ArrayList of the errors
434      * @return an <code>ArrayList</code> of all errors.
435      */

436     public ArrayList JavaDoc returnErrors() {
437         if (_innerErrors == null) {
438             _innerErrors = new InnerErrorReporter();
439         }
440         return _innerErrors.returnErrors();
441     }
442
443     /**
444      * This boolean indicates if an ErrorReporter is reporting errors
445      * or not. The caller should check this before calling addError
446      * because the ErrorReporter may be off for some reason.
447      * @return a boolean indicating if the tag is reporting errors or not.
448      */

449     public boolean isReporting() {
450         return _reportErrors;
451     }
452
453     static class InnerErrorReporter implements org.apache.beehive.netui.tags.IErrorReporter
454     {
455         /**
456          * The errors reported by contained tags
457          */

458         private ArrayList JavaDoc _errors;
459
460         /**
461          * Add an error to the errors being reported by this tag.
462          * @param ape - The AbstractPageError to add
463          */

464         public void addError(AbstractPageError ape) {
465             assert (ape != null);
466             if (_errors == null) {
467                 _errors = new ArrayList JavaDoc();
468             }
469
470             // add the error and update it
471
_errors.add(ape);
472             ape.errorNo = _errors.size();
473         }
474
475         /**
476          * This boolean indicates if an ErrorReporter is reporting errors
477          * or not. The caller should check this before calling addError
478          * because the ErrorReporter may be off for some reason.
479          * @return a boolean indicating if the tag is reporting errors or not.
480          */

481         public boolean isReporting() {
482             return true;
483         }
484
485         /**
486          * Return an ArrayList of the errors
487          * @return an <code>ArrayList</code> of all errors.
488          */

489         public ArrayList JavaDoc returnErrors() {
490             ArrayList JavaDoc ret = _errors;
491             _errors = null;
492             return ret;
493         }
494     }
495 }
496
Popular Tags