KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > httpserver > HttpServerModule


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.httpserver;
21
22 import java.io.Externalizable JavaDoc;
23 import java.io.File JavaDoc;
24 import java.net.MalformedURLException JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Vector JavaDoc;
28 import javax.servlet.ServletContext JavaDoc;
29 import org.apache.tomcat.context.WebXmlReader;
30 import org.apache.tomcat.startup.EmbededTomcat;
31 import org.apache.tomcat.core.ContextManager;
32 import org.apache.tomcat.core.Context;
33 import org.apache.tomcat.logging.TomcatLogger;
34 import org.apache.tomcat.service.PoolTcpConnector;
35 import org.openide.ErrorManager;
36 import org.openide.filesystems.FileUtil;
37 import org.openide.filesystems.Repository;
38 import org.openide.modules.ModuleInstall;
39 import org.openide.util.Lookup;
40 import org.openide.util.LookupEvent;
41 import org.openide.util.LookupListener;
42 import org.openide.util.NbBundle;
43 import org.openide.util.RequestProcessor;
44 import org.openide.util.SharedClassObject;
45
46 /**
47 * Module installation class for Http Server
48 *
49 * @author Petr Jiricka
50 */

51 public class HttpServerModule extends ModuleInstall implements Externalizable JavaDoc {
52
53
54     private static ContextManager server;
55     
56     /** listener that reloads context when systemClassLoader changes */
57     private static ContextReloader reloader;
58     
59     private static Thread JavaDoc serverThread;
60     private static boolean inSetRunning = false;
61
62     /** Module is being closed. */
63     public void close () {
64         // stop the server, don't set the running status
65
synchronized (HttpServerSettings.httpLock ()) {
66             stopHTTPServer();
67         }
68     }
69
70     /** initiates HTTPServer so it runs */
71     static void initHTTPServer() {
72         if (inSetRunning)
73             return;
74         synchronized (HttpServerSettings.httpLock ()) {
75             if (inSetRunning)
76                 return;
77             inSetRunning = true;
78             try {
79                 if ((serverThread != null) && (!httpserverSettings ().running)) {
80                     // another thread is trying to start the server, wait for a while and then stop it if it's still bad
81
try {
82                         Thread.currentThread().sleep(2000);
83                     }
84                     catch (InterruptedException JavaDoc e) {}
85                     if ((serverThread != null) && (!httpserverSettings ().running)) {
86                         serverThread.stop();
87                         serverThread = null;
88                     }
89                 }
90                 if (serverThread == null) {
91                     serverThread = new Thread JavaDoc("HTTPServer") { // NOI18N
92
public void run() {
93                                            try {
94                                                server = buildServer();
95                                                server.start();
96                                                httpserverSettings ().runSuccess();
97                                                reloader.activate ();
98                                                // this is not a debug message, this is a server startup message
99
if (httpserverSettings ().isStartStopMessages())
100                                                    System.out.println(NbBundle.getMessage(HttpServerModule.class, "CTL_ServerStarted", new Object JavaDoc[] {new Integer JavaDoc(httpserverSettings ().getPort())}));
101                                            }
102                                            catch (ThreadDeath JavaDoc td) {
103                                                throw td;
104                                            }
105                                            catch (Throwable JavaDoc ex) {
106                                                ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, ex);
107                                                // couldn't start
108
serverThread = null;
109                                                inSetRunning = false;
110                                                httpserverSettings ().runFailure(ex);
111                                            }
112                                            finally {
113                                                httpserverSettings ().setStartStopMessages(true);
114                                            }
115                                        }
116                                    };
117                     serverThread.start();
118                 }
119                 // wait for the other thread to start the server
120
try {
121                     HttpServerSettings.httpLock ().wait(HttpServerSettings.SERVER_STARTUP_TIMEOUT);
122                 }
123                 catch (Exception JavaDoc e) {
124                     ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, e);
125                 }
126             }
127             finally {
128                 inSetRunning = false;
129             }
130         }
131     }
132
133     public void uninstalled () {
134         stopHTTPServer();
135     }
136     
137     /** stops the HTTP server */
138     @SuppressWarnings JavaDoc("deprecation")
139     static void stopHTTPServer() {
140         if (inSetRunning)
141             return;
142         synchronized (HttpServerSettings.httpLock ()) {
143             if (inSetRunning)
144                 return;
145             inSetRunning = true;
146             try {
147                 if (reloader != null) {
148                     reloader.deactivate ();
149                     reloader = null;
150                 }
151                 
152                 if ((serverThread != null) && (server != null)) {
153                     try {
154                         server.stop();
155                         serverThread.join();
156                     }
157                     catch (InterruptedException JavaDoc e) {
158                         serverThread.stop();
159                         /* deprecated, but this really is the last resort,
160                            only if everything else failed */

161                     }
162                     catch (Exception JavaDoc e) {
163                         //e.printStackTrace();
164
serverThread.stop();
165                         /* deprecated, but this really is the last resort,
166                            only if everything else failed */

167                     }
168                     serverThread = null;
169                     // this is not a debug message, this is a server shutdown message
170
if (httpserverSettings ().isStartStopMessages())
171                         System.out.println(NbBundle.getBundle(HttpServerModule.class).
172                                            getString("CTL_ServerStopped"));
173                 }
174             }
175             finally {
176                 inSetRunning = false;
177             }
178         }
179     }
180     
181     
182     private static ContextManager getContextManager(EmbededTomcat tc) {
183         try {
184             java.lang.reflect.Field JavaDoc fm = EmbededTomcat.class.getDeclaredField("contextM"); // NOI18N
185
fm.setAccessible(true);
186             return (ContextManager)fm.get(tc);
187         }
188         catch (NoSuchFieldException JavaDoc e) {
189             return null;
190         }
191         catch (IllegalAccessException JavaDoc e) {
192             return null;
193         }
194     }
195     
196
197     /** Removes WebXmlReader interceptor to avoid attempt
198      * to load JspServlet that processes jsp file and produces confusing message
199      */

