KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > manager > ManagerServlet


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

17
18
19 package org.apache.catalina.manager;
20
21
22 import java.io.BufferedOutputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 import javax.management.MBeanServer JavaDoc;
31 import javax.management.ObjectName JavaDoc;
32 import javax.naming.Binding JavaDoc;
33 import javax.naming.InitialContext JavaDoc;
34 import javax.naming.NamingEnumeration JavaDoc;
35 import javax.naming.NamingException JavaDoc;
36 import javax.servlet.ServletException JavaDoc;
37 import javax.servlet.ServletInputStream JavaDoc;
38 import javax.servlet.UnavailableException JavaDoc;
39 import javax.servlet.http.HttpServlet JavaDoc;
40 import javax.servlet.http.HttpServletRequest JavaDoc;
41 import javax.servlet.http.HttpServletResponse JavaDoc;
42
43 import org.apache.catalina.Container;
44 import org.apache.catalina.ContainerServlet;
45 import org.apache.catalina.Context;
46 import org.apache.catalina.Engine;
47 import org.apache.catalina.Globals;
48 import org.apache.catalina.Host;
49 import org.apache.catalina.Lifecycle;
50 import org.apache.catalina.Role;
51 import org.apache.catalina.Server;
52 import org.apache.catalina.ServerFactory;
53 import org.apache.catalina.Session;
54 import org.apache.catalina.UserDatabase;
55 import org.apache.catalina.Wrapper;
56 import org.apache.catalina.core.StandardServer;
57 import org.apache.catalina.util.RequestUtil;
58 import org.apache.catalina.util.ServerInfo;
59 import org.apache.catalina.util.StringManager;
60 import org.apache.tomcat.util.modeler.Registry;
61
62
63 /**
64  * Servlet that enables remote management of the web applications installed
65  * within the same virtual host as this web application is. Normally, this
66  * functionality will be protected by a security constraint in the web
67  * application deployment descriptor. However, this requirement can be
68  * relaxed during testing.
69  * <p>
70  * This servlet examines the value returned by <code>getPathInfo()</code>
71  * and related query parameters to determine what action is being requested.
72  * The following actions and parameters (starting after the servlet path)
73  * are supported:
74  * <ul>
75  * <li><b>/deploy?config={config-url}</b> - Install and start a new
76  * web application, based on the contents of the context configuration
77  * file found at the specified URL. The <code>docBase</code> attribute
78  * of the context configuration file is used to locate the actual
79  * WAR or directory containing the application.</li>
80  * <li><b>/deploy?config={config-url}&war={war-url}/</b> - Install and start
81  * a new web application, based on the contents of the context
82  * configuration file found at <code>{config-url}</code>, overriding the
83  * <code>docBase</code> attribute with the contents of the web
84  * application archive found at <code>{war-url}</code>.</li>
85  * <li><b>/deploy?path=/xxx&war={war-url}</b> - Install and start a new
86  * web application attached to context path <code>/xxx</code>, based
87  * on the contents of the web application archive found at the
88  * specified URL.</li>
89  * <li><b>/list</b> - List the context paths of all currently installed web
90  * applications for this virtual host. Each context will be listed with
91  * the following format <code>path:status:sessions</code>.
92  * Where path is the context path. Status is either running or stopped.
93  * Sessions is the number of active Sessions.</li>
94  * <li><b>/reload?path=/xxx</b> - Reload the Java classes and resources for
95  * the application at the specified path.</li>
96  * <li><b>/resources?type=xxxx</b> - Enumerate the available global JNDI
97  * resources, optionally limited to those of the specified type
98  * (fully qualified Java class name), if available.</li>
99  * <li><b>/roles</b> - Enumerate the available security role names and
100  * descriptions from the user database connected to the <code>users</code>
101  * resource reference.
102  * <li><b>/serverinfo</b> - Display system OS and JVM properties.
103  * <li><b>/sessions?path=/xxx</b> - List session information about the web
104  * application attached to context path <code>/xxx</code> for this
105  * virtual host.</li>
106  * <li><b>/start?path=/xxx</b> - Start the web application attached to
107  * context path <code>/xxx</code> for this virtual host.</li>
108  * <li><b>/stop?path=/xxx</b> - Stop the web application attached to
109  * context path <code>/xxx</code> for this virtual host.</li>
110  * <li><b>/undeploy?path=/xxx</b> - Shutdown and remove the web application
111  * attached to context path <code>/xxx</code> for this virtual host,
112  * and remove the underlying WAR file or document base directory.
113  * (<em>NOTE</em> - This is only allowed if the WAR file or document
114  * base is stored in the <code>appBase</code> directory of this host,
115  * typically as a result of being placed there via the <code>/deploy</code>
116  * command.</li>
117  * </ul>
118  * <p>Use <code>path=/</code> for the ROOT context.</p>
119  * <p>The syntax of the URL for a web application archive must conform to one
120  * of the following patterns to be successfully deployed:</p>
121  * <ul>
122  * <li><b>file:/absolute/path/to/a/directory</b> - You can specify the absolute
123  * path of a directory that contains the unpacked version of a web
124  * application. This directory will be attached to the context path you
125  * specify without any changes.</li>
126  * <li><b>jar:file:/absolute/path/to/a/warfile.war!/</b> - You can specify a
127  * URL to a local web application archive file. The syntax must conform to
128  * the rules specified by the <code>JarURLConnection</code> class for a
129  * reference to an entire JAR file.</li>
130  * <li><b>jar:http://hostname:port/path/to/a/warfile.war!/</b> - You can specify
131  * a URL to a remote (HTTP-accessible) web application archive file. The
132  * syntax must conform to the rules specified by the
133  * <code>JarURLConnection</code> class for a reference to an entire
134  * JAR file.</li>
135  * </ul>
136  * <p>
137  * <b>NOTE</b> - Attempting to reload or remove the application containing
138  * this servlet itself will not succeed. Therefore, this servlet should
139  * generally be deployed as a separate web application within the virtual host
140  * to be managed.
141  * <p>
142  * <b>NOTE</b> - For security reasons, this application will not operate
143  * when accessed via the invoker servlet. You must explicitly map this servlet
144  * with a servlet mapping, and you will always want to protect it with
145  * appropriate security constraints as well.
146  * <p>
147  * The following servlet initialization parameters are recognized:
148  * <ul>
149  * <li><b>debug</b> - The debugging detail level that controls the amount
150  * of information that is logged by this servlet. Default is zero.
151  * </ul>
152  *
153  * @author Craig R. McClanahan
154  * @author Remy Maucherat
155  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
156  */

