KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > widget > RendererCache


1 /*
2  * Copyright (c) 1998-2004 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
30 package com.caucho.widget;
31
32 import com.caucho.util.L10N;
33
34 import java.io.IOException JavaDoc;
35 import java.lang.reflect.InvocationTargetException JavaDoc;
36 import java.lang.reflect.Method JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.logging.Level JavaDoc;
41 import java.util.logging.Logger JavaDoc;
42
43 class RendererCache
44 {
45   private static L10N L = new L10N( RendererCache.class );
46
47   static protected final Logger JavaDoc log =
48     Logger.getLogger( RendererCache.class.getName() );
49
50   static final WidgetRenderer<Object JavaDoc> NULL_RENDERER
51     = new WidgetRenderer<Object JavaDoc>(){
52       public void render( WidgetConnection connection,
53                           Object JavaDoc widgetState )
54         throws WidgetException, IOException JavaDoc
55       {
56       }
57     };
58
59   private Map JavaDoc<String JavaDoc, WidgetRenderer> _rendererCache
60     = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc, WidgetRenderer>());
61
62   public <S extends WidgetState>
63     WidgetRenderer<S> getRenderer( WidgetConnection connection,
64                                    Widget<S> widget,
65                                    S widgetState )
66   {
67     String JavaDoc contentType = connection.getContentType();
68     WidgetMode widgetMode = widgetState.getWidgetMode();
69     
70     String JavaDoc cacheKey = contentType + Character.MAX_VALUE + widgetMode.toString();
71
72     WidgetRenderer renderer = _rendererCache.get( cacheKey );
73
74     if ( renderer != null )
75       return (WidgetRenderer<S>) renderer;
76
77     if ( renderer == NULL_RENDERER ) {
78       if ( log.isLoggable( Level.FINEST ) )
79         log.finest(
80             L.l( "no WidgetRenderer for contentType {0} for widget type {1}",
81                  contentType, widget.getClass().getName() ) );
82
83       return null;
84     }
85
86     String JavaDoc methodName = createMethodName( contentType );
87
88     Class JavaDoc widgetClass = widget.getClass();
89     Class JavaDoc widgetStateClass = widgetState.getClass();
90
91     // XXX: look for a WidgetRenderer added with addRenderer(WidgetRenderer)
92

93     // XXX: look for a globally registered WidgetRenderer in a WidgetRendererManager
94

95
96     // XXX: this won't work right if getMethod( "foo", { Baz.class } )
97
// matches a method foo( Foo ) where Baz extends Bar
98
// the createRenderer() methods may need to change
99

100     while ( renderer == null && widgetStateClass != null ) {
101
102       // look for render{ContentType}(WidgetConnection, widgetStateClass )
103

104       renderer
105         = createMethodNameRenderer( widget, widgetClass, widgetStateClass, methodName );
106
107       // look for render(String, WidgetConnection, widgetStateClass )
108

109       if ( renderer == null )
110         renderer
111           = createContentTypeRenderer( widget, widgetClass, widgetStateClass, contentType );
112
113       // try with the superclass of widgetStateClass
114

115       widgetStateClass = widgetStateClass.getSuperclass();
116     }
117
118     if ( renderer == null ) {
119       if ( log.isLoggable( Level.FINE ) )
120         log.fine(
121             L.l( "no WidgetRenderer for contentType {0} for widget type {1}",
122                  contentType, widget.getClass().getName() ) );
123
124       renderer = NULL_RENDERER;
125     }
126
127     _rendererCache.put( cacheKey, renderer );
128
129     return (WidgetRenderer<S>) renderer;
130   }
131
132   /** look for render{ContentType}( WidgetConnection, widgetClass ) */
133   private <S extends WidgetState>
134     WidgetRenderer<S> createMethodNameRenderer( final Widget<S> widget,
135                                                 Class JavaDoc widgetClass,
136                                                 Class JavaDoc widgetStateClass,
137                                                 String JavaDoc methodName )
138   {
139     Class JavaDoc[] methodArgs
140       = new Class JavaDoc[] { WidgetConnection.class, widgetStateClass };
141
142     Method JavaDoc findMethod = null;
143
144     try {
145       findMethod = widgetClass.getMethod( methodName, methodArgs );
146     }
147     catch (NoSuchMethodException JavaDoc ex) {
148     }
149
150     if ( findMethod != null ) {
151       if ( log.isLoggable( Level.FINEST ) )
152         log.finest( L.l( "WidgetRenderer for widget type {0} is method {1}()",
153                     widget.getClass().getName(), methodName ) );
154
155       final Method JavaDoc method = findMethod;
156
157       return new WidgetRenderer<S>() {
158         public void render( WidgetConnection connection, S widgetState )
159           throws WidgetException, IOException JavaDoc
160         {
161           try {
162             method.invoke( widget,
163                            new Object JavaDoc[] { connection, widgetState });
164           }
165           catch (IllegalAccessException JavaDoc ex) {
166             throw new WidgetException(ex);
167           }
168           catch (InvocationTargetException JavaDoc ex) {
169             throw new WidgetException(ex);
170           }
171         }
172       };
173     }
174     else
175       return null;
176   }
177
178   private <S extends WidgetState>
179     WidgetRenderer createContentTypeRenderer( final Widget<S> widget,
180                                               Class JavaDoc widgetClass,
181                                               Class JavaDoc widgetStateClass,
182                                               final String JavaDoc contentType )
183   {
184     Class JavaDoc[] methodArgs
185       = new Class JavaDoc[] { String JavaDoc.class, WidgetConnection.class, widgetStateClass };
186
187     Method JavaDoc findMethod = null;
188
189     try {
190       findMethod = widgetClass.getMethod( "render", methodArgs );
191     }
192     catch (NoSuchMethodException JavaDoc ex) {
193     }
194
195
196     if ( findMethod != null ) {
197       if ( log.isLoggable( Level.FINEST ) )
198         log.finest( L.l( "WidgetRenderer for contentType {0} for widget type {1} is method {2}()", contentType, widget.getClass().getName(), "render" ) );
199
200       final Method JavaDoc method = findMethod;
201
202       return new WidgetRenderer<S>() {
203         public void render( WidgetConnection connection, S widgetState )
204           throws WidgetException, IOException JavaDoc
205         {
206           try {
207             method.invoke( widget,
208                            new Object JavaDoc[] {contentType, connection, widgetState});
209           }
210           catch (IllegalAccessException JavaDoc ex) {
211             throw new WidgetException(ex);
212           }
213           catch (InvocationTargetException JavaDoc ex) {
214             throw new WidgetException(ex);
215           }
216         }
217       };
218     }
219     else
220       return null;
221   }
222
223   private String JavaDoc createMethodName( String JavaDoc contentType )
224   {
225     StringBuffer JavaDoc methodName = new StringBuffer JavaDoc();
226     methodName.append("render");
227
228     boolean toUpper = true;
229
230     for (int i = 0; i < contentType.length(); i++) {
231       char ch = contentType.charAt( i );
232
233       boolean isIdentifier =
234         i == 0 ? Character.isJavaIdentifierStart( ch )
235                : Character.isJavaIdentifierPart( ch );
236
237       if ( ! isIdentifier ) {
238         if ( toUpper )
239           ch = '_';
240         else {
241           toUpper = true;
242           continue;
243         }
244       }
245
246       if ( toUpper )
247         ch = Character.toUpperCase( ch );
248
249       methodName.append( ch );
250
251       toUpper = false;
252
253     }
254
255     return methodName.toString();
256   }
257 }
258
Popular Tags