KickJava   Java API By Example, From Geeks To Geeks.

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


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 package com.caucho.portal.generic;
50
51 import javax.portlet.*;
52 import java.io.IOException JavaDoc;
53 import java.lang.reflect.Constructor JavaDoc;
54 import java.lang.reflect.Modifier JavaDoc;
55 import java.util.*;
56 import java.util.logging.Level JavaDoc;
57 import java.util.logging.Logger JavaDoc;
58
59 abstract public class GenericWindow
60   implements Window, PortletConfig
61 {
62   static protected final Logger JavaDoc log =
63     Logger.getLogger(GenericWindow.class.getName());
64
65   private String JavaDoc _namespace = "";
66   private String JavaDoc _portletName;
67   private Map<String JavaDoc, String JavaDoc> _initParamMap;
68   private int _expirationCache;
69   private boolean _isPrivate;
70   private Renderer _renderer;
71   private int _bufferSize;
72   private Set<Locale> _supportedLocales;
73   private GenericPortletPreferences _defaultPreferences;
74   private ResourceBundleFactory _resourceBundleFactory;
75   private String JavaDoc _errorPage;
76
77   private PortletContext _portletContext;
78
79   public GenericWindow()
80   {
81   }
82  
83   /**
84    * The namespace is used to uniquely identify this usage of the portlet,
85    * the default is "" (the empty string).
86    *
87    * The namespace is important when using a portlet preferences store,
88    * and also has an effect on the encoding of parameters.
89    */

90   public void setNamespace(String JavaDoc namespace)
91   {
92     _namespace = namespace;
93   }
94
95   /**
96    * The default is the namespace.
97    */

98   public void setPortletName(String JavaDoc portletName)
99   {
100     _portletName = portletName;
101   }
102
103   /**
104    * Add an init-param for the portlet.
105    */

106   public void addInitParam(String JavaDoc name, String JavaDoc value)
107   {
108     if (_initParamMap == null)
109       _initParamMap = new LinkedHashMap<String JavaDoc, String JavaDoc>();
110
111     _initParamMap.put(name, value);
112   }
113
114   public void addInitParam(NameValuePair nameValuePair)
115   {
116     addInitParam(nameValuePair.getName(), nameValuePair.getValue());
117   }
118
119   /**
120    * Set the default preferences.
121    */

122   public void setPortletPreferences(GenericPortletPreferences defaultPreferences)
123   {
124     _defaultPreferences = defaultPreferences;
125   }
126
127   /**
128    * Enable caching of the response and set the expiration time in seconds. 0
129    * (the default) means do not cache, -1 means unlimited cach time, any other
130    * number is the number of seconds for which the response can be cached.
131    */

132   public void setExpirationCache(int expirationCache)
133   {
134     _expirationCache = expirationCache;
135   }
136
137   /**
138    * If true then the response is private, indicating that it contains
139    * information that should only be provided to the current client, default is
140    * false. Setting this to true has an effect on caching, if true then a
141    * cached value
142    * cannot be shared amongst different users and the effectiveness of caching
143    * is greatly reduced.
144    */

145   public void setPrivate(boolean isPrivate)
146   {
147     _isPrivate = isPrivate;
148   }
149
150   /**
151    * Add a supported locale, the default is to support all locales.
152    * This is an ordered list, those added first are more preferrable.
153    */

154   void addSupportedLocale(String JavaDoc locale)
155   {
156     String JavaDoc language = "";
157     String JavaDoc country = "";
158     String JavaDoc variant = "";
159
160     String JavaDoc[] split = locale.split("_", 3);
161     int len = split.length;
162
163     if (len == 0) {
164       split = locale.split("-", 3);
165       len = split.length;
166     }
167
168     if (len == 0)
169       throw new IllegalArgumentException JavaDoc(locale);
170
171     language = split[0];
172     if (len > 0)
173       country = split[1];
174     if (len > 1)
175       country = split[2];
176     
177     if (_supportedLocales == null)
178       _supportedLocales = new LinkedHashSet<Locale>();
179
180     _supportedLocales.add(new Locale(language, country, variant));
181   }
182
183   /**
184    * Add supported locales with a comma separated list, the default is to
185    * support all locales. This is an ordered list, those added first are more
186    * preferrable.
187    */

188   void addSupportedLocales(String JavaDoc locales)
189   {
190     String JavaDoc[] split = locales.split("\\s*,\\s*");
191     for (int i = 0; i < split.length; i++)
192       addSupportedLocale(split[i]);
193   }
194
195   /**
196    * Set a resource bundle name, used to instantiate an instance of
197    * ResourceBundleFactory.
198    */

199   public void setResourceBundle(String JavaDoc name)
200   {
201     ResourceBundleFactory resourceBundleFactory =
202       new ResourceBundleFactory();
203
204     resourceBundleFactory.setName(name);
205
206     setResourceBundleFactory(resourceBundleFactory);
207   }
208
209   public void setResourceBundleFactory(ResourceBundleFactory factory)
210   {
211     if (_resourceBundleFactory != null)
212       throw new IllegalArgumentException JavaDoc("resource-bundle-factory already set");
213   }
214
215   /**
216    * A Renderer wraps decorations around the portlet, see
217    * {@link AbstractRenderer}.
218    */

219   public void setRenderer(Renderer renderer)
220   {
221     _renderer = renderer;
222   }
223
224   /**
225    * An alternative to {@link #setRenderer(Renderer)}, specify the class
226    * name of an object to instantiate
227    */

228   public void setRendererClass(String JavaDoc className)
229   {
230     setRenderer( (Renderer) newInstance(Renderer.class, className) );
231   }
232
233   /**
234    * 0 disables buffering, -1 allows the portal to choose a
235    * buffer size, a positive number indicaets a minimum buffer size. Default is
236    * 0 unless `error-page' ({@link #setErrorPage(String)} has been used, then
237    * the default is -1.
238    */

239   public void setBufferSize(int bufferSize)
240   {
241     _bufferSize = bufferSize;
242   }
243
244   /**
245    * Specify a location to forward to if an exception or constraint failure
246    * occurs while rendering the portlet. The default behaviour is
247    * for an exception or constraint failure to propogate to the parent
248    * window, or if there is no parent then to the servlet container.
249    *
250    * If an exception occurs the following request attributes are set:
251    *
252    * <dl>
253    * <dt>com.caucho.portal.error.exception
254    * <dd>java.lang.Throwable
255    *
256    * <dt>com.caucho.portal.error.exception_type
257    * <dd>java.lang.Class
258    *
259    * <dt>com.caucho.portal.error.message
260    * <dd>java.lang.String
261    *
262    * <dt>javax.portlet.renderRequest
263    * <dd>javax.portlet.RenderRequest
264    *
265    * <dt>javax.portlet.renderResponse
266    * <dd>javax.portlet.RenderResponse
267    *
268    * <dt>javax.portlet.portletConfig
269    * <dd>javax.portlet.PortletConfig
270    *
271    * </dl>
272    *
273    * If a constraint failure occurs the following request attributes are set:
274    *
275    * <dl>
276    * <dt>com.caucho.portal.error.constraint
277    * <dd>com.caucho.portal.generic.Constraint
278    *
279    * <dt>com.caucho.portal.error.constraint_type
280    * <dd>java.lang.Class
281    *
282    * <dt>com.caucho.portal.error.status_code
283    * <dd>java.lang.Integer
284    *
285    * <dt>javax.portlet.renderRequest
286    * <dd>javax.portlet.RenderRequest
287    *
288    * <dt>javax.portlet.renderResponse
289    * <dd>javax.portlet.RenderResponse
290    *
291    * <dt>javax.portlet.portletConfig
292    * <dd>javax.portlet.PortletConfig
293    *
294    * </dl>
295    */

296   public void setErrorPage(String JavaDoc errorPage)
297   {
298     _errorPage = errorPage;
299
300     if (_bufferSize == 0)
301       _bufferSize = -1;
302   }
303
304   public void init(PortletContext portletContext)
305     throws PortletException
306   {
307     if (_portletContext != null)
308       throw new IllegalStateException JavaDoc("portlet-context already set!");
309
310     _portletContext = portletContext;
311
312     if (_portletName == null)
313       _portletName = _namespace == null ? "anonymous" : _namespace;
314   }
315
316   /**
317    * Instantiate a new instance of an object, performing checks
318    * for validity.
319    *
320    * The object that results from instantiating an instance of
321    * <code>className</code> must be an <code>instance of</code>
322    * <code>targetClass</code>.
323    *
324    * @param targetClass the class that the instantiated Object should be
325    * compatible with.
326    *
327    * @param className the String name of a class to use when instantiating the
328    * object.
329    *
330    * @return a new Object
331    */

332   protected Object JavaDoc newInstance(Class JavaDoc targetClass, String JavaDoc className)
333     throws IllegalArgumentException JavaDoc
334   {
335     Class JavaDoc cl = null;
336
337     ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
338
339     try {
340       cl = Class.forName(className, false, loader);
341     } catch (ClassNotFoundException JavaDoc e) {
342     }
343
344     if (cl == null)
345       throw new IllegalArgumentException JavaDoc(
346           "`" + className + "' is not a known class");
347
348     if (!targetClass.isAssignableFrom(cl))
349       throw new IllegalArgumentException JavaDoc(
350           "'" + className + "' must implement " + targetClass.getName());
351
352     if (Modifier.isAbstract(cl.getModifiers()))
353       throw new IllegalArgumentException JavaDoc(
354           "'" + className + "' must not be abstract.");
355
356     if (!Modifier.isPublic(cl.getModifiers()))
357       throw new IllegalArgumentException JavaDoc(
358           "'" + className + "' must be public.");
359
360     Constructor JavaDoc []constructors = cl.getDeclaredConstructors();
361
362     Constructor JavaDoc zeroArg = null;
363     for (int i = 0; i < constructors.length; i++) {
364       if (constructors[i].getParameterTypes().length == 0) {
365         zeroArg = constructors[i];
366         break;
367       }
368     }
369
370     if (zeroArg == null || !Modifier.isPublic(zeroArg.getModifiers()))
371       throw new IllegalArgumentException JavaDoc(
372           "'" + className + "' must have a public zero arg constructor");
373
374     Object JavaDoc obj = null;
375
376     try {
377       obj = cl.newInstance();
378     }
379     catch (Exception JavaDoc ex) {
380       throw new IllegalArgumentException JavaDoc(
381           "error instantiating `" + className + "': " + ex.toString(), ex);
382     }
383
384     return obj;
385   }
386
387   protected String JavaDoc getNamespace()
388   {
389     return _namespace;
390   }
391
392   /**
393    * {@inheritDoc}
394    */

395   public PortletContext getPortletContext()
396   {
397     if (_portletContext == null)
398       throw new IllegalStateException JavaDoc("missing init()?");
399
400     return _portletContext;
401   }
402
403   /**
404    * {@inheritDoc}
405    */

406   public PortletConfig getPortletConfig()
407   {
408     return this;
409   }
410
411   /**
412    * {@inheritDoc}
413    */

414   public String JavaDoc getPortletName()
415   {
416     return _portletName;
417   }
418
419   public String JavaDoc getInitParameter(String JavaDoc name)
420   {
421     if (_initParamMap == null)
422       return null;
423     else
424       return _initParamMap.get(name);
425   }
426
427   public Enumeration getInitParameterNames()
428   {
429     if (_initParamMap == null)
430       return Collections.enumeration(Collections.EMPTY_LIST);
431     else
432       return Collections.enumeration(_initParamMap.keySet());
433   }
434
435   /**
436    * {@inheritDoc}
437    */

438   public int getExpirationCache()
439   {
440     return _expirationCache;
441   }
442
443   /**
444    * {@inheritDoc}
445    */

446   public boolean isPrivate()
447   {
448     return _isPrivate;
449   }
450
451   /**
452    * {@inheritDoc}
453    *
454    * This implementation returns true.
455    */

456   public boolean isWindowStateAllowed(PortletRequest request,
457                                       WindowState windowState)
458   {
459     // XXX: todo: support a window-states init-param like
460
// normal, minimized
461
return true;
462   }
463
464   /**
465    * {@inheritDoc}
466    *
467    * This implementation returns true.
468    */

469   public boolean isPortletModeAllowed(PortletRequest request,
470                                       PortletMode portletMode)
471   {
472     // todo: see getSupportedContentTypes()
473
return true;
474   }
475
476   /**
477    * {@inheritDoc}
478    *
479    * This implementation returns null, which means that all content
480    * types are supported.
481    */

482   public Set<String JavaDoc> getSupportedContentTypes(PortletMode portletMode)
483   {
484     // XXX: todo: support a content-type init-param like
485
// edit(text/html), view(text/html, application/pdf)
486
return null;
487   }
488
489   /**
490    * {@inheritDoc}
491    *
492    * This implementation returns null, which means that all locales are
493    * supported.
494    */

495   public Set<Locale> getSupportedLocales()
496   {
497     return _supportedLocales;
498   }
499
500   /**
501    * {@inheritDoc}
502    *
503    * This implementation returns null.
504    */

505   public PortletPreferences getDefaultPreferences()
506   {
507     return _defaultPreferences;
508   }
509
510   /**
511    * {@inheritDoc}
512    */

513   public ArrayList<PreferencesValidator> getPreferencesValidators()
514   {
515     if (_defaultPreferences != null)
516       return _defaultPreferences.getPreferencesValidators();
517     else
518       return null;
519   }
520
521   /**
522    * {@inheritDoc}
523    *
524    * This implementation returns null.
525    */

526   public Map<String JavaDoc, String JavaDoc> getRoleRefMap()
527   {
528     return null;
529     // todo
530
}
531
532   /**
533    * {@inheritDoc}
534    *
535    * This implementation returns null.
536    */

537   public ArrayList<Constraint> getConstraints()
538   {
539     return null;
540     // todo
541
}
542
543   /**
544    * {@inheritDoc}
545    */

546   public Renderer getRenderer()
547   {
548     return _renderer;
549   }
550
551   /**
552    * {@inheritDoc}
553    *
554    * This implementation returns PortletMode.VIEW.
555    */

556   public PortletMode handlePortletModeFailure( PortletRequest request,
557                                                PortletMode notAllowed )
558   {
559     return PortletMode.VIEW;
560   }
561
562
563   /**
564    * {@inheritDoc}
565    *
566    * This implementation returns WindowState.NORMAL.
567    */

568   public WindowState handleWindowStateFailure( PortletRequest request,
569                                                WindowState notAllowed )
570   {
571     return WindowState.NORMAL;
572   }
573
574   /**
575    * {@inheritDoc}
576    *
577    * @see #setErrorPage(String)
578    */

579   public void handleConstraintFailure( RenderRequest request,
580                                        RenderResponse response,
581                                        ConstraintFailureEvent event )
582   {
583     if (_errorPage == null)
584       return;
585
586     Object JavaDoc existingConstraint =
587       request.getAttribute("com.caucho.portal.error.constraint");
588
589     Object JavaDoc existingConstraintType =
590       request.getAttribute("com.caucho.portal.error.constraint_type");
591
592     Object JavaDoc existingStatusCode =
593       request.getAttribute("com.caucho.portal.error.status_code");
594
595     Constraint constraint = event.getConstraint();
596     Class JavaDoc constraintType = constraint.getClass();
597     Integer JavaDoc statusCode = new Integer JavaDoc(event.getStatusCode());
598
599     request.setAttribute( "com.caucho.portal.error.constraint",
600                           constraint );
601     request.setAttribute( "com.caucho.portal.error.constraint_type",
602                           constraintType);
603     request.setAttribute( "com.caucho.portal.error.status_code",
604                           statusCode );
605
606     try {
607       if (handleErrorPage(request, response))
608         event.setHandled(false);
609       else
610         event.setHandled(true);
611     }
612     finally {
613       if (existingConstraint == null) {
614         request.removeAttribute( "com.caucho.portal.error.constraint" );
615         request.removeAttribute( "com.caucho.portal.error.constraint_type" );
616         request.removeAttribute( "com.caucho.portal.error.status_code" );
617       }
618       else {
619         request.setAttribute( "com.caucho.portal.error.constraint",
620                               existingConstraint );
621
622         request.setAttribute( "com.caucho.portal.error.constraint_type",
623                               existingConstraintType );
624
625         request.setAttribute( "com.caucho.portal.error.status_code",
626                               existingStatusCode );
627       }
628     }
629   }
630
631
632   /**
633    * {@inheritDoc}
634    *
635    * @see #setErrorPage(String)
636    */

637   public void handleException( RenderRequest request,
638                                RenderResponse response,
639                                ExceptionEvent event )
640   {
641     if (_errorPage == null)
642       return;
643
644     Object JavaDoc existingException =
645       request.getAttribute("com.caucho.portal.error.exception");
646
647     Object JavaDoc existingExceptionType =
648       request.getAttribute("com.caucho.portal.error.exception_type");
649
650     Object JavaDoc existingMessage =
651       request.getAttribute("com.caucho.portal.error.message");
652
653     Exception JavaDoc exception = event.getException();
654     Class JavaDoc exceptionType = exception.getClass();
655     String JavaDoc message = exception.getMessage();
656
657     request.setAttribute( "com.caucho.portal.error.exception",
658                           exception );
659
660     request.setAttribute( "com.caucho.portal.error.exception_type",
661                           exceptionType );
662
663     request.setAttribute( "com.caucho.portal.error.message",
664                           message );
665
666     try {
667       if (handleErrorPage(request, response))
668         event.setHandled(false);
669       else
670         event.setHandled(true);
671     }
672     finally {
673       if (existingException == null) {
674         request.removeAttribute( "com.caucho.portal.error.exception" );
675         request.removeAttribute( "com.caucho.portal.error.exception_type" );
676         request.removeAttribute( "com.caucho.portal.error.message" );
677       }
678       else {
679         request.setAttribute( "com.caucho.portal.error.exception",
680                               existingException );
681
682         request.setAttribute( "com.caucho.portal.error.exception_type",
683                               existingExceptionType );
684
685         request.setAttribute( "com.caucho.portal.error.message",
686                               existingMessage );
687       }
688     }
689   }
690
691   private boolean handleErrorPage( RenderRequest request,
692                                    RenderResponse response )
693   {
694     try {
695
696       PortletRequestDispatcher dispatcher
697         = getPortletContext().getRequestDispatcher(_errorPage);
698
699       dispatcher.include(request, response);
700     }
701     catch (Exception JavaDoc ex) {
702       log.log(Level.WARNING, ex.toString(), ex);
703       return false;
704     }
705
706     return true;
707   }
708
709   /**
710    * {@inheritDoc}
711    */

712   public ResourceBundle getResourceBundle(Locale locale)
713   {
714     if (_resourceBundleFactory == null)
715       _resourceBundleFactory = new ResourceBundleFactory();
716
717     return _resourceBundleFactory.getResourceBundle(locale);
718   }
719
720   /**
721    * {@inheritDoc}
722    */

723   public int getBufferSize()
724   {
725     return _bufferSize;
726   }
727
728   abstract public void processAction(PortletConnection connection)
729     throws PortletException, IOException JavaDoc;
730
731   abstract public void render(PortletConnection connection)
732     throws PortletException, IOException JavaDoc;
733
734   public void destroy()
735   {
736   }
737 }
738
739
Popular Tags