157
158 public class ManagerServlet
159     extends HttpServlet JavaDoc implements ContainerServlet {
160
161
162     // ----------------------------------------------------- Instance Variables
163

164
165     /**
166      * Path where context descriptors should be deployed.
167      */

168     protected File JavaDoc configBase = null;
169
170
171     /**
172      * The Context container associated with our web application.
173      */

174     protected Context JavaDoc context = null;
175
176
177     /**
178      * The debugging detail level for this servlet.
179      */

180     protected int debug = 1;
181
182
183     /**
184      * File object representing the directory into which the deploy() command
185      * will store the WAR and context configuration files that have been
186      * uploaded.
187      */

188     protected File JavaDoc deployed = null;
189
190
191     /**
192      * Path used to store revisions of webapps.
193      */

194     protected File JavaDoc versioned = null;
195
196
197     /**
198      * Path used to store context descriptors.
199      */

200     protected File JavaDoc contextDescriptors = null;
201
202
203     /**
204      * The associated host.
205      */

206     protected Host host = null;
207
208     
209     /**
210      * The host appBase.
211      */

212     protected File JavaDoc appBase = null;
213     
214     
215     /**
216      * MBean server.
217      */

218     protected MBeanServer JavaDoc mBeanServer = null;
219
220
221     /**
222      * The associated deployer ObjectName.
223      */

224     protected ObjectName JavaDoc oname = null;
225     
226
227     /**
228      * The global JNDI <code>NamingContext</code> for this server,
229      * if available.
230      */

231     protected javax.naming.Context JavaDoc global = null;
232
233
234     /**
235      * The string manager for this package.
236      */

237     protected static StringManager sm =
238         StringManager.getManager(Constants.Package);
239
240
241     /**
242      * The Wrapper container associated with this servlet.
243      */

244     protected Wrapper wrapper = null;
245
246
247     // ----------------------------------------------- ContainerServlet Methods
248

249
250     /**
251      * Return the Wrapper with which we are associated.
252      */

253     public Wrapper getWrapper() {
254
255         return (this.wrapper);
256
257     }
258
259
260     /**
261      * Set the Wrapper with which we are associated.
262      *
263      * @param wrapper The new wrapper
264      */

265     public void setWrapper(Wrapper wrapper) {
266
267         this.wrapper = wrapper;
268         if (wrapper == null) {
269             context = null;
270             host = null;
271             oname = null;
272         } else {
273             context = (Context JavaDoc) wrapper.getParent();
274             host = (Host) context.getParent();
275             Engine engine = (Engine) host.getParent();
276             try {
277                 oname = new ObjectName JavaDoc(engine.getName()
278                         + ":type=Deployer,host=" + host.getName());
279             } catch (Exception JavaDoc e) {
280                 // ?
281
}
282         }
283
284         // Retrieve the MBean server
285
mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
286         
287     }
288
289
290     // --------------------------------------------------------- Public Methods
291

292
293     /**
294      * Finalize this servlet.
295      */

296     public void destroy() {
297
298         ; // No actions necessary
299

300     }
301
302
303     /**
304      * Process a GET request for the specified resource.
305      *
306      * @param request The servlet request we are processing
307      * @param response The servlet response we are creating
308      *
309      * @exception IOException if an input/output error occurs
310      * @exception ServletException if a servlet-specified error occurs
311      */

312     public void doGet(HttpServletRequest JavaDoc request,
313                       HttpServletResponse JavaDoc response)
314         throws IOException JavaDoc, ServletException JavaDoc {
315
316         // Verify that we were not accessed using the invoker servlet
317
if (request.getAttribute(Globals.INVOKED_ATTR) != null)
318             throw new UnavailableException JavaDoc
319                 (sm.getString("managerServlet.cannotInvoke"));
320
321         // Identify the request parameters that we need
322
String JavaDoc command = request.getPathInfo();
323         if (command == null)
324             command = request.getServletPath();
325         String JavaDoc config = request.getParameter("config");
326         String JavaDoc path = request.getParameter("path");
327         String JavaDoc type = request.getParameter("type");
328         String JavaDoc war = request.getParameter("war");
329         String JavaDoc tag = request.getParameter("tag");
330         boolean update = false;
331         if ((request.getParameter("update") != null)
332             && (request.getParameter("update").equals("true"))) {
333             update = true;
334         }
335
336         // Prepare our output writer to generate the response message
337
response.setContentType("text/plain; charset=" + Constants.CHARSET);
338         PrintWriter JavaDoc writer = response.getWriter();
339
340         // Process the requested command (note - "/deploy" is not listed here)
341
if (command == null) {
342             writer.println(sm.getString("managerServlet.noCommand"));
343         } else if (command.equals("/deploy")) {
344             if (war != null || config != null) {
345                 deploy(writer, config, path, war, update);
346             } else {
347                 deploy(writer, path, tag);
348             }
349         } else if (command.equals("/install")) {
350             // Deprecated
351
deploy(writer, config, path, war, false);
352         } else if (command.equals("/list")) {
353             list(writer);
354         } else if (command.equals("/reload")) {
355             reload(writer, path);
356         } else if (command.equals("/remove")) {
357             // Deprecated
358
undeploy(writer, path);
359         } else if (command.equals("/resources")) {
360             resources(writer, type);
361         } else if (command.equals("/roles")) {
362             roles(writer);
363         } else if (command.equals("/save")) {
364             save(writer, path);
365         } else if (command.equals("/serverinfo")) {
366             serverinfo(writer);
367         } else if (command.equals("/sessions")) {
368             sessions(writer, path);
369         } else if (command.equals("/start")) {
370             start(writer, path);
371         } else if (command.equals("/stop")) {
372             stop(writer, path);
373         } else if (command.equals("/undeploy")) {
374             undeploy(writer, path);
375         } else {
376             writer.println(sm.getString("managerServlet.unknownCommand",
377                                         command));
378         }
379
380         // Finish up the response
381
writer.flush();
382         writer.close();
383
384     }
385
386
387     /**
388      * Process a PUT request for the specified resource.
389      *
390      * @param request The servlet request we are processing
391      * @param response The servlet response we are creating
392      *
393      * @exception IOException if an input/output error occurs
394      * @exception ServletException if a servlet-specified error occurs
395      */

396     public void doPut(HttpServletRequest JavaDoc request,
397                       HttpServletResponse JavaDoc response)
398         throws IOException JavaDoc, ServletException JavaDoc {
399
400         // Verify that we were not accessed using the invoker servlet
401
if (request.getAttribute(Globals.INVOKED_ATTR) != null)
402             throw new UnavailableException JavaDoc
403                 (sm.getString("managerServlet.cannotInvoke"));
404
405         // Identify the request parameters that we need
406
String JavaDoc command = request.getPathInfo();
407         if (command == null)
408             command = request.getServletPath();
409         String JavaDoc path = request.getParameter("path");
410         String JavaDoc tag = request.getParameter("tag");
411         boolean update = false;
412         if ((request.getParameter("update") != null)
413             && (request.getParameter("update").equals("true"))) {
414             update = true;
415         }
416
417         // Prepare our output writer to generate the response message
418
response.setContentType("text/plain;charset="+Constants.CHARSET);
419         PrintWriter JavaDoc writer = response.getWriter();
420
421         // Process the requested command
422
if (command == null) {
423             writer.println(sm.getString("managerServlet.noCommand"));
424         } else if (command.equals("/deploy")) {
425             deploy(writer, path, tag, update, request);
426         } else {
427             writer.println(sm.getString("managerServlet.unknownCommand",
428                                         command));
429         }
430
431         // Finish up the response
432
writer.flush();
433         writer.close();
434
435     }
436
437
438     /**
439      * Initialize this servlet.
440      */

441     public void init() throws ServletException JavaDoc {
442
443         // Ensure that our ContainerServlet properties have been set
444
if ((wrapper == null) || (context == null))
445             throw new UnavailableException JavaDoc
446                 (sm.getString("managerServlet.noWrapper"));
447
448         // Verify that we were not accessed using the invoker servlet
449
String JavaDoc servletName = getServletConfig().getServletName();
450         if (servletName == null)
451             servletName = "";
452         if (servletName.startsWith("org.apache.catalina.INVOKER."))
453             throw new UnavailableException JavaDoc
454                 (sm.getString("managerServlet.cannotInvoke"));
455
456         // Set our properties from the initialization parameters
457
String JavaDoc value = null;
458         try {
459             value = getServletConfig().getInitParameter("debug");
460             debug = Integer.parseInt(value);
461         } catch (Throwable JavaDoc t) {
462             ;
463         }
464
465         // Acquire global JNDI resources if available
466
Server JavaDoc server = ServerFactory.getServer();
467         if ((server != null) && (server instanceof StandardServer)) {
468             global = ((StandardServer) server).getGlobalNamingContext();
469         }
470
471         // Calculate the directory into which we will be deploying applications
472
versioned = (File JavaDoc) getServletContext().getAttribute
473             ("javax.servlet.context.tempdir");
474
475         // Identify the appBase of the owning Host of this Context
476
// (if any)
477
String JavaDoc appBase = ((Host) context.getParent()).getAppBase();
478         deployed = new File JavaDoc(appBase);
479         if (!deployed.isAbsolute()) {
480             deployed = new File JavaDoc(System.getProperty("catalina.base"),
481                                 appBase);
482         }
483         configBase = new File JavaDoc(System.getProperty("catalina.base"), "conf");
484         Container container = context;
485         Container host = null;
486         Container engine = null;
487         while (container != null) {
488             if (container instanceof Host)
489                 host = container;
490             if (container instanceof Engine)
491                 engine = container;
492             container = container.getParent();
493         }
494         if (engine != null) {
495             configBase = new File JavaDoc(configBase, engine.getName());
496         }
497         if (host != null) {
498             configBase = new File JavaDoc(configBase, host.getName());
499         }
500         // Note: The directory must exist for this to work.
501

502         // Log debugging messages as necessary
503
if (debug >= 1) {
504             log("init: Associated with Deployer '" +
505                 oname + "'");
506             if (global != null) {
507                 log("init: Global resources are available");
508             }
509         }
510
511     }
512
513
514
515     // -------------------------------------------------------- Private Methods
516

517
518     /**
519      * Store server configuration.
520      *
521      * @param path Optional context path to save
522      */

523     protected synchronized void save(PrintWriter JavaDoc writer, String JavaDoc path) {
524
525         Server JavaDoc server = ServerFactory.getServer();
526
527         if (!(server instanceof StandardServer)) {
528             writer.println(sm.getString("managerServlet.saveFail", server));
529             return;
530         }
531
532         if ((path == null) || path.length() == 0 || !path.startsWith("/")) {
533             try {
534                 ((StandardServer) server).storeConfig();
535                 writer.println(sm.getString("managerServlet.saved"));
536             } catch (Exception JavaDoc e) {
537                 log("managerServlet.storeConfig", e);
538                 writer.println(sm.getString("managerServlet.exception",
539                                             e.toString()));
540                 return;
541             }
542         } else {
543             String JavaDoc contextPath = path;
544             if (path.equals("/")) {
545                 contextPath = "";
546             }
547             Context JavaDoc context = (Context JavaDoc) host.findChild(contextPath);
548             if (context == null) {
549                 writer.println(sm.getString("managerServlet.noContext", path));
550                 return;
551             }
552             try {
553                 ((StandardServer) server).storeContext(context);
554                 writer.println(sm.getString("managerServlet.savedContext",
555                                path));
556             } catch (Exception JavaDoc e) {
557                 log("managerServlet.save[" + path + "]", e);
558                 writer.println(sm.getString("managerServlet.exception",
559                                             e.toString()));
560                 return;
561             }
562         }
563
564     }
565
566
567     /**
568      * Deploy a web application archive (included in the current request)
569      * at the specified context path.
570      *
571      * @param writer Writer to render results to
572      * @param path Context path of the application to be installed
573      * @param tag Tag to be associated with the webapp
574      * @param request Servlet request we are processing
575      */

576     protected synchronized void deploy
577         (PrintWriter JavaDoc writer, String JavaDoc path,
578          String JavaDoc tag, boolean update, HttpServletRequest JavaDoc request) {
579
580         if (debug >= 1) {
581             log("deploy: Deploying web application at '" + path + "'");
582         }
583
584         // Validate the requested context path
585
if ((path == null) || path.length() == 0 || !path.startsWith("/")) {
586             writer.println(sm.getString("managerServlet.invalidPath", path));
587             return;
588         }
589         String JavaDoc displayPath = path;
590         if( path.equals("/") )
591             path = "";
592         String JavaDoc basename = getDocBase(path);
593
594         // Check if app already exists, or undeploy it if updating
595
Context JavaDoc context = (Context JavaDoc) host.findChild(path);
596         if (update) {
597             if (context != null) {
598                 undeploy(writer, displayPath);
599             }
600             context = (Context JavaDoc) host.findChild(path);
601         }
602         if (context != null) {
603             writer.println
604                 (sm.getString("managerServlet.alreadyContext",
605                               displayPath));
606             return;
607         }
608
609         // Calculate the base path
610
File JavaDoc deployedPath = deployed;
611         if (tag != null) {
612             deployedPath = new File JavaDoc(versioned, tag);
613             deployedPath.mkdirs();
614         }
615
616         // Upload the web application archive to a local WAR file
617
File JavaDoc localWar = new File JavaDoc(deployedPath, basename + ".war");
618         if (debug >= 2) {
619             log("Uploading WAR file to " + localWar);
620         }
621
622         // Copy WAR to appBase
623
try {
624             if (!isServiced(path)) {
625                 addServiced(path);
626                 try {
627                     // Upload WAR
628
uploadWar(request, localWar);
629                     // Copy WAR and XML to the host app base if needed
630
if (tag != null) {
631                         deployedPath = deployed;
632                         File JavaDoc localWarCopy = new File JavaDoc(deployedPath, basename + ".war");
633                         copy(localWar, localWarCopy);
634                         localWar = localWarCopy;
635                         copy(localWar, new File JavaDoc(getAppBase(), basename + ".war"));
636                     }
637                     // Perform new deployment
638
check(path);
639                 } finally {
640                     removeServiced(path);
641                 }
642             }
643         } catch (Exception JavaDoc e) {
644             log("managerServlet.check[" + displayPath + "]", e);
645             writer.println(sm.getString("managerServlet.exception",
646                                         e.toString()));
647             return;
648         }
649         
650         context = (Context JavaDoc) host.findChild(path);
651         if (context != null && context.getConfigured()) {
652             writer.println(sm.getString("managerServlet.deployed", displayPath));
653         } else {
654             // Something failed
655
writer.println(sm.getString("managerServlet.deployFailed", displayPath));
656         }
657         
658     }
659
660
661     /**
662      * Install an application for the specified path from the specified
663      * web application archive.
664      *
665      * @param writer Writer to render results to
666      * @param tag Revision tag to deploy from
667      * @param path Context path of the application to be installed
668      */

669     protected void deploy(PrintWriter JavaDoc writer, String JavaDoc path, String JavaDoc tag) {
670
671         // Validate the requested context path
672
if ((path == null) || path.length() == 0 || !path.startsWith("/")) {
673             writer.println(sm.getString("managerServlet.invalidPath", path));
674             return;
675         }
676         String JavaDoc displayPath = path;
677         if( path.equals("/") )
678             path = "";
679
680         // Calculate the base path
681
File JavaDoc deployedPath = versioned;
682         if (tag != null) {
683             deployedPath = new File JavaDoc(deployedPath, tag);
684         }
685
686         // Find the local WAR file
687
File JavaDoc localWar = new File JavaDoc(deployedPath, getDocBase(path) + ".war");
688         // Find the local context deployment file (if any)
689
File JavaDoc localXml = new File JavaDoc(configBase, getConfigFile(path) + ".xml");
690
691         // Check if app already exists, or undeploy it if updating
692
Context JavaDoc context = (Context JavaDoc) host.findChild(path);
693         if (context != null) {
694             undeploy(writer, displayPath);
695         }
696
697         // Copy WAR to appBase
698
try {
699             if (!isServiced(path)) {
700                 addServiced(path);
701                 try {
702                     copy(localWar, new File JavaDoc(getAppBase(), getDocBase(path) + ".war"));
703                     // Perform new deployment
704
check(path);
705                 } finally {
706                     removeServiced(path);
707                 }
708             }
709         } catch (Exception JavaDoc e) {
710             log("managerServlet.check[" + displayPath + "]", e);
711             writer.println(sm.getString("managerServlet.exception",
712                                         e.toString()));
713             return;
714         }
715         
716         context = (Context JavaDoc) host.findChild(path);
717         if (context != null && context.getConfigured()) {
718             writer.println(sm.getString("managerServlet.deployed", displayPath));
719         } else {
720             // Something failed
721
writer.println(sm.getString("managerServlet.deployFailed", displayPath));
722         }
723         
724     }
725
726
727     /**
728      * Install an application for the specified path from the specified
729      * web application archive.
730      *
731      * @param writer Writer to render results to
732      * @param config URL of the context configuration file to be installed
733      * @param path Context path of the application to be installed
734      * @param war URL of the web application archive to be installed
735      * @param update true to override any existing webapp on the path
736      */

737     protected void deploy(PrintWriter JavaDoc writer, String JavaDoc config,
738             String JavaDoc path, String JavaDoc war, boolean update) {
739         
740         if (config != null && config.length() == 0) {
741             config = null;
742         }
743         if (war != null && war.length() == 0) {
744             war = null;
745         }
746         
747         if (debug >= 1) {
748             if (config != null && config.length() > 0) {
749                 if (war != null) {
750                     log("install: Installing context configuration at '" +
751                             config + "' from '" + war + "'");
752                 } else {
753                     log("install: Installing context configuration at '" +
754                             config + "'");
755                 }
756             } else {
757                 if (path != null && path.length() > 0) {
758                     log("install: Installing web application at '" + path +
759                             "' from '" + war + "'");
760                 } else {
761                     log("install: Installing web application from '" + war + "'");
762                 }
763             }
764         }
765         
766         if (path == null || path.length() == 0 || !path.startsWith("/")) {
767             writer.println(sm.getString("managerServlet.invalidPath",
768                                         RequestUtil.filter(path)));
769             return;
770         }
771         String JavaDoc displayPath = path;
772         if("/".equals(path)) {
773             path = "";
774         }
775         
776         // Check if app already exists, or undeploy it if updating
777
Context JavaDoc context = (Context JavaDoc) host.findChild(path);
778         if (update) {
779             if (context != null) {
780                 undeploy(writer, displayPath);
781             }
782             context = (Context JavaDoc) host.findChild(path);
783         }
784         if (context != null) {
785             writer.println
786             (sm.getString("managerServlet.alreadyContext",
787                     displayPath));
788             return;
789         }
790         
791         if (config != null && (config.startsWith("file:"))) {
792             config = config.substring("file:".length());
793         }
794         if (war != null && (war.startsWith("file:"))) {
795             war = war.substring("file:".length());
796         }
797         
798         try {
799             if (!isServiced(path)) {
800                 addServiced(path);
801                 try {
802                     if (config != null) {
803                         copy(new File JavaDoc(config),
804                                 new File JavaDoc(configBase, getConfigFile(path) + ".xml"));
805                     }
806                     if (war != null) {
807                         if (war.endsWith(".war")) {
808                             copy(new File JavaDoc(war),
809                                     new File JavaDoc(getAppBase(), getDocBase(path) + ".war"));
810                         } else {
811                             copy(new File JavaDoc(war),
812                                     new File JavaDoc(getAppBase(), getDocBase(path)));
813                         }
814                     }
815                     // Perform new deployment
816
check(path);
817                 } finally {
818                     removeServiced(path);
819                 }
820             }
821             context = (Context JavaDoc) host.findChild(path);
822             if (context != null && context.getConfigured()) {
823                 writer.println(sm.getString("managerServlet.deployed", displayPath));
824             } else {
825                 // Something failed
826
writer.println(sm.getString("managerServlet.deployFailed", displayPath));
827             }
828         } catch (Throwable JavaDoc t) {
829             log("ManagerServlet.install[" + displayPath + "]", t);
830             writer.println(sm.getString("managerServlet.exception",
831                     t.toString()));
832         }
833         
834     }
835
836
837     /**
838      * Render a list of the currently active Contexts in our virtual host.
839      *
840      * @param writer Writer to render to
841      */

842     protected void list(PrintWriter JavaDoc writer) {
843
844         if (debug >= 1)
845             log("list: Listing contexts for virtual host '" +
846                 host.getName() + "'");
847
848         writer.println(sm.getString("managerServlet.listed",
849                                     host.getName()));
850         Container[] contexts = host.findChildren();
851         for (int i = 0; i < contexts.length; i++) {
852             Context JavaDoc context = (Context JavaDoc) contexts[i];
853             String JavaDoc displayPath = context.getPath();
854             if( displayPath.equals("") )
855                 displayPath = "/";
856             if (context != null ) {
857                 if (context.getAvailable()) {
858                     writer.println(sm.getString("managerServlet.listitem",
859                                                 displayPath,
860                                                 "running",
861                                       "" + context.getManager().findSessions().length,
862                                                 context.getDocBase()));
863                 } else {
864                     writer.println(sm.getString("managerServlet.listitem",
865                                                 displayPath,
866                                                 "stopped",
867                                                 "0",
868                                                 context.getDocBase()));
869                 }
870             }
871         }
872     }
873
874
875     /**
876      * Reload the web application at the specified context path.
877      *
878      * @param writer Writer to render to
879      * @param path Context path of the application to be restarted
880      */

881     protected void reload(PrintWriter JavaDoc writer, String JavaDoc path) {
882
883         if (debug >= 1)
884             log("restart: Reloading web application at '" + path + "'");
885
886         if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
887             writer.println(sm.getString("managerServlet.invalidPath",
888                                         RequestUtil.filter(path)));
889             return;
890         }
891         String JavaDoc displayPath = path;
892         if( path.equals("/") )
893             path = "";
894
895         try {
896             Context JavaDoc context = (Context JavaDoc) host.findChild(path);
897             if (context == null) {
898                 writer.println(sm.getString
899                                ("managerServlet.noContext",
900                                    RequestUtil.filter(displayPath)));
901                 return;
902             }
903             // It isn't possible for the manager to reload itself
904
if (context.getPath().equals(this.context.getPath())) {
905                 writer.println(sm.getString("managerServlet.noSelf"));
906                 return;
907             }
908             context.reload();
909             writer.println
910                 (sm.getString("managerServlet.reloaded", displayPath));
911         } catch (Throwable JavaDoc t) {
912             log("ManagerServlet.reload[" + displayPath + "]", t);
913             writer.println(sm.getString("managerServlet.exception",
914                                         t.toString()));
915         }
916
917     }
918
919
920     /**
921      * Render a list of available global JNDI resources.
922      *
923      * @param type Fully qualified class name of the resource type of interest,
924      * or <code>null</code> to list resources of all types
925      */