200     private static void removeWebXmlReader (EmbededTomcat tc) {
201         try {
202             java.lang.reflect.Field JavaDoc fm = EmbededTomcat.class.getDeclaredField("contextInt"); // NOI18N
203
fm.setAccessible(true);
204             Vector JavaDoc contextInt = (Vector JavaDoc)fm.get(tc);
205             Iterator JavaDoc it = contextInt.iterator ();
206             while (it.hasNext ()) {
207                 Object JavaDoc o = it.next ();
208                 if (o instanceof WebXmlReader) {
209                     contextInt.remove (o);
210                     break;
211                 }
212             }
213         }
214         catch (NoSuchFieldException JavaDoc e) {
215             return;
216         }
217         catch (IllegalAccessException JavaDoc e) {
218             return;
219         }
220     }
221     
222
223     private static ContextManager buildServer() throws Exception JavaDoc {
224         HttpServerSettings op = httpserverSettings ();
225
226         NbLogger logger = new NbLogger();
227         logger.setName("tc_log"); // NOI18N
228

229         final EmbededTomcat tc=new EmbededTomcat();
230         
231         File JavaDoc wd = FileUtil.toFile (
232                       Repository.getDefault ().getDefaultFileSystem().getRoot());
233         wd = new File JavaDoc(wd, "httpwork"); // NOI18N
234
tc.setWorkDir(wd.getAbsolutePath());
235         
236         // install interceptors which need to be initialized BEFORE the default server interceptors
237
NbLoaderInterceptor nbL =new NbLoaderInterceptor();
238     tc.addContextInterceptor( nbL );
239         
240         // hack - force initialization of default interceptors, so our interceptor is after them
241
tc.addApplicationAdapter(null);
242
243         // install interceptors which need to be initialized AFTER the default server interceptors
244
NbServletsInterceptor nbI =new NbServletsInterceptor();
245     tc.addContextInterceptor( nbI );
246
247         removeWebXmlReader (tc);
248         
249         ServletContext JavaDoc sctx;
250         sctx=tc.addContext("", wd.toURI().toURL()); // NOI18N
251
tc.initContext( sctx );
252         //ctxt.getServletLoader().setParentLoader(TopManager.getDefault().systemClassLoader());
253

254         tc.addEndpoint( op.getPort(), null, null);
255
256         final ContextManager cm = getContextManager(tc);
257         
258         reloader = new ContextReloader (tc, cm, sctx);
259         
260         // reduce number of threads
261
Enumeration JavaDoc e = cm.getConnectors ();
262         while (e.hasMoreElements ()) {
263             Object JavaDoc o = e.nextElement ();
264             if (o instanceof PoolTcpConnector) {
265                 org.apache.tomcat.core.ServerConnector conn = (PoolTcpConnector)o;
266                 conn.setAttribute (PoolTcpConnector.MIN_SPARE_THREADS, "0"); // NOI18N
267
conn.setAttribute (PoolTcpConnector.MAX_SPARE_THREADS, "1"); // NOI18N
268
conn.setAttribute (PoolTcpConnector.MAX_THREADS, "3"); // NOI18N
269
}
270         }
271         
272         return cm;
273         
274     }
275
276     private static class NbLogger extends TomcatLogger {
277         public NbLogger() {
278             super();
279         }
280
281         protected void realLog(String JavaDoc message) {
282         }
283
284         protected void realLog(String JavaDoc message, Throwable JavaDoc t) {
285         }
286     
287         public void flush() {
288         }
289     }
290
291     /**
292      * Obtains settings of this module
293      */

