KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > beehive > netui > pageflow > internal > JavaControlUtils


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * $Header:$
17  */

18 package org.apache.beehive.netui.pageflow.internal;
19
20 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
21
22 import org.apache.beehive.controls.runtime.servlet.ServletBeanContext;
23 import org.apache.beehive.controls.api.bean.Controls;
24 import org.apache.beehive.controls.api.bean.ControlBean;
25 import org.apache.beehive.controls.api.bean.Control;
26 import org.apache.beehive.controls.api.context.ControlBeanContext;
27 import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
28 import org.apache.beehive.controls.api.properties.PropertyMap;
29
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpServletResponse JavaDoc;
32 import javax.servlet.http.HttpSession JavaDoc;
33 import javax.servlet.ServletContext JavaDoc;
34 import java.lang.reflect.Field JavaDoc;
35 import java.lang.reflect.Modifier JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.HashMap JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.HashSet JavaDoc;
40
41 import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
42 import java.beans.beancontext.BeanContext JavaDoc;
43
44 import org.apache.beehive.netui.util.logging.Logger;
45 import org.apache.beehive.netui.pageflow.ControlFieldInitializationException;
46 import org.apache.beehive.netui.pageflow.PageFlowUtils;
47 import org.apache.beehive.netui.pageflow.PageFlowManagedObject;
48
49
50 /**
51  * @exclude
52  */