926     protected void resources(PrintWriter JavaDoc writer, String JavaDoc type) {
927
928         if (debug >= 1) {
929             if (type != null) {
930                 log("resources: Listing resources of type " + type);
931             } else {
932                 log("resources: Listing resources of all types");
933             }
934         }
935
936         // Is the global JNDI resources context available?
937
if (global == null) {
938             writer.println(sm.getString("managerServlet.noGlobal"));
939             return;
940         }
941
942         // Enumerate the global JNDI resources of the requested type
943
if (type != null) {
944             writer.println(sm.getString("managerServlet.resourcesType",
945                                         type));
946         } else {
947             writer.println(sm.getString("managerServlet.resourcesAll"));
948         }
949
950         Class JavaDoc clazz = null;
951         try {
952             if (type != null) {
953                 clazz = Class.forName(type);
954             }
955         } catch (Throwable JavaDoc t) {
956             log("ManagerServlet.resources[" + type + "]", t);
957             writer.println(sm.getString("managerServlet.exception",
958                                         t.toString()));
959             return;
960         }
961
962         printResources(writer, "", global, type, clazz);
963
964     }
965
966
967     /**
968      * List the resources of the given context.
969      */

970     protected void printResources(PrintWriter JavaDoc writer, String JavaDoc prefix,
971                                   javax.naming.Context JavaDoc namingContext,
972                                   String JavaDoc type, Class JavaDoc clazz) {
973
974         try {
975             NamingEnumeration JavaDoc items = namingContext.listBindings("");
976             while (items.hasMore()) {
977                 Binding JavaDoc item = (Binding JavaDoc) items.next();
978                 if (item.getObject() instanceof javax.naming.Context JavaDoc) {
979                     printResources
980                         (writer, prefix + item.getName() + "/",
981                          (javax.naming.Context JavaDoc) item.getObject(), type, clazz);
982                 } else {
983                     if ((clazz != null) &&
984                         (!(clazz.isInstance(item.getObject())))) {
985                         continue;
986                     }
987                     writer.print(prefix + item.getName());
988                     writer.print(':');
989                     writer.print(item.getClassName());
990                     // Do we want a description if available?
991
writer.println();
992                 }
993             }
994         } catch (Throwable JavaDoc t) {
995             log("ManagerServlet.resources[" + type + "]", t);
996             writer.println(sm.getString("managerServlet.exception",
997                                         t.toString()));
998         }
999
1000    }
1001
1002
1003    /**
1004     * Render a list of security role names (and corresponding descriptions)
1005     * from the <code>org.apache.catalina.UserDatabase</code> resource that is
1006     * connected to the <code>users</code> resource reference. Typically, this
1007     * will be the global user database, but can be adjusted if you have
1008     * different user databases for different virtual hosts.
1009     *
1010     * @param writer Writer to render to
1011     */