294     static HttpServerSettings httpserverSettings () {
295         return HttpServerSettings.getDefault();
296     }
297     
298     /** Listener for change of system class loader to reinitialize context
299      * running on HTTP server.
300      * The purpose is to force usage of up-to-date classes even in the case
301      * of module reloading.
302      */

303     private static class ContextReloader implements LookupListener, Runnable JavaDoc {
304         
305         private ServletContext JavaDoc ide_ctx;
306         
307         private EmbededTomcat tc;
308         
309         private ContextManager cm;
310
311     private Lookup.Result<ClassLoader JavaDoc> res;
312         
313         public ContextReloader (EmbededTomcat tc, ContextManager cm, ServletContext JavaDoc ctx) {
314             ide_ctx = ctx;
315             this.tc = tc;
316             this.cm = cm;
317         }
318         
319         /** Starts to listen on class loader changes */
320         public void activate () {
321             res = Lookup.getDefault().lookup(new Lookup.Template<ClassLoader JavaDoc> (ClassLoader JavaDoc.class));
322             res.addLookupListener (this);
323         }
324         
325         /** Stops listening. */
326         public void deactivate () {
327         if (res != null) {
328                 res.removeLookupListener (this);
329             res = null;
330         }
331         }
332         
333         public void resultChanged (LookupEvent evt) {
334             RequestProcessor.getDefault ().post (this);
335         }
336         
337         public void run () {
338         ClassLoader JavaDoc cl = (ClassLoader JavaDoc)res.allInstances ().iterator ().next ();
339             cm.setParentClassLoader (cl);
340             
341             File JavaDoc wd = FileUtil.toFile (
342                           Repository.getDefault ().getDefaultFileSystem().getRoot());
343             wd = new File JavaDoc(wd, "httpwork"); // NOI18N
344

345             Enumeration JavaDoc e = cm.getContexts ();
346             while (e.hasMoreElements ()) {
347                 Object JavaDoc o = e.nextElement ();
348                 if (o instanceof Context JavaDoc) {
349                     Context JavaDoc ctx = (Context JavaDoc)o;
350                     // PENDING why this is in loop?
351
tc.removeContext (ide_ctx);
352                     try {
353                         ide_ctx=tc.addContext ("", wd.toURI().toURL ()); // NOI18N
354
}
355                     catch (MalformedURLException JavaDoc ex) {
356                         // ErrorManager.getDefault ().log (ErrorManager.INFORMATIONAL, ex);
357
}
358                     tc.initContext ( ide_ctx );
359                 }
360             }
361             
362         }
363         
364     }
365 }
366
367
Popular Tags