KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > portal > PortletSupport


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Sam
27  */

28
29 package com.caucho.portal;
30
31 import com.caucho.util.L10N;
32
33 import javax.portlet.*;
34 import java.io.File JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.lang.reflect.InvocationTargetException JavaDoc;
37 import java.lang.reflect.Method JavaDoc;
38 import java.util.Collections JavaDoc;
39 import java.util.HashMap JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.Map JavaDoc;
42 import java.util.NoSuchElementException JavaDoc;
43 import java.util.logging.Level JavaDoc;
44 import java.util.logging.Logger JavaDoc;
45
46 public class PortletSupport extends GenericPortlet {
47   private static final L10N L = new L10N(PortletSupport.class);
48
49   static protected final Logger JavaDoc log =
50     Logger.getLogger(PortletSupport.class.getName());
51
52   private static final Class JavaDoc[] _actionMethodParams
53     = new Class JavaDoc[] { ActionRequest.class, ActionResponse.class };
54
55   private static final Class JavaDoc[] _renderMethodParams
56     = new Class JavaDoc[] { RenderRequest.class, RenderResponse.class };
57
58   private Map JavaDoc<PortletMode, ActionProxy> _actionProxyCache
59     = Collections.synchronizedMap(new HashMap JavaDoc<PortletMode, ActionProxy>());
60
61   private Map JavaDoc<PortletMode, RenderProxy> _renderProxyCache
62     = Collections.synchronizedMap(new HashMap JavaDoc<PortletMode, RenderProxy>());
63
64   private interface ActionProxy {
65     public void processAction(ActionRequest request, ActionResponse response)
66       throws PortletException, IOException JavaDoc;
67   }
68
69   private interface RenderProxy {
70     public void render(RenderRequest request, RenderResponse response)
71       throws PortletException, IOException JavaDoc;
72   }
73
74   public void init()
75     throws PortletException
76   {
77   }
78
79   protected <T> T useBean( PortletRequest request, String JavaDoc name, Class JavaDoc<T> c)
80   {
81     return useBean( request, name, c, true );
82   }
83
84   protected <T> T useBean( PortletRequest request,
85                            String JavaDoc name,
86                            Class JavaDoc<T> c,
87                            boolean create )
88   {
89     T bean = (T) request.getAttribute( name );
90
91     if (bean == null && create) {
92       try {
93         bean = c.newInstance();
94       }
95       catch (Exception JavaDoc ex) {
96         throw new RuntimeException JavaDoc(ex);
97       }
98
99       request.setAttribute( name, bean );
100     }
101
102     return bean;
103   }
104
105   protected boolean isEmpty( String JavaDoc s )
106   {
107     return s == null || s.length() == 0;
108   }
109
110   protected static <S extends PortletMediator>
111     S createMediator( RenderRequest request,
112                       RenderResponse response,
113                       Class JavaDoc<S> mediatorClass )
114     throws PortletException
115   {
116     String JavaDoc namespace = response.getNamespace();
117
118     return createMediator( request, response, mediatorClass, namespace );
119   }
120
121   protected static <S extends PortletMediator>
122     S createMediator( RenderRequest request,
123                       RenderResponse response,
124                       Class JavaDoc<S> mediatorClass,
125                       String JavaDoc namespace )
126     throws PortletException
127   {
128     String JavaDoc attributeName = mediatorClass.getName();
129
130     if ( namespace != null )
131       attributeName = attributeName + namespace;
132
133     S mediator = (S) request.getAttribute( attributeName );
134
135     if ( mediator == null ) {
136       try {
137         mediator = (S) mediatorClass.newInstance();
138       }
139       catch ( Exception JavaDoc ex ) {
140         throw new PortletException( ex );
141       }
142
143       request.setAttribute( attributeName, mediator );
144     }
145
146     mediator.setNamespace( namespace );
147     mediator.setRequest( request );
148     mediator.setResponse( response );
149
150     return mediator;
151   }
152
153   /**
154    * Prepare is called once for each request, either before the action method
155    * appropriate for the mode is invoked, or if there is no action then
156    * before a render appropriate for the mode is invoked.
157    */

158   protected void prepare( PortletRequest request, PortletResponse response )
159     throws PortletException
160   {
161   }
162
163   protected void checkPrepare(PortletRequest request, PortletResponse response)
164     throws PortletException
165   {
166
167     String JavaDoc attributeName = "__prepared__" + System.identityHashCode(this);
168
169     if (request.getAttribute( attributeName ) == null) {
170       request.setAttribute( attributeName, Boolean.TRUE);
171
172       if (log.isLoggable(Level.FINEST))
173         log.finest(L.l("prepare for mode `{0}'", request.getPortletMode()));
174
175       prepare(request, response);
176     }
177   }
178
179   private ActionProxy findActionProxy( ActionRequest request,
180                                        ActionResponse response )
181   {
182     PortletMode mode = request.getPortletMode();
183     ActionProxy proxy = _actionProxyCache.get(mode);
184
185     if (proxy != null)
186       return proxy;
187
188     // try to find a method named "action" + mode
189

190     try {
191       String JavaDoc methodName = new StringBuffer JavaDoc()
192         .append("action")
193         .append(Character.toUpperCase(mode.toString().charAt(0)))
194         .append(mode.toString().substring(1))
195         .toString();
196
197       if (log.isLoggable(Level.FINER))
198         log.log(Level.FINER, "looking for method `" + methodName + "'");
199
200       final Method JavaDoc method
201         = getClass().getMethod(methodName, _actionMethodParams);
202
203       if (method != null) {
204         proxy = new ActionProxy() {
205           public void processAction( ActionRequest request,
206                                      ActionResponse response )
207             throws PortletException, IOException JavaDoc
208           {
209             try {
210               if (log.isLoggable(Level.FINEST))
211                 log.log(Level.FINER, "invoking method " + method);
212
213               method.invoke( PortletSupport.this,
214                              new Object JavaDoc[] { request, response });
215             }
216             catch (IllegalAccessException JavaDoc ex) {
217               throw new PortletException(ex);
218             }
219             catch (InvocationTargetException JavaDoc ex) {
220               throw new PortletException(ex);
221             }
222           }
223         };
224       }
225     }
226     catch (NoSuchMethodException JavaDoc ex) {
227       if (log.isLoggable(Level.FINE))
228         log.log(Level.FINE, ex.toString(), ex);
229     }
230
231     if (proxy != null)
232       _actionProxyCache.put(mode, proxy);
233
234     return proxy;
235   }
236
237   public void processAction( ActionRequest request, ActionResponse response )
238     throws PortletException, IOException JavaDoc
239   {
240     PortletMode mode = request.getPortletMode();
241
242     if (log.isLoggable(Level.FINEST))
243       log.finest(L.l("processAction for mode `{0}'", mode));
244
245     ActionProxy proxy = findActionProxy( request, response );
246
247     if (proxy == null)
248       throw new PortletModeException( L.l("No action for mode `{0}'", mode),
249           mode );
250
251     checkPrepare( request, response );
252
253     proxy.processAction( request, response);
254   }
255
256   private RenderProxy findRenderProxy( RenderRequest request,
257                                        RenderResponse response )
258   {
259     PortletMode mode = request.getPortletMode();
260
261     RenderProxy proxy = _renderProxyCache.get(mode);
262
263     if (proxy != null)
264       return proxy;
265
266     // try to find a .xtp/.jsp/.jspx file
267

268     Iterator JavaDoc<String JavaDoc> candidates = getViewCandidates( request, response );
269
270     while (candidates.hasNext()) {
271       String JavaDoc candidate = candidates.next();
272
273       if (log.isLoggable(Level.FINER))
274         log.finer(L.l("view candidate `{0}'", candidate));
275
276       if (new File JavaDoc(getPortletContext().getRealPath(candidate)).exists()) {
277         final String JavaDoc target = candidate;
278
279         proxy = new RenderProxy() {
280           public void render(RenderRequest request, RenderResponse response)
281             throws PortletException, IOException JavaDoc
282           {
283             dispatchView( request, response, target );
284           }
285         };
286
287         break;
288       }
289     }
290
291     if (proxy != null) {
292       _renderProxyCache.put(mode, proxy);
293
294       return proxy;
295     }
296
297     // try to find a method named "do" + mode
298

299     String JavaDoc methodName = new StringBuffer JavaDoc()
300       .append("do")
301       .append(Character.toUpperCase(mode.toString().charAt(0)))
302       .append(mode.toString().substring(1))
303       .toString();
304
305     if (log.isLoggable(Level.FINER))
306       log.log(Level.FINER, "looking for method `" + methodName + "'");
307
308     try {
309       final Method JavaDoc method
310         = getClass().getMethod(methodName, _renderMethodParams);
311
312       if (method != null) {
313         proxy = new RenderProxy() {
314           public void render( RenderRequest request, RenderResponse response )
315             throws PortletException, IOException JavaDoc
316           {
317             try {
318               if (log.isLoggable(Level.FINER))
319                 log.log(Level.FINER, "invoking method " + method);
320
321               if (log.isLoggable(Level.FINER))
322                 log.log(Level.FINER, "with " + request + " " + response);
323
324
325               method.invoke( PortletSupport.this,
326                              new Object JavaDoc[] { request, response });
327             }
328             catch (IllegalAccessException JavaDoc ex) {
329               throw new PortletException(ex);
330             }
331             catch (InvocationTargetException JavaDoc ex) {
332               throw new PortletException(ex);
333             }
334           }
335         };
336       }
337     } catch (NoSuchMethodException JavaDoc ex) {
338       if (log.isLoggable(Level.FINEST))
339         log.log(Level.FINEST, ex.toString(), ex);
340     }
341
342     if (proxy != null)
343       _renderProxyCache.put(mode, proxy);
344
345     return proxy;
346   }
347
348   protected Iterator JavaDoc<String JavaDoc> getViewCandidates( RenderRequest request,
349                                                 RenderResponse response )
350   {
351     final String JavaDoc path = new StringBuffer JavaDoc()
352       .append(getPortletName())
353       .append('/')
354       .append(request.getPortletMode().toString())
355       .toString();
356
357     
358     return new Iterator JavaDoc<String JavaDoc>() {
359       int i = 0;
360
361       public boolean hasNext()
362       {
363         return i < 3;
364       }
365
366       public String JavaDoc next()
367       {
368         switch (i++) {
369           case 0:
370             return path + ".xtp";
371           case 1:
372             return path + ".jsp";
373           case 2:
374             return path + ".jspx";
375           default:
376             throw new NoSuchElementException JavaDoc();
377         }
378       }
379
380       public void remove()
381       {
382         throw new UnsupportedOperationException JavaDoc();
383       }
384     };
385   }
386
387   public void render( RenderRequest request, RenderResponse response )
388     throws PortletException, IOException JavaDoc
389   {
390     WindowState windowState = request.getWindowState();
391
392     if (windowState.equals(WindowState.MINIMIZED))
393       return;
394
395     RenderProxy proxy = findRenderProxy( request, response );
396
397     PortletMode mode = request.getPortletMode();
398
399     if (log.isLoggable(Level.FINEST))
400       log.finest(L.l("render for mode `{0}'", mode));
401
402     if (proxy == null)
403       throw new PortletModeException( L.l("No render for mode `{0}'", mode),
404                                       mode );
405
406     checkPrepare( request, response );
407
408     if (response.getContentType() == null)
409       response.setContentType("text/html");
410
411     proxy.render( request, response );
412
413   }
414
415   protected void dispatchView( RenderRequest request,
416                                RenderResponse response,
417                                String JavaDoc path )
418     throws PortletException, IOException JavaDoc
419   {
420     if (log.isLoggable(Level.FINEST))
421       log.finest(L.l("dispatching view to `{0}'", path));
422
423     PortletRequestDispatcher dispatcher
424         = getPortletContext().getRequestDispatcher(path);
425
426     dispatcher.include(request, response);
427   }
428 }
429
Popular Tags