1012    protected void roles(PrintWriter JavaDoc writer) {
1013
1014        if (debug >= 1) {
1015            log("roles: List security roles from user database");
1016        }
1017
1018        // Look up the UserDatabase instance we should use
1019
UserDatabase database = null;
1020        try {
1021            InitialContext JavaDoc ic = new InitialContext JavaDoc();
1022            database = (UserDatabase) ic.lookup("java:comp/env/users");
1023        } catch (NamingException JavaDoc e) {
1024            writer.println(sm.getString("managerServlet.userDatabaseError"));
1025            log("java:comp/env/users", e);
1026            return;
1027        }
1028        if (database == null) {
1029            writer.println(sm.getString("managerServlet.userDatabaseMissing"));
1030            return;
1031        }
1032
1033        // Enumerate the available roles
1034
writer.println(sm.getString("managerServlet.rolesList"));
1035        Iterator JavaDoc roles = database.getRoles();
1036        if (roles != null) {
1037            while (roles.hasNext()) {
1038                Role role = (Role) roles.next();
1039                writer.print(role.getRolename());
1040                writer.print(':');
1041                if (role.getDescription() != null) {
1042                    writer.print(role.getDescription());
1043                }
1044                writer.println();
1045            }
1046        }
1047
1048
1049    }
1050
1051
1052    /**
1053     * Writes System OS and JVM properties.
1054     * @param writer Writer to render to
1055     */

