KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > jsp > CmsJspTagInclude


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/jsp/CmsJspTagInclude.java,v $
3  * Date : $Date: 2006/10/26 12:25:35 $
4  * Version: $Revision: 1.37 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.jsp;
33
34 import org.opencms.file.CmsFile;
35 import org.opencms.file.CmsObject;
36 import org.opencms.file.CmsPropertyDefinition;
37 import org.opencms.flex.CmsFlexController;
38 import org.opencms.flex.CmsFlexResponse;
39 import org.opencms.loader.CmsLoaderException;
40 import org.opencms.loader.I_CmsResourceLoader;
41 import org.opencms.loader.I_CmsResourceStringDumpLoader;
42 import org.opencms.main.CmsException;
43 import org.opencms.main.OpenCms;
44 import org.opencms.staticexport.CmsLinkManager;
45 import org.opencms.util.CmsStringUtil;
46 import org.opencms.workplace.editors.directedit.CmsDirectEditParams;
47
48 import java.io.IOException JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Locale JavaDoc;
51 import java.util.Map JavaDoc;
52
53 import javax.servlet.ServletException JavaDoc;
54 import javax.servlet.ServletRequest JavaDoc;
55 import javax.servlet.ServletResponse JavaDoc;
56 import javax.servlet.http.HttpServletRequest JavaDoc;
57 import javax.servlet.http.HttpServletResponse JavaDoc;
58 import javax.servlet.jsp.JspException JavaDoc;
59 import javax.servlet.jsp.PageContext JavaDoc;
60 import javax.servlet.jsp.tagext.BodyTagSupport JavaDoc;
61
62 /**
63  * Implementation of the <code>&lt;cms:include/&gt;</code> tag,
64  * used to include another OpenCms managed resource in a JSP.<p>
65  *
66  * @author Alexander Kandzior
67  *
68  * @version $Revision: 1.37 $
69  *
70  * @since 6.0.0
71  */

