KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > generic > AbstractRenderer


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution, if
19  * any, must include the following acknowlegement:
20  * "This product includes software developed by the
21  * Caucho Technology (http://www.caucho.com/)."
22  * Alternately, this acknowlegement may appear in the software itself,
23  * if and wherever such third-party acknowlegements normally appear.
24  *
25  * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * info@caucho.com.
29  *
30  * 5. Products derived from this software may not be called "Resin"
31  * nor may "Resin" appear in their names without prior written
32  * permission of Caucho Technology.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
35  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
36  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37  * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
38  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
40  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
42  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
43  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
44  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * @author Sam
47  */

48
49
50 package com.caucho.portal.generic;
51
52 import javax.portlet.*;
53 import java.io.IOException JavaDoc;
54 import java.io.OutputStream JavaDoc;
55 import java.io.PrintWriter JavaDoc;
56 import java.util.Enumeration JavaDoc;
57 import java.util.LinkedHashSet JavaDoc;
58 import java.util.Locale JavaDoc;
59 import java.util.Map JavaDoc;
60 import java.util.ResourceBundle JavaDoc;
61 import java.util.Set JavaDoc;
62 import java.util.logging.Logger JavaDoc;
63
64 /**
65  * <h3>Template</h3>
66  *
67  * To implement a renderer that adds decoration to content
68  * rendered with the PrintWriter, the following are overridden:
69  *
70  * <pre>
71  * protected void beginPage( PrintWriter out, RenderRequest request, String namespace )
72  * throws IOException
73  * {
74  * ...
75  * }
76  *
77  * protected void beginWindow( PrintWriter out, RenderRequest request, String namespace )
78  * throws IOException
79  * {
80  * ...
81  * }
82  *
83  * protected void endWindow( PrintWriter out, RenderRequest request, String namespace )
84  * throws IOException
85  * {
86  * ...
87  * }
88  *
89  * protected void endPage( PrintWriter out, RenderRequest request, String namespace )
90  * throws IOException
91  * {
92  * ...
93  * }
94  *
95  * <h3>Helper methods</h3>
96  * <ul>
97  * <li><code>{@link #printEscaped(java.io.PrintWriter,java.lang.CharSequence) printEscaped(out, string)};</code>
98  * <li><code>String contentType = {@link #getContentType(javax.portlet.RenderRequest) getContentType(request)}; </code>
99  * <li><code>Locale locale = {@link #getLocale(javax.portlet.RenderRequest) getLocale(request)}; </code>
100  * <li><code>String title = {@link #getTitle(javax.portlet.RenderRequest) getTitle(request)}; </code>
101  * <li><code>String shortTitle = {@link #getShortTitle(javax.portlet.RenderRequest) getShortTitle(request)}; </code>
102  * <li><code>PortletURL url = {@link #getControlURL(javax.portlet.RenderRequest) getControlURL(request)}; </code>
103  * <li><code>Set<PortletMode> portletModes = {@link #getPortletModes(javax.portlet.RenderRequest) getPortletModes(request)}; </code>
104  * <li><code>Set<WindowState> windowStates = {@link #getWindowStates(javax.portlet.RenderRequest) getWindowStates(request)}; </code>
105  * <li><code>ResourceBundle resourceBundle = {@link #getResourceBundle(javax.portlet.RenderRequest) getResourceBundle(request)}; </code>
106  * <li><code>PortletConfig portletConfig = {@link #getPortletConfig(javax.portlet.RenderRequest) getPortletConfig(request)}; </code>
107  * <li><code>RenderResponse renderResponse = {@link #getRenderResponse(javax.portlet.RenderRequest) getRenderResponse(request)}; </code>
108  */

109
110 abstract public class AbstractRenderer implements Renderer
111 {
112   public static final String JavaDoc PAGE_HEADER_RENDERED
113     = "com.caucho.portal.generic.AbstractRenderer.PAGE_HEADER_RENDERED";
114
115   protected static final Logger JavaDoc log =
116     Logger.getLogger(AbstractRenderer.class.getName());
117
118   private boolean _isAlwaysWrite = true;
119   private boolean _isAlwaysStream;
120   private String JavaDoc _defaultContentType = "text/html";
121   private int _bufferSize = -1;
122
123   private Boolean JavaDoc _isDecorateWindow;
124
125   /**
126    * If true beginWindow() and endWindow() are always called, if false never
127    * called, the default is to call beginWindow() and endWindow() unless
128    * beginPage() and endPage() are called.
129    */

130   public void setDecorateWindow(boolean isDecorateWindow)
131   {
132     _isDecorateWindow = isDecorateWindow ? Boolean.TRUE : Boolean.FALSE;
133   }
134
135   /**
136    * If true the portal will always call getWriter(), even if the portlet does
137    * not call getWriter(), unless getOutputStream() has been called.
138    *
139    * The default is true.
140    */

141   public void setAlwaysWrite(boolean isAlwaysWrite)
142   {
143     _isAlwaysWrite = isAlwaysWrite;
144   }
145
146
147   /**
148    * If true the portal will always call getOutputStream(), even if the portlet
149    * does not call getOutputStream(), unless getWriter() has been called.
150    *
151    * The default is false.
152    */

153   public void setAlwaysStream(boolean isAlwaysStream)
154   {
155     _isAlwaysStream = isAlwaysStream;
156   }
157
158   /**
159    * The default content type used if {@link #isAlwaysWrite()}
160    * or {@link #isAlwaysStream()} is true and a
161    * Writer or OutputStream is obtained before the content type of the
162    * response has been set, default is "text/html".
163    */

164   public void setDefaultContentType(String JavaDoc defaultContentType)
165   {
166     _defaultContentType = defaultContentType;
167   }
168
169   /**
170    * The default is -1, which allows the portal to choose a buffer size.
171    * 0 disables buffering of the renderer output.
172    */

173   public void setBufferSize(int bufferSize)
174   {
175     _bufferSize = bufferSize;
176   }
177
178   /**
179    * Return true if the WindowState is allowed.
180    *
181    * <code>portletRequest.getResponseContentType()</code> can be used
182    * if the allowed window states is dependent on the mime type of the
183    * response.
184    *
185    * The default is to return true.
186    */

187   public boolean isWindowStateAllowed( PortletRequest request,
188                                        WindowState windowState )
189   {
190     return true;
191   }
192
193   /**
194    * Return true if the WindowState is allowed.
195    *
196    * <code>portletRequest.getResponseContentType()</code> can be used
197    * if the allowed portlet modes is dependent on the mime type of the
198    * response.
199    *
200    * The default is to return true.
201    */

202   public boolean isPortletModeAllowed( PortletRequest request,
203                                        PortletMode portletMode )
204   {
205     return true;
206   }
207
208   public boolean isAlwaysWrite()
209   {
210     return _isAlwaysWrite;
211   }
212
213   public boolean isAlwaysStream()
214   {
215     return _isAlwaysStream;
216   }
217
218   public String JavaDoc getDefaultContentType()
219   {
220     return _defaultContentType;
221   }
222
223   public int getBufferSize()
224   {
225     return _bufferSize;
226   }
227
228   /**
229    * Return a Writer that wraps the passed PrintWriter, or null
230    * if there is no specialized writer for this request.
231    *
232    * This implementation calls beginPage() if needed and beginWindow()
233    * before returning the writer.
234    */

235   public PrintWriter JavaDoc getWriter( PrintWriter JavaDoc out,
236                                 RenderRequest request,
237                                 String JavaDoc namespace )
238     throws IOException JavaDoc
239   {
240     boolean doPage = (request.getAttribute(PAGE_HEADER_RENDERED) == null);
241
242     boolean doWindow = _isDecorateWindow == null
243                         ? !doPage
244                         : _isDecorateWindow.booleanValue();
245
246     if (doPage) {
247       beginPage(out, request, namespace);
248       request.setAttribute(PAGE_HEADER_RENDERED, this);
249     }
250
251     if (doWindow)
252       beginWindow(out, request, namespace);
253
254     return out;
255   }
256
257   /**
258    * Derived classes override to insert header content for a page,
259    * called only when beginPage() has not been called on some instance of
260    * AbstractRenderer for this request.
261    */

262   protected void beginPage( PrintWriter JavaDoc out,
263                             RenderRequest request,
264                             String JavaDoc namespace )
265     throws IOException JavaDoc
266   {
267   }
268
269   /**
270    * Derived classes override to insert header content before a portlet
271    * has been rendered.
272    */

273   protected void beginWindow( PrintWriter JavaDoc out,
274                               RenderRequest request,
275                               String JavaDoc namespace )
276     throws IOException JavaDoc
277   {
278   }
279
280   /**
281    * Derived classes override to append footer content after a portlet
282    * has been rendered.
283    */

284   protected void endWindow( PrintWriter JavaDoc out,
285                             RenderRequest request,
286                             String JavaDoc namespace )
287     throws IOException JavaDoc
288   {
289   }
290
291   /**
292    * Derived classes override to insert footer content for a page,
293    * called from only when beginPage() has been called for the Window.
294    */

295   protected void endPage( PrintWriter JavaDoc out,
296                           RenderRequest request,
297                           String JavaDoc namespace )
298     throws IOException JavaDoc
299   {
300   }
301
302   /**
303    * Finish with a Writer produced by this factory.
304    * This may be called even if the writer threw an Exception.
305    *
306    * This implementation calls endWindow() and endPage() if needed.
307    */

308   public void finish( PrintWriter JavaDoc out,
309                       RenderRequest request,
310                       String JavaDoc namespace,
311                       boolean isDiscarded )
312     throws IOException JavaDoc
313   {
314     boolean doPage = (this == request.getAttribute(PAGE_HEADER_RENDERED));
315
316     boolean doWindow = _isDecorateWindow == null
317                         ? !doPage
318                         : _isDecorateWindow.booleanValue();
319
320     if (!isDiscarded) {
321       if (doWindow)
322         endWindow(out, request, namespace);
323
324       if (doPage)
325         endPage(out, request, namespace);
326     }
327     else {
328       if (this == request.getAttribute(PAGE_HEADER_RENDERED))
329         request.removeAttribute(PAGE_HEADER_RENDERED);
330     }
331   }
332
333   /**
334    * Return an OutputStream that wraps the passed OutputStream, or null
335    * if there is no specialized writer for this request.
336    */

337   public OutputStream JavaDoc getOutputStream( OutputStream JavaDoc out,
338                                        RenderRequest request,
339                                        String JavaDoc namespace )
340     throws IOException JavaDoc
341   {
342     boolean doPage = (request.getAttribute(PAGE_HEADER_RENDERED) == null);
343
344     boolean doWindow = _isDecorateWindow == null
345                         ? !doPage
346                         : _isDecorateWindow.booleanValue();
347
348     if (doPage) {
349       beginPage(out, request, namespace);
350       request.setAttribute(PAGE_HEADER_RENDERED, this);
351     }
352
353     if (doWindow)
354       beginWindow(out, request, namespace);
355
356     return out;
357   }
358   
359   /**
360    * Derived classes override to insert header content for a page,
361    * called only when beginPage() has not been called on some instance of
362    * AbstractRenderer for this request.
363    *
364    * <code>request.getResponseContentType()</code> can be used
365    * to determine the content type.
366    *
367    * request.getAttribute("javax.portlet.title") may contain a title
368    * for the Window, if the portlet has set one.
369    */

370   protected void beginPage( OutputStream JavaDoc out,
371                             RenderRequest request,
372                             String JavaDoc namespace )
373     throws IOException JavaDoc
374   {
375   }
376
377   /**
378    * Derived classes override to insert header content before a portlet
379    * has been rendered.
380    *
381    * <code>request.getResponseContentType()</code> is used
382    * to determine the content type.
383    *
384    * request.getAttribute("javax.portlet.title") may contain a title
385    * for the Window, if the portlet has set one.
386    */

387   protected void beginWindow( OutputStream JavaDoc out,
388                               RenderRequest request,
389                               String JavaDoc namespace )
390     throws IOException JavaDoc
391   {
392   }
393
394   /**
395    * Derived classes override to append footer content after a portlet
396    * has been rendered.
397    *
398    * <code>request.getResponseContentType()</code> can be used
399    * to determine the content type.
400    *
401    */

402   protected void endWindow( OutputStream JavaDoc out,
403                             RenderRequest request,
404                             String JavaDoc namespace )
405     throws IOException JavaDoc
406   {
407   }
408
409   /**
410    * Derived classes override to insert footer content for a page,
411    * called from only when beginPage() has been called for the Window.
412    *
413    * <code>request.getResponseContentType()</code> can be used
414    * to determine the content type.
415    */

416   protected void endPage( OutputStream JavaDoc out,
417                           RenderRequest request,
418                           String JavaDoc namespace )
419     throws IOException JavaDoc
420   {
421   }
422
423   /**
424    * Finish with an OutputStream produced by this factory.
425    * This may be called even if the outputStream threw an Exception.
426    *
427    * This implementation calls endWindow() and endPage() if needed.
428    */

429   public void finish( OutputStream JavaDoc out,
430                       RenderRequest request,
431                       String JavaDoc namespace,
432                       boolean isDiscarded )
433     throws IOException JavaDoc
434   {
435     boolean doPage = (this == request.getAttribute(PAGE_HEADER_RENDERED));
436
437     boolean doWindow = _isDecorateWindow == null
438                         ? !doPage
439                         : _isDecorateWindow.booleanValue();
440
441     if (!isDiscarded) {
442       if (doWindow)
443         endWindow(out, request, namespace);
444
445       if (doPage)
446         endPage(out, request, namespace);
447     }
448     else {
449       if (this == request.getAttribute(PAGE_HEADER_RENDERED))
450         request.removeAttribute(PAGE_HEADER_RENDERED);
451     }
452   }
453
454   /**
455    * Return the content type to use for the response.
456    */

457   protected String JavaDoc getContentType(RenderRequest request)
458   {
459     return request.getResponseContentType();
460   }
461
462   /**
463    * Return the locale to use for the response.
464    */

465   protected Locale JavaDoc getLocale(RenderRequest request)
466   {
467     return request.getLocale();
468   }
469
470   /**
471    * Return the title for the window, or null if it has not been set.
472    * The title is the first of:
473    * <ul>
474    * <li>A title set by the portlet using response.setTitle()
475    * or request.setAttribute("javax.portlet.title");
476    * <li>The value of a lookup in the windows resource bundle for
477    * "javax.portlet.title" using the locale dertmined by
478    * {@link #getLocale(javax.portlet.RenderRequest) getLocale(request)}.
479    * </ul>
480    */

481   protected String JavaDoc getTitle(RenderRequest request)
482   {
483    String JavaDoc title = (String JavaDoc) request.getAttribute("javax.portlet.title");
484
485    if (title == null) {
486      PortletConfig portletConfig
487        = (PortletConfig) request.getAttribute("javax.portlet.portletConfig");
488
489      Locale JavaDoc locale = getLocale(request);
490      ResourceBundle JavaDoc bundle = portletConfig.getResourceBundle(locale);
491
492      if (bundle != null)
493        title = bundle.getString("javax.portlet.title");
494    }
495
496    return title;
497   }
498
499   /**
500    * Return the short title for the window, or null if a title is not
501    * available.
502    *
503    * <ul>
504    * <li>A title set by the portlet using
505    * request.setAttribute("javax.portlet.short-title");
506    * <li>A title set by the portlet using response.setTitle()
507    * or request.setAttribute("javax.portlet.title");
508    * <li>The value of a lookup in the windows resource bundle for
509    * "javax.portlet.short-title" using the locale determined by
510    * {@link #getLocale(javax.portlet.RenderRequest) getLocale(request)}.
511    * <li>The value of a lookup in the windows resource bundle for
512    * "javax.portlet.title" using the locale determined by
513    * {@link #getLocale(javax.portlet.RenderRequest) getLocale(request)}.
514    * </ul>
515    */

516   protected String JavaDoc getShortTitle( RenderRequest request )
517   {
518     String JavaDoc title = (String JavaDoc) request.getAttribute("javax.portlet.short-title");
519
520     if (title == null)
521       title = (String JavaDoc) request.getAttribute("javax.portlet.title");
522
523     if (title == null) {
524       PortletConfig portletConfig
525         = (PortletConfig) request.getAttribute("javax.portlet.portletConfig");
526
527       Locale JavaDoc locale = getLocale(request);
528       ResourceBundle JavaDoc bundle = portletConfig.getResourceBundle(locale);
529
530       title = bundle.getString("javax.portlet.short-title");
531
532       if (title == null)
533         title = bundle.getString("javax.portlet.title");
534     }
535
536     return title;
537   }
538
539   /**
540    * Create a PortletURL for a control, such as a link to change the window
541    * state or portlet mode. Control URLs are render urls that maintain
542    * existing render parameters.
543    */

544   protected PortletURL createControlURL(RenderRequest request)
545   {
546     RenderResponse response
547       = (RenderResponse) request.getAttribute("javax.portlet.renderResponse");
548
549     Map JavaDoc<String JavaDoc, String JavaDoc[]> renderParamMap = request.getParameterMap();
550
551     PortletURL url = response.createRenderURL();
552
553     url.setParameters(renderParamMap);
554
555     return url;
556   }
557
558   /**
559    * Return an Set of the possible portlet modes that the window can
560    * have. The list of all possibilities is first obtained from
561    * {@link javax.portlet.PortalContext#getSupportedPortletModesa() PortalContext.getSupportedPortletModes()}.
562    * Each one is checked with
563    * {@link javax.portlet.PortletRequest#isPortletModeAllowed(javax.portlet.PortletMode) request.isPortletModeAllowed()},
564    * if it is allowed then it is included in the returned Set.
565    */

566   protected Set JavaDoc<PortletMode> getPortletModes( RenderRequest request )
567   {
568     Set JavaDoc<PortletMode> portletModes = new LinkedHashSet JavaDoc<PortletMode>();
569
570     Enumeration JavaDoc<PortletMode> e = (Enumeration JavaDoc<PortletMode>)
571       request.getPortalContext().getSupportedPortletModes();
572
573     while (e.hasMoreElements()) {
574       PortletMode portletMode = e.nextElement();
575
576       if (request.isPortletModeAllowed(portletMode))
577         portletModes.add(portletMode);
578     }
579
580     return portletModes;
581   }
582
583   /**
584    * Return an Set of the possible window states that the window can
585    * have. The list of all possibilities is first obtained from
586    * {@link javax.portlet.PortalContext#getSupportedWindowStates() PortalContext.getSupportedWindowStates()}.
587    * Each one is checked with
588    * {@link javax.portlet.PortletRequest#isWindowStateAllowed(javax.portlet.WindowState) request.isWindowStateAllowed()},
589    * if it is allowed then it is included in the returned Set.
590    */

591   protected Set JavaDoc<WindowState> getWindowStates( RenderRequest request )
592   {
593     Set JavaDoc<WindowState> windowStates = new LinkedHashSet JavaDoc<WindowState>();
594
595     Enumeration JavaDoc<WindowState> e = (Enumeration JavaDoc<WindowState>)
596       request.getPortalContext().getSupportedWindowStates();
597
598     while (e.hasMoreElements()) {
599       WindowState windowState = e.nextElement();
600
601       if (request.isWindowStateAllowed(windowState))
602         windowStates.add(windowState);
603     }
604
605     return windowStates;
606   }
607
608   /**
609    * Get a resource bundle for the portlet being rendered.
610    */

611   protected ResourceBundle JavaDoc getResourceBundle( RenderRequest request )
612   {
613     Locale JavaDoc locale = getLocale( request );
614     PortletConfig portletConfig = getPortletConfig( request );
615     return portletConfig.getResourceBundle( locale );
616   }
617
618  /**
619    * Get the PortletConfig for the portlet being rendered.
620    */

621   protected PortletConfig getPortletConfig(RenderRequest request)
622   {
623     return (PortletConfig) request.getAttribute("javax.portlet.portletConfig");
624   }
625
626   /**
627    * Get the RenderResponse for the portlet being rendered.
628    */

629   protected RenderResponse getRenderResponse(RenderRequest request)
630   {
631     return (RenderResponse) request.getAttribute("javax.portlet.renderResponse");
632   }
633
634   /**
635    * Print a string with appropriate escaping for XML, for example '&lt;'
636    * becomes '&amp;lt;'.
637    */

638   protected PrintWriter JavaDoc printEscaped( PrintWriter JavaDoc out, CharSequence JavaDoc string )
639   {
640     if ( string == null ) {
641       out.print( (String JavaDoc) null );
642       return out;
643     }
644
645     for ( int i = 0; i < string.length(); i++ ) {
646       char ch = string.charAt( i );
647
648       switch ( ch ) {
649         case '<': out.print( "&lt;" ); break;
650         case '>': out.print( "&gt;" ); break;
651         case '&': out.print( "&amp;" ); break;
652         case '\"': out.print( "&quot;" ); break;
653         case '\'': out.print( "&rsquo;" ); break;
654         default: out.print( ch );
655       }
656     }
657
658     return out;
659   }
660
661 }
662
663
Popular Tags