1 28 29 package com.caucho.portal; 30 31 import com.caucho.util.L10N; 32 33 import javax.portlet.*; 34 import java.io.File ; 35 import java.io.IOException ; 36 import java.lang.reflect.InvocationTargetException ; 37 import java.lang.reflect.Method ; 38 import java.util.Collections ; 39 import java.util.HashMap ; 40 import java.util.Iterator ; 41 import java.util.Map ; 42 import java.util.NoSuchElementException ; 43 import java.util.logging.Level ; 44 import java.util.logging.Logger ; 45 46 public class PortletSupport extends GenericPortlet { 47 private static final L10N L = new L10N(PortletSupport.class); 48 49 static protected final Logger log = 50 Logger.getLogger(PortletSupport.class.getName()); 51 52 private static final Class [] _actionMethodParams 53 = new Class [] { ActionRequest.class, ActionResponse.class }; 54 55 private static final Class [] _renderMethodParams 56 = new Class [] { RenderRequest.class, RenderResponse.class }; 57 58 private Map <PortletMode, ActionProxy> _actionProxyCache 59 = Collections.synchronizedMap(new HashMap <PortletMode, ActionProxy>()); 60 61 private Map <PortletMode, RenderProxy> _renderProxyCache 62 = Collections.synchronizedMap(new HashMap <PortletMode, RenderProxy>()); 63 64 private interface ActionProxy { 65 public void processAction(ActionRequest request, ActionResponse response) 66 throws PortletException, IOException ; 67 } 68 69 private interface RenderProxy { 70 public void render(RenderRequest request, RenderResponse response) 71 throws PortletException, IOException ; 72 } 73 74 public void init() 75 throws PortletException 76 { 77 } 78 79 protected <T> T useBean( PortletRequest request, String name, Class <T> c) 80 { 81 return useBean( request, name, c, true ); 82 } 83 84 protected <T> T useBean( PortletRequest request, 85 String name, 86 Class <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 ex) { 96 throw new RuntimeException (ex); 97 } 98 99 request.setAttribute( name, bean ); 100 } 101 102 return bean; 103 } 104 105 protected boolean isEmpty( String 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 <S> mediatorClass ) 114 throws PortletException 115 { 116 String 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 <S> mediatorClass, 125 String namespace ) 126 throws PortletException 127 { 128 String 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 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 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 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 190 try { 191 String methodName = new StringBuffer () 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 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 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 [] { request, response }); 215 } 216 catch (IllegalAccessException ex) { 217 throw new PortletException(ex); 218 } 219 catch (InvocationTargetException ex) { 220 throw new PortletException(ex); 221 } 222 } 223 }; 224 } 225 } 226 catch (NoSuchMethodException 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 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 268 Iterator <String > candidates = getViewCandidates( request, response ); 269 270 while (candidates.hasNext()) { 271 String candidate = candidates.next(); 272 273 if (log.isLoggable(Level.FINER)) 274 log.finer(L.l("view candidate `{0}'", candidate)); 275 276 if (new File (getPortletContext().getRealPath(candidate)).exists()) { 277 final String target = candidate; 278 279 proxy = new RenderProxy() { 280 public void render(RenderRequest request, RenderResponse response) 281 throws PortletException, IOException 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 299 String methodName = new StringBuffer () 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 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 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 [] { request, response }); 327 } 328 catch (IllegalAccessException ex) { 329 throw new PortletException(ex); 330 } 331 catch (InvocationTargetException ex) { 332 throw new PortletException(ex); 333 } 334 } 335 }; 336 } 337 } catch (NoSuchMethodException 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 <String > getViewCandidates( RenderRequest request, 349 RenderResponse response ) 350 { 351 final String path = new StringBuffer () 352 .append(getPortletName()) 353 .append('/') 354 .append(request.getPortletMode().toString()) 355 .toString(); 356 357 358 return new Iterator <String >() { 359 int i = 0; 360 361 public boolean hasNext() 362 { 363 return i < 3; 364 } 365 366 public String 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 (); 377 } 378 } 379 380 public void remove() 381 { 382 throw new UnsupportedOperationException (); 383 } 384 }; 385 } 386 387 public void render( RenderRequest request, RenderResponse response ) 388 throws PortletException, IOException 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 path ) 418 throws PortletException, IOException 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 |