72 public class CmsJspTagInclude extends BodyTagSupport JavaDoc implements I_CmsJspTagParamParent {
73
74     /** Serial version UID required for safe serialization. */
75     private static final long serialVersionUID = 705978510743164951L;
76
77     /** The value of the "attribute" attribute. */
78     private String JavaDoc m_attribute;
79
80     /** The value of the "cacheable" attribute. */
81     private boolean m_cacheable;
82
83     /** The value of the "editable" attribute. */
84     private boolean m_editable;
85
86     /** The value of the "element" attribute. */
87     private String JavaDoc m_element;
88
89     /** Hashmap to save parameters to the include in. */
90     private Map JavaDoc m_parameterMap;
91
92     /** The value of the "property" attribute. */
93     private String JavaDoc m_property;
94
95     /** The value of the "suffix" attribute. */
96     private String JavaDoc m_suffix;
97
98     /** The value of the "page" attribute. */
99     private String JavaDoc m_target;
100
101     /**
102      * Empty constructor, required for attribute value initialization.<p>
103      */

104     public CmsJspTagInclude() {
105
106         super();
107         m_cacheable = true;
108     }
109
110     /**
111      * Adds parameters to a parameter Map that can be used for a http request.<p>
112      *
113      * @param parameters the Map to add the parameters to
114      * @param name the name to add
115      * @param value the value to add
116      * @param overwrite if <code>true</code>, a parameter in the map will be overwritten by
117      * a parameter with the same name, otherwise the request will have multiple parameters
118      * with the same name (which is possible in http requests)
119      */

120     public static void addParameter(Map JavaDoc parameters, String JavaDoc name, String JavaDoc value, boolean overwrite) {
121
122         // No null values allowed in parameters
123
if ((parameters == null) || (name == null) || (value == null)) {
124             return;
125         }
126
127         // Check if the parameter name (key) exists
128
if (parameters.containsKey(name) && (!overwrite)) {
129             // Yes: Check name values if value exists, if so do nothing, else add new value
130
String JavaDoc[] values = (String JavaDoc[])parameters.get(name);
131             String JavaDoc[] newValues = new String JavaDoc[values.length + 1];
132             System.arraycopy(values, 0, newValues, 0, values.length);
133             newValues[values.length] = value;
134             parameters.put(name, newValues);
135         } else {
136             // No: Add new parameter name / value pair
137
String JavaDoc[] values = new String JavaDoc[] {value};
138             parameters.put(name, values);
139         }
140     }
141
142     /**
143      * Includes the selected target.<p>
144      *
145      * @param context the current JSP page context
146      * @param target the target for the include, might be <code>null</code>
147      * @param element the element to select form the target might be <code>null</code>
148      * @param editable flag to indicate if the target is editable
149      * @param paramMap a map of parameters for the include, will be merged with the request
150      * parameters, might be <code>null</code>
151      * @param req the current request
152      * @param res the current response
153      *
154      * @throws JspException in case something goes wrong
155      */

156     public static void includeTagAction(
157         PageContext JavaDoc context,
158         String JavaDoc target,
159         String JavaDoc element,
160         boolean editable,
161         Map JavaDoc paramMap,
162         ServletRequest JavaDoc req,
163         ServletResponse JavaDoc res) throws JspException JavaDoc {
164
165         // no locale and no cachable parameter are used by default
166
includeTagAction(context, target, element, null, editable, true, paramMap, req, res);
167     }
168
169     /**
170      * Includes the selected target.<p>
171      *
172      * @param context the current JSP page context
173      * @param target the target for the include, might be <code>null</code>
174      * @param element the element to select form the target, might be <code>null</code>
175      * @param locale the locale to use for the selected element, might be <code>null</code>
176      * @param editable flag to indicate if the target is editable
177      * @param cacheable flag to indicate if the target should be cacheable in the Flex cache
178      * @param paramMap a map of parameters for the include, will be merged with the request
179      * parameters, might be <code>null</code>
180      * @param req the current request
181      * @param res the current response
182      *
183      * @throws JspException in case something goes wrong
184      */

185     public static void includeTagAction(
186         PageContext JavaDoc context,
187         String JavaDoc target,
188         String JavaDoc element,
189         Locale JavaDoc locale,
190         boolean editable,
191         boolean cacheable,
192         Map JavaDoc paramMap,
193         ServletRequest JavaDoc req,
194         ServletResponse JavaDoc res) throws JspException JavaDoc {
195
196         // the Flex controller provides access to the interal OpenCms structures
197
CmsFlexController controller = CmsFlexController.getController(req);
198
199         if (target == null) {
200             // set target to default
201
target = controller.getCmsObject().getRequestContext().getUri();
202         }
203
204         // resolve possible relative URI
205
target = CmsLinkManager.getAbsoluteUri(target, controller.getCurrentRequest().getElementUri());
206
207         try {
208             // now resolve additional include extensions that might be required for special loader implementations
209
target = OpenCms.getResourceManager().resolveIncludeExtensions(
210                 target,
211                 element,
212                 editable,
213                 paramMap,
214                 req,
215                 res);
216         } catch (CmsException e) {
217             // store exception in controller and discontinue
218
controller.setThrowable(e, target);
219             throw new JspException JavaDoc(e);
220         }
221
222         // include direct edit "start" element (if enabled)
223
boolean directEditOpen = editable
224             && CmsJspTagEditable.startDirectEdit(context, new CmsDirectEditParams(target, element));
225
226         // save old parameters from request
227
Map JavaDoc oldParameterMap = req.getParameterMap();
228         try {
229             // each include will have it's unique map of parameters
230
Map JavaDoc parameterMap = (paramMap == null) ? new HashMap JavaDoc() : new HashMap JavaDoc(paramMap);
231             if (cacheable && (element != null)) {
232                 // add template element selector for JSP templates (only required if cacheable)
233
addParameter(parameterMap, I_CmsResourceLoader.PARAMETER_ELEMENT, element, true);
234             }
235             // add parameters to set the correct element
236
controller.getCurrentRequest().addParameterMap(parameterMap);
237             if (cacheable) {
238                 // use include with cache
239
includeActionWithCache(controller, context, target, parameterMap, req, res);
240             } else {
241                 // no cache required
242
includeActionNoCache(controller, context, target, element, locale, req, res);
243             }
244         } finally {
245             // restore old parameter map (if required)
246
if (oldParameterMap != null) {
247                 controller.getCurrentRequest().setParameterMap(oldParameterMap);
248             }
249         }
250
251         // include direct edit "end" element (if required)
252
if (directEditOpen) {
253             CmsJspTagEditable.endDirectEdit(context);
254         }
255     }
256
257     /**
258      * Includes the selected target without caching.<p>
259      *
260      * @param controller the current JSP controller
261      * @param context the current JSP page context
262      * @param target the target for the include
263      * @param element the element to select form the target
264      * @param locale the locale to select from the target
265      * @param req the current request
266      * @param res the current response
267      *
268      * @throws JspException in case something goes wrong
269      */

270     private static void includeActionNoCache(
271         CmsFlexController controller,
272         PageContext JavaDoc context,
273         String JavaDoc target,
274         String JavaDoc element,
275         Locale JavaDoc locale,
276         ServletRequest JavaDoc req,
277         ServletResponse JavaDoc res) throws JspException JavaDoc {
278
279         try {
280             // include is not cachable
281
CmsFile file = controller.getCmsObject().readFile(target);
282             CmsObject cms = controller.getCmsObject();
283             if (locale == null) {
284                 locale = cms.getRequestContext().getLocale();
285             }
286             // get the loader for the requested file
287
I_CmsResourceLoader loader = OpenCms.getResourceManager().getLoader(file);
288             String JavaDoc content;
289             if (loader instanceof I_CmsResourceStringDumpLoader) {
290                 // loder can provide content as a String
291
I_CmsResourceStringDumpLoader strLoader = (I_CmsResourceStringDumpLoader)loader;
292                 content = strLoader.dumpAsString(cms, file, element, locale, req, res);
293             } else {
294                 if (!(req instanceof HttpServletRequest JavaDoc) || !(res instanceof HttpServletResponse JavaDoc)) {
295                     // http type is required for loader (no refactoring to avoid changes to interface)
296
CmsLoaderException e = new CmsLoaderException(Messages.get().container(
297                         Messages.ERR_BAD_REQUEST_RESPONSE_0));
298                     throw new JspException JavaDoc(e);
299                 }
300                 // get the bytes from the loader and convert them to a String
301
byte[] result = loader.dump(
302                     cms,
303                     file,
304                     element,
305                     locale,
306                     (HttpServletRequest JavaDoc)req,
307                     (HttpServletResponse JavaDoc)res);
308                 // use the encoding from the property or the system default if not available
309
String JavaDoc encoding = cms.readPropertyObject(file, CmsPropertyDefinition.PROPERTY_CONTENT_ENCODING, true).getValue(
310                     OpenCms.getSystemInfo().getDefaultEncoding());
311                 content = new String JavaDoc(result, encoding);
312             }
313             // write the content String to the JSP output writer
314
context.getOut().print(content);
315
316         } catch (ServletException JavaDoc e) {
317             // store original Exception in controller in order to display it later
318
Throwable JavaDoc t = (e.getRootCause() != null) ? e.getRootCause() : e;
319             t = controller.setThrowable(t, target);
320             throw new JspException JavaDoc(t);
321         } catch (IOException JavaDoc e) {
322             // store original Exception in controller in order to display it later
323
Throwable JavaDoc t = controller.setThrowable(e, target);
324             throw new JspException JavaDoc(t);
325         } catch (CmsException e) {
326             // store original Exception in controller in order to display it later
327
Throwable JavaDoc t = controller.setThrowable(e, target);
328             throw new JspException JavaDoc(t);
329         }
330     }
331
332     /**
333      * Includes the selected target using the Flex cache.<p>
334      *
335      * @param controller the current JSP controller
336      * @param context the current JSP page context
337      * @param target the target for the include, might be <code>null</code>
338      * @param parameterMap a map of parameters for the include
339      * @param req the current request
340      * @param res the current response
341      *
342      * @throws JspException in case something goes wrong
343      */

344     private static void includeActionWithCache(
345         CmsFlexController controller,
346         PageContext JavaDoc context,
347         String JavaDoc target,
348         Map JavaDoc parameterMap,
349         ServletRequest JavaDoc req,
350         ServletResponse JavaDoc res) throws JspException JavaDoc {
351
352         try {
353             // write out a FLEX_CACHE_DELIMITER char on the page, this is used as a parsing delimeter later
354
context.getOut().print(CmsFlexResponse.FLEX_CACHE_DELIMITER);
355             // add the target to the include list (the list will be initialized if it is currently empty)
356
controller.getCurrentResponse().addToIncludeList(target, parameterMap);
357             // now use the Flex dispatcher to include the target (this will also work for targets in the OpenCms VFS)
358
controller.getCurrentRequest().getRequestDispatcher(target).include(req, res);
359         } catch (ServletException JavaDoc e) {
360             // store original Exception in controller in order to display it later
361
Throwable JavaDoc t = (e.getRootCause() != null) ? e.getRootCause() : e;
362             t = controller.setThrowable(t, target);
363             throw new JspException JavaDoc(t);
364         } catch (IOException JavaDoc e) {
365             // store original Exception in controller in order to display it later
366
Throwable JavaDoc t = controller.setThrowable(e, target);
367             throw new JspException JavaDoc(t);
368         }
369     }
370
371     /**
372      * This methods adds parameters to the current request.<p>
373      *
374      * Parameters added here will be treated like parameters from the
375      * HttpRequest on included pages.<p>
376      *
377      * Remember that the value for a parameter in a HttpRequest is a
378      * String array, not just a simple String. If a parameter added here does
379      * not already exist in the HttpRequest, it will be added. If a parameter
380      * exists, another value will be added to the array of values. If the
381      * value already exists for the parameter, nothing will be added, since a
382      * value can appear only once per parameter.<p>
383      *
384      * @param name the name to add
385      * @param value the value to add
386      * @see org.opencms.jsp.I_CmsJspTagParamParent#addParameter(String, String)
387      */

388     public void addParameter(String JavaDoc name, String JavaDoc value) {
389
390         // No null values allowed in parameters
391
if ((name == null) || (value == null)) {
392             return;
393         }
394
395         // Check if internal map exists, create new one if not
396
if (m_parameterMap == null) {
397             m_parameterMap = new HashMap JavaDoc();
398         }
399
400         addParameter(m_parameterMap, name, value, false);
401     }
402
403     /**
404      * @return <code>EVAL_PAGE</code>
405      *
406      * @see javax.servlet.jsp.tagext.Tag#doEndTag()
407      *
408      * @throws JspException by interface default
409      */

410     public int doEndTag() throws JspException JavaDoc {
411
412         ServletRequest JavaDoc req = pageContext.getRequest();
413         ServletResponse JavaDoc res = pageContext.getResponse();
414
415         if (CmsFlexController.isCmsRequest(req)) {
416             // this will always be true if the page is called through OpenCms
417
CmsObject cms = CmsFlexController.getCmsObject(req);
418             String JavaDoc target = null;
419
420             // try to find out what to do
421
if (m_target != null) {
422                 // option 1: target is set with "page" or "file" parameter
423
target = m_target + getSuffix();
424             } else if (m_property != null) {
425                 // option 2: target is set with "property" parameter
426
try {
427                     String JavaDoc prop = cms.readPropertyObject(cms.getRequestContext().getUri(), m_property, true).getValue();
428                     if (prop != null) {
429                         target = prop + getSuffix();
430                     }
431                 } catch (Exception JavaDoc e) {
432                     // target will be null
433
}
434             } else if (m_attribute != null) {
435                 // option 3: target is set in "attribute" parameter
436
try {
437                     String JavaDoc attr = (String JavaDoc)req.getAttribute(m_attribute);
438                     if (attr != null) {
439                         target = attr + getSuffix();
440                     }
441                 } catch (Exception JavaDoc e) {
442                     // target will be null
443
}
444             } else {
445                 // option 4: target might be set in body
446
String JavaDoc body = null;
447                 if (getBodyContent() != null) {
448                     body = getBodyContent().getString();
449                     if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(body)) {
450                         // target IS set in body
451
target = body + getSuffix();
452                     }
453                     // else target is not set at all, default will be used
454
}
455             }
456
457             // now perform the include action
458
includeTagAction(pageContext, target, m_element, null, m_editable, m_cacheable, m_parameterMap, req, res);
459
460             // must call release here manually to make sure m_parameterMap is cleared
461
release();
462         }
463
464         return EVAL_PAGE;
465     }
466
467     /**
468      * Returns <code>{@link #EVAL_BODY_BUFFERED}</code>.<p>
469      *
470      * @return <code>{@link #EVAL_BODY_BUFFERED}</code>
471      *
472      * @see javax.servlet.jsp.tagext.Tag#doStartTag()
473      */