1056    protected void serverinfo(PrintWriter JavaDoc writer) {
1057        if (debug >= 1)
1058            log("serverinfo");
1059        try {
1060            StringBuffer JavaDoc props = new StringBuffer JavaDoc();
1061            props.append("OK - Server info");
1062            props.append("\nTomcat Version: ");
1063            props.append(ServerInfo.getServerInfo());
1064            props.append("\nOS Name: ");
1065            props.append(System.getProperty("os.name"));
1066            props.append("\nOS Version: ");
1067            props.append(System.getProperty("os.version"));
1068            props.append("\nOS Architecture: ");
1069            props.append(System.getProperty("os.arch"));
1070            props.append("\nJVM Version: ");
1071            props.append(System.getProperty("java.runtime.version"));
1072            props.append("\nJVM Vendor: ");
1073            props.append(System.getProperty("java.vm.vendor"));
1074            writer.println(props.toString());
1075        } catch (Throwable JavaDoc t) {
1076            getServletContext().log("ManagerServlet.serverinfo",t);
1077            writer.println(sm.getString("managerServlet.exception",
1078                                        t.toString()));
1079        }
1080    }
1081
1082    /**
1083     * Session information for the web application at the specified context path.
1084     * Displays a profile of session MaxInactiveInterval timeouts listing number
1085     * of sessions for each 10 minute timeout interval up to 10 hours.
1086     *
1087     * @param writer Writer to render to
1088     * @param path Context path of the application to list session information for
1089     */

