KickJava   Java API By Example, From Geeks To Geeks.

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


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.pageflow.AutoRegisterActionServlet;
21 import org.apache.beehive.netui.pageflow.ServletContainerAdapter;
22 import org.apache.beehive.netui.pageflow.RequestContext;
23 import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler;
24 import org.apache.beehive.netui.util.internal.BouncyClassLoader;
25 import org.apache.beehive.netui.util.internal.cache.ClassLevelCache;
26 import org.apache.beehive.netui.util.logging.Logger;
27 import org.apache.beehive.netui.util.internal.DiscoveryUtils;
28
29 import javax.servlet.http.HttpSession JavaDoc;
30 import javax.servlet.ServletContext JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.Map JavaDoc;
33 import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap;
34 import java.io.File JavaDoc;
35
36 import org.apache.struts.action.ActionServlet;
37
38
39 public class DefaultReloadableClassHandler
40         extends DefaultHandler
41     implements ReloadableClassHandler
42 {
43     private static final Logger _log = Logger.getInstance( DefaultReloadableClassHandler.class );
44     
45     private BouncyClassLoader _pageFlowClassLoader = null;
46     
47     public DefaultReloadableClassHandler( ServletContext JavaDoc servletContext )
48     {
49         init( null, null, servletContext );
50         
51         // This feature is disabled for now.
52
if ( false )
53         {
54             ClassLoader JavaDoc contextClassLoader = Thread.currentThread().getContextClassLoader();
55             ServletContainerAdapter servletContainerAdapter = AdapterManager.getServletContainerAdapter( servletContext );
56             File JavaDoc[] classDirs = null;
57             
58             // TODO: make this configurable in netui-config.xml. You should be able to specify absolute files
59
// and also context-relative paths.
60
{
61                 String JavaDoc path = servletContext.getRealPath( "/WEB-INF/classes" );
62                 
63                 if ( path != null )
64                 {
65                     File JavaDoc file = new File JavaDoc( path );
66                     if ( file.isDirectory() ) classDirs = new File JavaDoc[]{ file };
67                 }
68             }
69             
70             if ( classDirs != null && ! servletContainerAdapter.isInProductionMode() )
71             {
72                 _pageFlowClassLoader = new BouncyClassLoader( classDirs, contextClassLoader );
73             }
74         }
75     }
76     
77     public Object JavaDoc newInstance( String JavaDoc className )
78         throws ClassNotFoundException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc
79     {
80         return getRegisteredReloadableClassHandler().loadClass( className ).newInstance();
81     }
82     
83     private static Map JavaDoc/*< String, Class >*/ _loadedClasses = new InternalConcurrentHashMap/*< String, Class >*/();
84     private static class Null {}
85     private static Class JavaDoc NULL_CLASS = Null.class;
86     
87     public Class JavaDoc loadCachedClass( String JavaDoc className )
88     {
89         Class JavaDoc clazz = ( Class JavaDoc ) _loadedClasses.get( className );
90         
91         if ( clazz != null )
92         {
93             return clazz != NULL_CLASS ? clazz : null;
94         }
95         else
96         {
97             try
98             {
99                 clazz = getRegisteredReloadableClassHandler().loadClass( className );
100                 _loadedClasses.put( className, clazz );
101                 return clazz;
102             }
103             catch ( ClassNotFoundException JavaDoc e )
104             {
105                 _loadedClasses.put( className, NULL_CLASS );
106                 return null;
107             }
108         }
109     }
110     
111     public Class JavaDoc loadClass( String JavaDoc className )
112         throws ClassNotFoundException JavaDoc
113     {
114         if ( _pageFlowClassLoader != null )
115         {
116             synchronized ( this )
117             {
118                 return _pageFlowClassLoader.loadClass( className );
119             }
120         }
121         else
122         {
123             return DiscoveryUtils.getClassLoader().loadClass( className );
124         }
125     }
126     
127     public void reloadClasses( RequestContext context )
128     {
129         if ( _pageFlowClassLoader == null )
130         {
131             return;
132         }
133         
134         synchronized ( this )
135         {
136             if ( _pageFlowClassLoader.isStale() )
137             {
138                 _log.debug( "Classes modified; bouncing classloader." );
139                 
140                 //
141
// First go through the session and remove any attributes whose classes were loaded by the stale
142
// classloader.
143
//
144
HttpSession JavaDoc session = InternalUtils.getHttpSession( context.getRequest(), false );
145                 
146                 if ( session != null )
147                 {
148                     for ( Enumeration JavaDoc e = session.getAttributeNames(); e.hasMoreElements(); )
149                     {
150                         String JavaDoc attrName = ( String JavaDoc ) e.nextElement();
151                         Object JavaDoc attr = session.getAttribute( attrName );
152                         if ( attr.getClass().getClassLoader() == _pageFlowClassLoader )
153                         {
154                             if ( _log.isDebugEnabled() )
155                             {
156                                 _log.debug( "Removing session attribute " + attrName + " (" + attr
157                                              + ") because its ClassLoader is being bounced." );
158                             }
159                             
160                             session.removeAttribute( attrName );
161                         }
162                     }
163                 }
164                 
165                 //
166
// Clear all caches of methods, etc.
167
//
168
ClassLevelCache.clearAll();
169                 
170                 //
171
// Clear out all registered modules from the ActionServlet.
172
//
173
ActionServlet actionServlet = InternalUtils.getActionServlet( getServletContext() );
174                 
175                 if ( actionServlet instanceof AutoRegisterActionServlet )
176                 {
177                     ( ( AutoRegisterActionServlet ) actionServlet ).clearRegisteredModules();
178                 }
179                 
180                 //
181
// Bounce the classloader.
182
//
183
init( getConfig(), getPreviousHandler(), getServletContext() );
184             }
185         }
186     }
187     
188     public ClassLoader JavaDoc getClassLoader()
189     {
190         if ( _pageFlowClassLoader != null )
191         {
192             synchronized ( this )
193             {
194                 return _pageFlowClassLoader;
195             }
196         }
197         
198         return _pageFlowClassLoader;
199     }
200     
201     public boolean isReloadEnabled()
202     {
203         return _pageFlowClassLoader != null;
204     }
205     
206     public ReloadableClassHandler getRegisteredReloadableClassHandler()
207     {
208         return ( ReloadableClassHandler ) super.getRegisteredHandler();
209     }
210 }
211
Popular Tags