474     public int doStartTag() {
475
476         return EVAL_BODY_BUFFERED;
477     }
478
479     /**
480      * Returns the attribute.<p>
481      *
482      * @return the attribute
483      */

484     public String JavaDoc getAttribute() {
485
486         return m_attribute != null ? m_attribute : "";
487     }
488
489     /**
490      * Returns the cacheable flag.<p>
491      *
492      * @return the cacheable flag
493      */

494     public String JavaDoc getCacheable() {
495
496         return String.valueOf(m_cacheable);
497     }
498
499     /**
500      * Returns the editable flag.<p>
501      *
502      * @return the editable flag
503      */

504     public String JavaDoc getEditable() {
505
506         return String.valueOf(m_editable);
507     }
508
509     /**
510      * Returns the element.<p>
511      *
512      * @return the element
513      */

514     public String JavaDoc getElement() {
515
516         return m_element;
517     }
518
519     /**
520      * Returns the value of <code>{@link #getPage()}</code>.<p>
521      *
522      * @return the value of <code>{@link #getPage()}</code>
523      * @see #getPage()
524      */

525     public String JavaDoc getFile() {
526
527         return getPage();
528     }
529
530     /**
531      * Returns the include page target.<p>
532      *
533      * @return the include page target
534      */

535     public String JavaDoc getPage() {
536
537         return m_target != null ? m_target : "";
538     }
539
540     /**
541      * Returns the property.<p>
542      *
543      * @return the property
544      */