53 public class JavaControlUtils
54 {
55     private static final Logger _log = Logger.getInstance( JavaControlUtils.class );
56     private static final String JavaDoc CONTROL_CONTEXT_CLASSNAME = ServletBeanContext.class.getName();
57     private static final String JavaDoc CONTROL_ANNOTATION_CLASSNAME = Control.class.getName();
58     
59     /** Map of control-container-class (e.g., PageFlowController) to Map of fields/control-properties. */
60     private static InternalConcurrentHashMap/*< String, Map< Field, PropertyMap > >*/ _controlFieldCache =
61             new InternalConcurrentHashMap/*< String, Map< Field, PropertyMap > >*/();
62     
63     public static void initializeControlContext( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
64                                                  ServletContext JavaDoc servletContext )
65     {
66         ControlBeanContext beanContext = getControlBeanContext( request, response, servletContext, true );
67
68         //
69
// Start a new execution context
70
//
71
if ( beanContext instanceof ServletBeanContext )
72         {
73             ( ( ServletBeanContext ) beanContext ).beginContext( servletContext, request, response );
74         }
75     }
76
77     public static void uninitializeControlContext( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
78                                                    ServletContext JavaDoc servletContext )
79     {
80         
81         ControlBeanContext beanContext = getControlBeanContext( request, response, servletContext, false );
82         
83         if ( beanContext instanceof ServletBeanContext )
84         {
85             ( ( ServletBeanContext ) beanContext ).endContext();
86         }
87     }
88     
89     public static class ControlInstantiationException
90         extends Exception JavaDoc
91     {
92         private String JavaDoc _controlBeanClassName;
93         
94         public ControlInstantiationException( String JavaDoc controlBeanClassName, Throwable JavaDoc cause_ )
95         {
96             super( cause_ );
97             _controlBeanClassName = controlBeanClassName;
98         }
99
100         public String JavaDoc getControlBeanClassName()
101         {
102             return _controlBeanClassName;
103         }
104     }
105     
106     private static ControlBeanContext getControlBeanContext( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
107                                                              ServletContext JavaDoc servletContext, boolean createIfMissing )
108     {
109         //
110
// Retrieve the control bean context from the request, and if it's not there, from the session.
111
// Using the request first ensures that we don't get confused by session invalidation.
112
//
113
ControlBeanContext beanContext = ( ControlBeanContext ) request.getAttribute( CONTROL_CONTEXT_CLASSNAME );
114         if ( beanContext != null ) return beanContext;
115         
116         HttpSession JavaDoc session = request.getSession( false );
117         if ( session != null )
118         {
119             beanContext = ( ControlBeanContext ) session.getAttribute( CONTROL_CONTEXT_CLASSNAME );
120             
121             if ( beanContext != null )
122             {
123                 request.setAttribute( CONTROL_CONTEXT_CLASSNAME, beanContext );
124                 return beanContext;
125             }
126         }
127         
128         //
129
// If no context exists, then create a new one and store it in the session.
130
//
131
if ( createIfMissing )
132         {
133             beanContext = ( ControlBeanContext )
134                 AdapterManager.getServletContainerAdapter( servletContext ).createControlBeanContext( request, response );
135             request.getSession().setAttribute( CONTROL_CONTEXT_CLASSNAME, beanContext );
136             request.setAttribute( CONTROL_CONTEXT_CLASSNAME, beanContext );
137         }
138        
139         return beanContext;
140     }
141     
142     public static void destroyControl( Object JavaDoc controlInstance )
143     {
144         assert controlInstance instanceof ControlBean : controlInstance.getClass().getName();
145         BeanContext beanContext = ( ( ControlBean ) controlInstance ).getBeanContext();
146         if ( beanContext != null ) beanContext.remove( controlInstance );
147     }
148     
149
150     
151     /**
152      * @return a map of Field (accessible) -> AnnotationMap
153      */

154     private static Map getAccessibleControlFieldAnnotations( Class JavaDoc controlContainerClass, ServletContext JavaDoc servletContext )
155     {
156         String JavaDoc className = controlContainerClass.getName();
157         
158         //
159
// Reading the annotations is expensive. See if there's a cached copy of the map.
160
//
161
Map/*< Field, PropertyMap >*/ cached = ( Map ) _controlFieldCache.get( className );
162         
163         if ( cached != null )
164         {
165             return cached;
166         }
167
168         
169         HashMap JavaDoc/*< Field, PropertyMap >*/ ret = new HashMap JavaDoc/*< Field, PropertyMap >*/();
170         boolean accessPrivateFields = true;
171         
172         // Note that the annnotation reader doesn't change per-class. Inherited annotated elements are all read.
173
AnnotationReader annReader = AnnotationReader.getAnnotationReader( controlContainerClass, servletContext );
174         
175         //
176
// Go through this class and all superclasses, looking for control fields. Make sure that a superclass control
177
// field never replaces a subclass control field (this is what the 'fieldNames' HashSet is for).
178
//
179

180         HashSet JavaDoc fieldNames = new HashSet JavaDoc();
181         
182         do
183         {
184             Field JavaDoc[] fields = controlContainerClass.getDeclaredFields();
185             
186             for ( int i = 0; i < fields.length; i++ )
187             {
188                 Field JavaDoc field = fields[i];
189                 String JavaDoc fieldName = field.getName();
190                 int modifiers = field.getModifiers();
191                 
192                 if ( ! fieldNames.contains( fieldName ) && ! Modifier.isStatic( modifiers )
193                      && annReader.getAnnotation( field.getName(), CONTROL_ANNOTATION_CLASSNAME ) != null )
194                 {
195                     if ( accessPrivateFields || ! Modifier.isPrivate( modifiers ) )
196                     {
197                         field.setAccessible( true );
198                         ret.put( field, new AnnotatedElementMap( field ) );
199                         fieldNames.add( fieldName );
200                     }
201                 }
202             }
203     
204             accessPrivateFields = false;
205             controlContainerClass = controlContainerClass.getSuperclass();
206         } while ( controlContainerClass != null );
207         
208         _controlFieldCache.put( className, ret );
209         return ret;
210     }
211     
212     /**
213      * Initialize all null member variables that are Java Controls.
214      *
215      * @param request the current HttpServletRequest.
216      */

217     public static void initJavaControls( HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response,
218                                          ServletContext JavaDoc servletContext, PageFlowManagedObject controlClient )
219         throws ControlFieldInitializationException
220     {
221         Class JavaDoc controlClientClass = controlClient.getClass();
222         Map controlFields = getAccessibleControlFieldAnnotations( controlClientClass, servletContext );
223         if ( controlFields.isEmpty() ) return;
224
225         request = PageFlowUtils.unwrapMultipart( request );
226         ControlBeanContext beanContext = getControlBeanContext( request, response, servletContext, false );
227         assert beanContext != null : "ControlBeanContext was not initialized by PageFlowRequestProcessor";
228         try
229         {
230             Controls.initializeClient(null, controlClient, beanContext);
231         }
232         catch ( Exception JavaDoc e )
233         {
234             _log.error( "Exception occurred while initializing controls", e);
235             throw new ControlFieldInitializationException( controlClientClass.getName(), controlClient, e );
236         }
237     }
238     
239     /**
240      * Clean up all member variables that are Java Controls.
241      */

242     public static void uninitJavaControls( ServletContext JavaDoc servletContext, PageFlowManagedObject controlClient )
243     {
244         Map controlFields = getAccessibleControlFieldAnnotations( controlClient.getClass(), servletContext );
245         
246         for ( Iterator JavaDoc i = controlFields.keySet().iterator(); i.hasNext(); )
247         {
248             Field JavaDoc controlField = ( Field JavaDoc ) i.next();
249
250             try
251             {
252                 Object JavaDoc fieldValue = controlField.get( controlClient );
253                 
254                 if ( fieldValue != null )
255                 {
256                     controlField.set( controlClient, null );
257                     destroyControl( fieldValue );
258                 }
259             }
260             catch ( IllegalAccessException JavaDoc e )
261             {
262                 _log.error( "Exception while uninitializing Java Control " + controlField.getName(), e );
263             }
264         }
265     }
266 }
267
Popular Tags