1090    protected void sessions(PrintWriter JavaDoc writer, String JavaDoc path) {
1091
1092        if (debug >= 1)
1093            log("sessions: Session information for web application at '" + path + "'");
1094
1095        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
1096            writer.println(sm.getString("managerServlet.invalidPath",
1097                                        RequestUtil.filter(path)));
1098            return;
1099        }
1100        String JavaDoc displayPath = path;
1101        if( path.equals("/") )
1102            path = "";
1103        try {
1104            Context JavaDoc context = (Context JavaDoc) host.findChild(path);
1105            if (context == null) {
1106                writer.println(sm.getString("managerServlet.noContext",
1107                                            RequestUtil.filter(displayPath)));
1108                return;
1109            }
1110            writer.println(sm.getString("managerServlet.sessions", displayPath));
1111            writer.println(sm.getString("managerServlet.sessiondefaultmax",
1112                                "" + context.getManager().getMaxInactiveInterval()/60));
1113            Session [] sessions = context.getManager().findSessions();
1114            int [] timeout = new int[60];
1115            int notimeout = 0;
1116            for (int i = 0; i < sessions.length; i++) {
1117                int time = sessions[i].getMaxInactiveInterval()/(10*60);
1118                if (time < 0)
1119                    notimeout++;
1120                else if (time >= timeout.length)
1121                    timeout[timeout.length-1]++;
1122                else
1123                    timeout[time]++;
1124            }
1125            if (timeout[0] > 0)
1126                writer.println(sm.getString("managerServlet.sessiontimeout",
1127                                            "<10", "" + timeout[0]));
1128            for (int i = 1; i < timeout.length-1; i++) {
1129                if (timeout[i] > 0)
1130                    writer.println(sm.getString("managerServlet.sessiontimeout",
1131                                     "" + (i)*10 + " - <" + (i+1)*10,
1132                                                "" + timeout[i]));
1133            }
1134            if (timeout[timeout.length-1] > 0)
1135                writer.println(sm.getString("managerServlet.sessiontimeout",
1136                                            ">=" + timeout.length*10,
1137                                            "" + timeout[timeout.length-1]));
1138            if (notimeout > 0)
1139                writer.println(sm.getString("managerServlet.sessiontimeout",
1140                                            "unlimited","" + notimeout));
1141        } catch (Throwable JavaDoc t) {
1142            log("ManagerServlet.sessions[" + displayPath + "]", t);
1143            writer.println(sm.getString("managerServlet.exception",
1144                                        t.toString()));
1145        }
1146
1147    }
1148
1149
1150    /**
1151     * Start the web application at the specified context path.
1152     *
1153     * @param writer Writer to render to
1154     * @param path Context path of the application to be started
1155     */

1156    protected void start(PrintWriter JavaDoc writer, String JavaDoc path) {
1157
1158        if (debug >= 1)
1159            log("start: Starting web application at '" + path + "'");
1160
1161        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
1162            writer.println(sm.getString("managerServlet.invalidPath",
1163                                        RequestUtil.filter(path)));
1164            return;
1165        }
1166        String JavaDoc displayPath = path;
1167        if( path.equals("/") )
1168            path = "";
1169
1170        try {
1171            Context JavaDoc context = (Context JavaDoc) host.findChild(path);
1172            if (context == null) {
1173                writer.println(sm.getString("managerServlet.noContext",
1174                                            RequestUtil.filter(displayPath)));
1175                return;
1176            }
1177            ((Lifecycle) context).start();
1178            if (context.getAvailable())
1179                writer.println
1180                    (sm.getString("managerServlet.started", displayPath));
1181            else
1182                writer.println
1183                    (sm.getString("managerServlet.startFailed", displayPath));
1184        } catch (Throwable JavaDoc t) {
1185            getServletContext().log
1186                (sm.getString("managerServlet.startFailed", displayPath), t);
1187            writer.println
1188                (sm.getString("managerServlet.startFailed", displayPath));
1189            writer.println(sm.getString("managerServlet.exception",
1190                                        t.toString()));
1191        }
1192
1193    }
1194
1195
1196    /**
1197     * Stop the web application at the specified context path.
1198     *
1199     * @param writer Writer to render to
1200     * @param path Context path of the application to be stopped
1201     */