545     public String JavaDoc getProperty() {
546
547         return m_property != null ? m_property : "";
548     }
549
550     /**
551      * Returns the suffix.<p>
552      *
553      * @return the suffix
554      */

555     public String JavaDoc getSuffix() {
556
557         return m_suffix != null ? m_suffix : "";
558     }
559
560     /**
561      * @see javax.servlet.jsp.tagext.Tag#release()
562      */

563     public void release() {
564
565         super.release();
566         m_target = null;
567         m_suffix = null;
568         m_property = null;
569         m_element = null;
570         m_parameterMap = null;
571         m_editable = false;
572         m_cacheable = true;
573     }
574
575     /**
576      * Sets the attribute.<p>
577      *
578      * @param attribute the attribute to set
579      */

580     public void setAttribute(String JavaDoc attribute) {
581
582         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(attribute)) {
583             m_attribute = attribute;
584         }
585     }
586
587     /**
588      * Sets the cacheable flag.<p>
589      *
590      * Cachable is <code>true</code> by default.<p>
591      *
592      * @param cacheable the flag to set
593      */

594     public void setCacheable(String JavaDoc cacheable) {
595
596         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(cacheable)) {
597             m_cacheable = Boolean.valueOf(cacheable).booleanValue();
598         }
599     }
600
601     /**
602      * Sets the editable flag.<p>
603      *
604      * Editable is <code>false</code> by default.<p>
605      *
606      * @param editable the flag to set
607      */

608     public void setEditable(String JavaDoc editable) {
609
610         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(editable)) {
611             m_editable = Boolean.valueOf(editable).booleanValue();
612         }
613     }
614
615     /**
616      * Sets the element.<p>
617      *
618      * @param element the element to set
619      */

620     public void setElement(String JavaDoc element) {
621
622         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(element)) {
623             m_element = element;
624         }
625     }
626
627     /**
628      * Sets the file, same as using <code>setPage()</code>.<p>
629      *
630      * @param file the file to set
631      * @see #setPage(String)
632      */

633     public void setFile(String JavaDoc file) {
634
635         setPage(file);
636     }
637
638     /**
639      * Sets the include page target.<p>
640      *
641      * @param target the target to set
642      */

643     public void setPage(String JavaDoc target) {
644
645         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(target)) {
646             m_target = target;
647         }
648     }
649
650     /**
651      * Sets the property.<p>
652      *
653      * @param property the property to set
654      */

655     public void setProperty(String JavaDoc property) {
656
657         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(property)) {
658             m_property = property;
659         }
660     }
661
662     /**
663      * Sets the suffix.<p>
664      *
665      * @param suffix the suffix to set
666      */

667     public void setSuffix(String JavaDoc suffix) {
668
669         if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(suffix)) {
670             m_suffix = suffix.toLowerCase();
671         }
672     }
673 }
Popular Tags