1202    protected void stop(PrintWriter JavaDoc writer, String JavaDoc path) {
1203
1204        if (debug >= 1)
1205            log("stop: Stopping web application at '" + path + "'");
1206
1207        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
1208            writer.println(sm.getString("managerServlet.invalidPath",
1209                                        RequestUtil.filter(path)));
1210            return;
1211        }
1212        String JavaDoc displayPath = path;
1213        if( path.equals("/") )
1214            path = "";
1215
1216        try {
1217            Context JavaDoc context = (Context JavaDoc) host.findChild(path);
1218            if (context == null) {
1219                writer.println(sm.getString("managerServlet.noContext",
1220                                            RequestUtil.filter(displayPath)));
1221                return;
1222            }
1223            // It isn't possible for the manager to stop itself
1224
if (context.getPath().equals(this.context.getPath())) {
1225                writer.println(sm.getString("managerServlet.noSelf"));
1226                return;
1227            }
1228            ((Lifecycle) context).stop();
1229            writer.println(sm.getString("managerServlet.stopped", displayPath));
1230        } catch (Throwable JavaDoc t) {
1231            log("ManagerServlet.stop[" + displayPath + "]", t);
1232            writer.println(sm.getString("managerServlet.exception",
1233                                        t.toString()));
1234        }
1235
1236    }
1237
1238
1239    /**
1240     * Undeploy the web application at the specified context path.
1241     *
1242     * @param writer Writer to render to
1243     * @param path Context path of the application to be removed
1244     */

1245    protected void undeploy(PrintWriter JavaDoc writer, String JavaDoc path) {
1246
1247        if (debug >= 1)
1248            log("undeploy: Undeploying web application at '" + path + "'");
1249
1250        if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
1251            writer.println(sm.getString("managerServlet.invalidPath",
1252                                        RequestUtil.filter(path)));
1253            return;
1254        }
1255        String JavaDoc displayPath = path;
1256        if( path.equals("/") )
1257            path = "";
1258
1259        try {
1260
1261            // Validate the Context of the specified application
1262
Context JavaDoc context = (Context JavaDoc) host.findChild(path);
1263            if (context == null) {
1264                writer.println(sm.getString("managerServlet.noContext",
1265                                            RequestUtil.filter(displayPath)));
1266                return;
1267            }
1268
1269            // Identify the appBase of the owning Host of this Context (if any)
1270
String JavaDoc appBase = null;
1271            File JavaDoc appBaseDir = null;
1272            if (context.getParent() instanceof Host) {
1273                appBase = ((Host) context.getParent()).getAppBase();
1274                appBaseDir = new File JavaDoc(appBase);
1275                if (!appBaseDir.isAbsolute()) {
1276                    appBaseDir = new File JavaDoc(System.getProperty("catalina.base"),
1277                                          appBase);
1278                }
1279            }
1280
1281            if (!isDeployed(path)) {
1282                writer.println(sm.getString("managerServlet.notDeployed",
1283                        RequestUtil.filter(displayPath)));
1284                return;
1285            }
1286
1287            if (!isServiced(path)) {
1288                addServiced(path);
1289                try {
1290                    // Try to stop the context first to be nicer
1291
((Lifecycle) context).stop();
1292                } catch (Throwable JavaDoc t) {
1293                    // Ignore
1294
}
1295                try {
1296                    File JavaDoc war = new File JavaDoc(getAppBase(), getDocBase(path) + ".war");
1297                    File JavaDoc dir = new File JavaDoc(getAppBase(), getDocBase(path));
1298                    File JavaDoc xml = new File JavaDoc(configBase, getConfigFile(path) + ".xml");
1299                    if (war.exists()) {
1300                        war.delete();
1301                    } else if (dir.exists()) {
1302                        undeployDir(dir);
1303                    } else {
1304                        xml.delete();
1305                    }
1306                    // Perform new deployment
1307
check(path);
1308                } finally {
1309                    removeServiced(path);
1310                }
1311            }
1312            writer.println(sm.getString("managerServlet.undeployed",
1313                                        displayPath));
1314        } catch (Throwable JavaDoc t) {
1315            log("ManagerServlet.undeploy[" + displayPath + "]", t);
1316            writer.println(sm.getString("managerServlet.exception",
1317                                        t.toString()));
1318        }
1319
1320    }
1321
1322
1323    // -------------------------------------------------------- Support Methods
1324

1325
1326    /**
1327     * Given a context path, get the config file name.
1328     */

1329    protected String JavaDoc getConfigFile(String JavaDoc path) {
1330        String JavaDoc basename = null;
1331        if (path.equals("")) {
1332            basename = "ROOT";
1333        } else {
1334            basename = path.substring(1).replace('/', '#');
1335        }
1336        return (basename);
1337    }
1338
1339
1340    /**
1341     * Given a context path, get the config file name.
1342     */

1343    protected String JavaDoc getDocBase(String JavaDoc path) {
1344        String JavaDoc basename = null;
1345        if (path.equals("")) {
1346            basename = "ROOT";
1347        } else {
1348            basename = path.substring(1);
1349        }
1350        return (basename);
1351    }
1352
1353    
1354    /**
1355     * Return a File object representing the "application root" directory
1356     * for our associated Host.
1357     */

1358    protected File JavaDoc getAppBase() {
1359
1360        if (appBase != null) {
1361            return appBase;
1362        }
1363
1364        File JavaDoc file = new File JavaDoc(host.getAppBase());
1365        if (!file.isAbsolute())
1366            file = new File JavaDoc(System.getProperty("catalina.base"),
1367                            host.getAppBase());
1368        try {
1369            appBase = file.getCanonicalFile();
1370        } catch (IOException JavaDoc e) {
1371            appBase = file;
1372        }
1373        return (appBase);
1374
1375    }
1376
1377
1378    /**
1379     * Invoke the isDeployed method on the deployer.
1380     */

1381    protected boolean isDeployed(String JavaDoc name)
1382        throws Exception JavaDoc {
1383        String JavaDoc[] params = { name };
1384        String JavaDoc[] signature = { "java.lang.String" };
1385        Boolean JavaDoc result =
1386            (Boolean JavaDoc) mBeanServer.invoke(oname, "isDeployed", params, signature);
1387        return result.booleanValue();
1388    }
1389    
1390
1391    /**
1392     * Invoke the check method on the deployer.
1393     */

1394    protected void check(String JavaDoc name)
1395        throws Exception JavaDoc {
1396        String JavaDoc[] params = { name };
1397        String JavaDoc[] signature = { "java.lang.String" };
1398        mBeanServer.invoke(oname, "check", params, signature);
1399    }
1400    
1401
1402    /**
1403     * Invoke the isServiced method on the deployer.
1404     */

1405    protected boolean isServiced(String JavaDoc name)
1406        throws Exception JavaDoc {
1407        String JavaDoc[] params = { name };
1408        String JavaDoc[] signature = { "java.lang.String" };
1409        Boolean JavaDoc result =
1410            (Boolean JavaDoc) mBeanServer.invoke(oname, "isServiced", params, signature);
1411        return result.booleanValue();
1412    }
1413    
1414
1415    /**
1416     * Invoke the addServiced method on the deployer.
1417     */

1418    protected void addServiced(String JavaDoc name)
1419        throws Exception JavaDoc {
1420        String JavaDoc[] params = { name };
1421        String JavaDoc[] signature = { "java.lang.String" };
1422        mBeanServer.invoke(oname, "addServiced", params, signature);
1423    }
1424    
1425
1426    /**
1427     * Invoke the removeServiced method on the deployer.
1428     */

1429    protected void removeServiced(String JavaDoc name)
1430        throws Exception JavaDoc {
1431        String JavaDoc[] params = { name };
1432        String JavaDoc[] signature = { "java.lang.String" };
1433        mBeanServer.invoke(oname, "removeServiced", params, signature);
1434    }
1435    
1436
1437    /**
1438     * Delete the specified directory, including all of its contents and
1439     * subdirectories recursively.
1440     *
1441     * @param dir File object representing the directory to be deleted
1442     */

1443    protected void undeployDir(File JavaDoc dir) {
1444
1445        String JavaDoc files[] = dir.list();
1446        if (files == null) {
1447            files = new String JavaDoc[0];
1448        }
1449        for (int i = 0; i < files.length; i++) {
1450            File JavaDoc file = new File JavaDoc(dir, files[i]);
1451            if (file.isDirectory()) {
1452                undeployDir(file);
1453            } else {
1454                file.delete();
1455            }
1456        }
1457        dir.delete();
1458
1459    }
1460
1461
1462    /**
1463     * Upload the WAR file included in this request, and store it at the
1464     * specified file location.
1465     *
1466     * @param request The servlet request we are processing
1467     * @param war The file into which we should store the uploaded WAR
1468     *
1469     * @exception IOException if an I/O error occurs during processing
1470     */

1471    protected void uploadWar(HttpServletRequest JavaDoc request, File JavaDoc war)
1472        throws IOException JavaDoc {
1473
1474        war.delete();
1475        ServletInputStream JavaDoc istream = null;
1476        BufferedOutputStream JavaDoc ostream = null;
1477        try {
1478            istream = request.getInputStream();
1479            ostream =
1480                new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(war), 1024);
1481            byte buffer[] = new byte[1024];
1482            while (true) {
1483                int n = istream.read(buffer);
1484                if (n < 0) {
1485                    break;
1486                }
1487                ostream.write(buffer, 0, n);
1488            }
1489            ostream.flush();
1490            ostream.close();
1491            ostream = null;
1492            istream.close();
1493            istream = null;
1494        } catch (IOException JavaDoc e) {
1495            war.delete();
1496            throw e;
1497        } finally {
1498            if (ostream != null) {
1499                try {
1500                    ostream.close();
1501                } catch (Throwable JavaDoc t) {
1502                    ;
1503                }
1504                ostream = null;
1505            }
1506            if (istream != null) {
1507                try {
1508                    istream.close();
1509                } catch (Throwable JavaDoc t) {
1510                    ;
1511                }
1512                istream = null;
1513            }
1514        }
1515
1516    }
1517
1518
1519    /**
1520     * Copy the specified file or directory to the destination.
1521     *
1522     * @param src File object representing the source
1523     * @param dest File object representing the destination
1524     */

1525    public static boolean copy(File JavaDoc src, File JavaDoc dest) {
1526        boolean result = false;
1527        try {
1528            if( src != null &&
1529                    !src.getCanonicalPath().equals(dest.getCanonicalPath()) ) {
1530                result = copyInternal(src, dest, new byte[4096]);
1531            }
1532        } catch (IOException JavaDoc e) {
1533            e.printStackTrace();
1534        }
1535        return result;
1536    }
1537
1538    
1539    /**
1540     * Copy the specified file or directory to the destination.
1541     *
1542     * @param src File object representing the source
1543     * @param dest File object representing the destination
1544     */

1545    public static boolean copyInternal(File JavaDoc src, File JavaDoc dest, byte[] buf) {
1546        
1547        boolean result = true;
1548        
1549        String JavaDoc files[] = null;
1550        if (src.isDirectory()) {
1551            files = src.list();
1552            result = dest.mkdir();
1553        } else {
1554            files = new String JavaDoc[1];
1555            files[0] = "";
1556        }
1557        if (files == null) {
1558            files = new String JavaDoc[0];
1559        }
1560        for (int i = 0; (i < files.length) && result; i++) {
1561            File JavaDoc fileSrc = new File JavaDoc(src, files[i]);
1562            File JavaDoc fileDest = new File JavaDoc(dest, files[i]);
1563            if (fileSrc.isDirectory()) {
1564                result = copyInternal(fileSrc, fileDest, buf);
1565            } else {
1566                FileInputStream JavaDoc is = null;
1567                FileOutputStream JavaDoc os = null;
1568                try {
1569                    is = new FileInputStream JavaDoc(fileSrc);
1570                    os = new FileOutputStream JavaDoc(fileDest);
1571                    int len = 0;
1572                    while (true) {
1573                        len = is.read(buf);
1574                        if (len == -1)
1575                            break;
1576                        os.write(buf, 0, len);
1577                    }
1578                } catch (IOException JavaDoc e) {
1579                    e.printStackTrace();
1580                    result = false;
1581                } finally {
1582                    if (is != null) {
1583                        try {
1584                            is.close();
1585                        } catch (IOException JavaDoc e) {
1586                        }
1587                    }
1588                    if (os != null) {
1589                        try {
1590                            os.close();
1591                        } catch (IOException JavaDoc e) {
1592                        }
1593                    }
1594                }
1595            }
1596        }
1597        return result;
1598        
1599    }
1600    
1601    
1602}
1603
Popular Tags