Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » manager » [javadoc | source]
    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;
   23   import java.io.File;
   24   import java.io.FileInputStream;
   25   import java.io.FileOutputStream;
   26   import java.io.IOException;
   27   import java.io.PrintWriter;
   28   import java.util.Iterator;
   29   
   30   import javax.management.MBeanServer;
   31   import javax.management.ObjectName;
   32   import javax.naming.Binding;
   33   import javax.naming.InitialContext;
   34   import javax.naming.NamingEnumeration;
   35   import javax.naming.NamingException;
   36   import javax.servlet.ServletException;
   37   import javax.servlet.ServletInputStream;
   38   import javax.servlet.UnavailableException;
   39   import javax.servlet.http.HttpServlet;
   40   import javax.servlet.http.HttpServletRequest;
   41   import javax.servlet.http.HttpServletResponse;
   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.Manager;
   51   import org.apache.catalina.Role;
   52   import org.apache.catalina.Server;
   53   import org.apache.catalina.ServerFactory;
   54   import org.apache.catalina.Session;
   55   import org.apache.catalina.UserDatabase;
   56   import org.apache.catalina.Wrapper;
   57   import org.apache.catalina.core.StandardServer;
   58   import org.apache.catalina.util.RequestUtil;
   59   import org.apache.catalina.util.ServerInfo;
   60   import org.apache.catalina.util.StringManager;
   61   import org.apache.tomcat.util.modeler.Registry;
   62   
   63   
   64   /**
   65    * Servlet that enables remote management of the web applications installed
   66    * within the same virtual host as this web application is.  Normally, this
   67    * functionality will be protected by a security constraint in the web
   68    * application deployment descriptor.  However, this requirement can be
   69    * relaxed during testing.
   70    * <p>
   71    * This servlet examines the value returned by <code>getPathInfo()</code>
   72    * and related query parameters to determine what action is being requested.
   73    * The following actions and parameters (starting after the servlet path)
   74    * are supported:
   75    * <ul>
   76    * <li><b>/deploy?config={config-url}</b> - Install and start a new
   77    *     web application, based on the contents of the context configuration
   78    *     file found at the specified URL.  The <code>docBase</code> attribute
   79    *     of the context configuration file is used to locate the actual
   80    *     WAR or directory containing the application.</li>
   81    * <li><b>/deploy?config={config-url}&war={war-url}/</b> - Install and start
   82    *     a new web application, based on the contents of the context
   83    *     configuration file found at <code>{config-url}</code>, overriding the
   84    *     <code>docBase</code> attribute with the contents of the web
   85    *     application archive found at <code>{war-url}</code>.</li>
   86    * <li><b>/deploy?path=/xxx&war={war-url}</b> - Install and start a new
   87    *     web application attached to context path <code>/xxx</code>, based
   88    *     on the contents of the web application archive found at the
   89    *     specified URL.</li>
   90    * <li><b>/list</b> - List the context paths of all currently installed web
   91    *     applications for this virtual host.  Each context will be listed with
   92    *     the following format <code>path:status:sessions</code>.
   93    *     Where path is the context path.  Status is either running or stopped.
   94    *     Sessions is the number of active Sessions.</li>
   95    * <li><b>/reload?path=/xxx</b> - Reload the Java classes and resources for
   96    *     the application at the specified path.</li>
   97    * <li><b>/resources?type=xxxx</b> - Enumerate the available global JNDI
   98    *     resources, optionally limited to those of the specified type
   99    *     (fully qualified Java class name), if available.</li>
  100    * <li><b>/roles</b> - Enumerate the available security role names and
  101    *     descriptions from the user database connected to the <code>users</code>
  102    *     resource reference.
  103    * <li><b>/serverinfo</b> - Display system OS and JVM properties.
  104    * <li><b>/expire?path=/xxx</b> - List session idle timeinformation about the
  105    *     web application attached to context path <code>/xxx</code> for this
  106    *     virtual host.</li>
  107    * <li><b>/expire?path=/xxx&idle=mm</b> - Expire sessions
  108    *     for the context path <code>/xxx</code> which were idle for at
  109    *     least mm minutes.</li>
  110    * <li><b>/start?path=/xxx</b> - Start the web application attached to
  111    *     context path <code>/xxx</code> for this virtual host.</li>
  112    * <li><b>/stop?path=/xxx</b> - Stop the web application attached to
  113    *     context path <code>/xxx</code> for this virtual host.</li>
  114    * <li><b>/undeploy?path=/xxx</b> - Shutdown and remove the web application
  115    *     attached to context path <code>/xxx</code> for this virtual host,
  116    *     and remove the underlying WAR file or document base directory.
  117    *     (<em>NOTE</em> - This is only allowed if the WAR file or document
  118    *     base is stored in the <code>appBase</code> directory of this host,
  119    *     typically as a result of being placed there via the <code>/deploy</code>
  120    *     command.</li>
  121    * </ul>
  122    * <p>Use <code>path=/</code> for the ROOT context.</p>
  123    * <p>The syntax of the URL for a web application archive must conform to one
  124    * of the following patterns to be successfully deployed:</p>
  125    * <ul>
  126    * <li><b>file:/absolute/path/to/a/directory</b> - You can specify the absolute
  127    *     path of a directory that contains the unpacked version of a web
  128    *     application.  This directory will be attached to the context path you
  129    *     specify without any changes.</li>
  130    * <li><b>jar:file:/absolute/path/to/a/warfile.war!/</b> - You can specify a
  131    *     URL to a local web application archive file.  The syntax must conform to
  132    *     the rules specified by the <code>JarURLConnection</code> class for a
  133    *     reference to an entire JAR file.</li>
  134    * <li><b>jar:http://hostname:port/path/to/a/warfile.war!/</b> - You can specify
  135    *     a URL to a remote (HTTP-accessible) web application archive file.  The
  136    *     syntax must conform to the rules specified by the
  137    *     <code>JarURLConnection</code> class for a reference to an entire
  138    *     JAR file.</li>
  139    * </ul>
  140    * <p>
  141    * <b>NOTE</b> - Attempting to reload or remove the application containing
  142    * this servlet itself will not succeed.  Therefore, this servlet should
  143    * generally be deployed as a separate web application within the virtual host
  144    * to be managed.
  145    * <p>
  146    * <b>NOTE</b> - For security reasons, this application will not operate
  147    * when accessed via the invoker servlet.  You must explicitly map this servlet
  148    * with a servlet mapping, and you will always want to protect it with
  149    * appropriate security constraints as well.
  150    * <p>
  151    * The following servlet initialization parameters are recognized:
  152    * <ul>
  153    * <li><b>debug</b> - The debugging detail level that controls the amount
  154    *     of information that is logged by this servlet.  Default is zero.
  155    * </ul>
  156    *
  157    * @author Craig R. McClanahan
  158    * @author Remy Maucherat
  159    * @version $Revision: 615478 $ $Date: 2008-01-26 20:52:28 +0100 (sam., 26 janv. 2008) $
  160    */
  161   
  162   public class ManagerServlet
  163       extends HttpServlet implements ContainerServlet {
  164   
  165   
  166       // ----------------------------------------------------- Instance Variables
  167   
  168   
  169       /**
  170        * Path where context descriptors should be deployed.
  171        */
  172       protected File configBase = null;
  173   
  174   
  175       /**
  176        * The Context container associated with our web application.
  177        */
  178       protected Context context = null;
  179   
  180   
  181       /**
  182        * The debugging detail level for this servlet.
  183        */
  184       protected int debug = 1;
  185   
  186   
  187       /**
  188        * File object representing the directory into which the deploy() command
  189        * will store the WAR and context configuration files that have been
  190        * uploaded.
  191        */
  192       protected File deployed = null;
  193   
  194   
  195       /**
  196        * Path used to store revisions of webapps.
  197        */
  198       protected File versioned = null;
  199   
  200   
  201       /**
  202        * Path used to store context descriptors.
  203        */
  204       protected File contextDescriptors = null;
  205   
  206   
  207       /**
  208        * The associated host.
  209        */
  210       protected Host host = null;
  211   
  212       
  213       /**
  214        * The host appBase.
  215        */
  216       protected File appBase = null;
  217       
  218       
  219       /**
  220        * MBean server.
  221        */
  222       protected MBeanServer mBeanServer = null;
  223   
  224   
  225       /**
  226        * The associated deployer ObjectName.
  227        */
  228       protected ObjectName oname = null;
  229       
  230   
  231       /**
  232        * The global JNDI <code>NamingContext</code> for this server,
  233        * if available.
  234        */
  235       protected javax.naming.Context global = null;
  236   
  237   
  238       /**
  239        * The string manager for this package.
  240        */
  241       protected static StringManager sm =
  242           StringManager.getManager(Constants.Package);
  243   
  244   
  245       /**
  246        * The Wrapper container associated with this servlet.
  247        */
  248       protected Wrapper wrapper = null;
  249   
  250   
  251       // ----------------------------------------------- ContainerServlet Methods
  252   
  253   
  254       /**
  255        * Return the Wrapper with which we are associated.
  256        */
  257       public Wrapper getWrapper() {
  258   
  259           return (this.wrapper);
  260   
  261       }
  262   
  263   
  264       /**
  265        * Set the Wrapper with which we are associated.
  266        *
  267        * @param wrapper The new wrapper
  268        */
  269       public void setWrapper(Wrapper wrapper) {
  270   
  271           this.wrapper = wrapper;
  272           if (wrapper == null) {
  273               context = null;
  274               host = null;
  275               oname = null;
  276           } else {
  277               context = (Context) wrapper.getParent();
  278               host = (Host) context.getParent();
  279               Engine engine = (Engine) host.getParent();
  280               try {
  281                   oname = new ObjectName(engine.getName() 
  282                           + ":type=Deployer,host=" + host.getName());
  283               } catch (Exception e) {
  284                   // ?
  285               }
  286           }
  287   
  288           // Retrieve the MBean server
  289           mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
  290           
  291       }
  292   
  293   
  294       // --------------------------------------------------------- Public Methods
  295   
  296   
  297       /**
  298        * Finalize this servlet.
  299        */
  300       public void destroy() {
  301   
  302           ;       // No actions necessary
  303   
  304       }
  305   
  306   
  307       /**
  308        * Process a GET request for the specified resource.
  309        *
  310        * @param request The servlet request we are processing
  311        * @param response The servlet response we are creating
  312        *
  313        * @exception IOException if an input/output error occurs
  314        * @exception ServletException if a servlet-specified error occurs
  315        */
  316       public void doGet(HttpServletRequest request,
  317                         HttpServletResponse response)
  318           throws IOException, ServletException {
  319   
  320           // Verify that we were not accessed using the invoker servlet
  321           if (request.getAttribute(Globals.INVOKED_ATTR) != null)
  322               throw new UnavailableException
  323                   (sm.getString("managerServlet.cannotInvoke"));
  324   
  325           // Identify the request parameters that we need
  326           String command = request.getPathInfo();
  327           if (command == null)
  328               command = request.getServletPath();
  329           String config = request.getParameter("config");
  330           String path = request.getParameter("path");
  331           String type = request.getParameter("type");
  332           String war = request.getParameter("war");
  333           String tag = request.getParameter("tag");
  334           boolean update = false;
  335           if ((request.getParameter("update") != null) 
  336               && (request.getParameter("update").equals("true"))) {
  337               update = true;
  338           }
  339   
  340           // Prepare our output writer to generate the response message
  341           response.setContentType("text/plain; charset=" + Constants.CHARSET);
  342           PrintWriter writer = response.getWriter();
  343   
  344           // Process the requested command (note - "/deploy" is not listed here)
  345           if (command == null) {
  346               writer.println(sm.getString("managerServlet.noCommand"));
  347           } else if (command.equals("/deploy")) {
  348               if (war != null || config != null) {
  349                   deploy(writer, config, path, war, update);
  350               } else {
  351                   deploy(writer, path, tag);
  352               }
  353           } else if (command.equals("/install")) {
  354               // Deprecated
  355               deploy(writer, config, path, war, false);
  356           } else if (command.equals("/list")) {
  357               list(writer);
  358           } else if (command.equals("/reload")) {
  359               reload(writer, path);
  360           } else if (command.equals("/remove")) {
  361               // Deprecated
  362               undeploy(writer, path);
  363           } else if (command.equals("/resources")) {
  364               resources(writer, type);
  365           } else if (command.equals("/roles")) {
  366               roles(writer);
  367           } else if (command.equals("/save")) {
  368               save(writer, path);
  369           } else if (command.equals("/serverinfo")) {
  370               serverinfo(writer);
  371           } else if (command.equals("/expire")) {
  372               expireSessions(writer, path, request);
  373           } else if (command.equals("/start")) {
  374               start(writer, path);
  375           } else if (command.equals("/stop")) {
  376               stop(writer, path);
  377           } else if (command.equals("/undeploy")) {
  378               undeploy(writer, path);
  379           } else {
  380               writer.println(sm.getString("managerServlet.unknownCommand",
  381                                           command));
  382           }
  383   
  384           // Finish up the response
  385           writer.flush();
  386           writer.close();
  387   
  388       }
  389   
  390   
  391       /**
  392        * Process a PUT request for the specified resource.
  393        *
  394        * @param request The servlet request we are processing
  395        * @param response The servlet response we are creating
  396        *
  397        * @exception IOException if an input/output error occurs
  398        * @exception ServletException if a servlet-specified error occurs
  399        */
  400       public void doPut(HttpServletRequest request,
  401                         HttpServletResponse response)
  402           throws IOException, ServletException {
  403   
  404           // Verify that we were not accessed using the invoker servlet
  405           if (request.getAttribute(Globals.INVOKED_ATTR) != null)
  406               throw new UnavailableException
  407                   (sm.getString("managerServlet.cannotInvoke"));
  408   
  409           // Identify the request parameters that we need
  410           String command = request.getPathInfo();
  411           if (command == null)
  412               command = request.getServletPath();
  413           String path = request.getParameter("path");
  414           String tag = request.getParameter("tag");
  415           boolean update = false;
  416           if ((request.getParameter("update") != null) 
  417               && (request.getParameter("update").equals("true"))) {
  418               update = true;
  419           }
  420   
  421           // Prepare our output writer to generate the response message
  422           response.setContentType("text/plain;charset="+Constants.CHARSET);
  423           PrintWriter writer = response.getWriter();
  424   
  425           // Process the requested command
  426           if (command == null) {
  427               writer.println(sm.getString("managerServlet.noCommand"));
  428           } else if (command.equals("/deploy")) {
  429               deploy(writer, path, tag, update, request);
  430           } else {
  431               writer.println(sm.getString("managerServlet.unknownCommand",
  432                                           command));
  433           }
  434   
  435           // Finish up the response
  436           writer.flush();
  437           writer.close();
  438   
  439       }
  440   
  441   
  442       /**
  443        * Initialize this servlet.
  444        */
  445       public void init() throws ServletException {
  446   
  447           // Ensure that our ContainerServlet properties have been set
  448           if ((wrapper == null) || (context == null))
  449               throw new UnavailableException
  450                   (sm.getString("managerServlet.noWrapper"));
  451   
  452           // Verify that we were not accessed using the invoker servlet
  453           String servletName = getServletConfig().getServletName();
  454           if (servletName == null)
  455               servletName = "";
  456           if (servletName.startsWith("org.apache.catalina.INVOKER."))
  457               throw new UnavailableException
  458                   (sm.getString("managerServlet.cannotInvoke"));
  459   
  460           // Set our properties from the initialization parameters
  461           String value = null;
  462           try {
  463               value = getServletConfig().getInitParameter("debug");
  464               debug = Integer.parseInt(value);
  465           } catch (Throwable t) {
  466               ;
  467           }
  468   
  469           // Acquire global JNDI resources if available
  470           Server server = ServerFactory.getServer();
  471           if ((server != null) && (server instanceof StandardServer)) {
  472               global = ((StandardServer) server).getGlobalNamingContext();
  473           }
  474   
  475           // Calculate the directory into which we will be deploying applications
  476           versioned = (File) getServletContext().getAttribute
  477               ("javax.servlet.context.tempdir");
  478   
  479           // Identify the appBase of the owning Host of this Context
  480           // (if any)
  481           String appBase = ((Host) context.getParent()).getAppBase();
  482           deployed = new File(appBase);
  483           if (!deployed.isAbsolute()) {
  484               deployed = new File(System.getProperty("catalina.base"),
  485                                   appBase);
  486           }
  487           configBase = new File(System.getProperty("catalina.base"), "conf");
  488           Container container = context;
  489           Container host = null;
  490           Container engine = null;
  491           while (container != null) {
  492               if (container instanceof Host)
  493                   host = container;
  494               if (container instanceof Engine)
  495                   engine = container;
  496               container = container.getParent();
  497           }
  498           if (engine != null) {
  499               configBase = new File(configBase, engine.getName());
  500           }
  501           if (host != null) {
  502               configBase = new File(configBase, host.getName());
  503           }
  504           // Note: The directory must exist for this to work.
  505   
  506           // Log debugging messages as necessary
  507           if (debug >= 1) {
  508               log("init: Associated with Deployer '" +
  509                   oname + "'");
  510               if (global != null) {
  511                   log("init: Global resources are available");
  512               }
  513           }
  514   
  515       }
  516   
  517   
  518   
  519       // -------------------------------------------------------- Private Methods
  520   
  521   
  522       /**
  523        * Store server configuration.
  524        * 
  525        * @param path Optional context path to save
  526        */
  527       protected synchronized void save(PrintWriter writer, String path) {
  528   
  529           Server server = ServerFactory.getServer();
  530   
  531           if (!(server instanceof StandardServer)) {
  532               writer.println(sm.getString("managerServlet.saveFail", server));
  533               return;
  534           }
  535   
  536           if ((path == null) || path.length() == 0 || !path.startsWith("/")) {
  537               try {
  538                   ((StandardServer) server).storeConfig();
  539                   writer.println(sm.getString("managerServlet.saved"));
  540               } catch (Exception e) {
  541                   log("managerServlet.storeConfig", e);
  542                   writer.println(sm.getString("managerServlet.exception",
  543                                               e.toString()));
  544                   return;
  545               }
  546           } else {
  547               String contextPath = path;
  548               if (path.equals("/")) {
  549                   contextPath = "";
  550               }
  551               Context context = (Context) host.findChild(contextPath);
  552               if (context == null) {
  553                   writer.println(sm.getString("managerServlet.noContext", path));
  554                   return;
  555               }
  556               try {
  557                   ((StandardServer) server).storeContext(context);
  558                   writer.println(sm.getString("managerServlet.savedContext", 
  559                                  path));
  560               } catch (Exception e) {
  561                   log("managerServlet.save[" + path + "]", e);
  562                   writer.println(sm.getString("managerServlet.exception",
  563                                               e.toString()));
  564                   return;
  565               }
  566           }
  567   
  568       }
  569   
  570   
  571       /**
  572        * Deploy a web application archive (included in the current request)
  573        * at the specified context path.
  574        *
  575        * @param writer Writer to render results to
  576        * @param path Context path of the application to be installed
  577        * @param tag Tag to be associated with the webapp
  578        * @param request Servlet request we are processing
  579        */
  580       protected synchronized void deploy
  581           (PrintWriter writer, String path,
  582            String tag, boolean update, HttpServletRequest request) {
  583   
  584           if (debug >= 1) {
  585               log("deploy: Deploying web application at '" + path + "'");
  586           }
  587   
  588           // Validate the requested context path
  589           if ((path == null) || path.length() == 0 || !path.startsWith("/")) {
  590               writer.println(sm.getString("managerServlet.invalidPath", path));
  591               return;
  592           }
  593           String displayPath = path;
  594           if( path.equals("/") )
  595               path = "";
  596           String basename = getDocBase(path);
  597   
  598           // Check if app already exists, or undeploy it if updating
  599           Context context = (Context) host.findChild(path);
  600           if (update) {
  601               if (context != null) {
  602                   undeploy(writer, displayPath);
  603               }
  604               context = (Context) host.findChild(path);
  605           }
  606           if (context != null) {
  607               writer.println
  608                   (sm.getString("managerServlet.alreadyContext",
  609                                 displayPath));
  610               return;
  611           }
  612   
  613           // Calculate the base path
  614           File deployedPath = deployed;
  615           if (tag != null) {
  616               deployedPath = new File(versioned, tag);
  617               deployedPath.mkdirs();
  618           }
  619   
  620           // Upload the web application archive to a local WAR file
  621           File localWar = new File(deployedPath, basename + ".war");
  622           if (debug >= 2) {
  623               log("Uploading WAR file to " + localWar);
  624           }
  625   
  626           // Copy WAR to appBase
  627           try {
  628               if (!isServiced(path)) {
  629                   addServiced(path);
  630                   try {
  631                       // Upload WAR
  632                       uploadWar(request, localWar);
  633                       // Copy WAR and XML to the host app base if needed
  634                       if (tag != null) {
  635                           deployedPath = deployed;
  636                           File localWarCopy = new File(deployedPath, basename + ".war");
  637                           copy(localWar, localWarCopy);
  638                           localWar = localWarCopy;
  639                           copy(localWar, new File(getAppBase(), basename + ".war"));
  640                       }
  641                       // Perform new deployment
  642                       check(path);
  643                   } finally {
  644                       removeServiced(path);
  645                   }
  646               }
  647           } catch (Exception e) {
  648               log("managerServlet.check[" + displayPath + "]", e);
  649               writer.println(sm.getString("managerServlet.exception",
  650                                           e.toString()));
  651               return;
  652           }
  653           
  654           context = (Context) host.findChild(path);
  655           if (context != null && context.getConfigured()) {
  656               writer.println(sm.getString("managerServlet.deployed", displayPath));
  657           } else {
  658               // Something failed
  659               writer.println(sm.getString("managerServlet.deployFailed", displayPath));
  660           }
  661           
  662       }
  663   
  664   
  665       /**
  666        * Install an application for the specified path from the specified
  667        * web application archive.
  668        *
  669        * @param writer Writer to render results to
  670        * @param tag Revision tag to deploy from
  671        * @param path Context path of the application to be installed
  672        */
  673       protected void deploy(PrintWriter writer, String path, String tag) {
  674   
  675           // Validate the requested context path
  676           if ((path == null) || path.length() == 0 || !path.startsWith("/")) {
  677               writer.println(sm.getString("managerServlet.invalidPath", path));
  678               return;
  679           }
  680           String displayPath = path;
  681           if( path.equals("/") )
  682               path = "";
  683   
  684           // Calculate the base path
  685           File deployedPath = versioned;
  686           if (tag != null) {
  687               deployedPath = new File(deployedPath, tag);
  688           }
  689   
  690           // Find the local WAR file
  691           File localWar = new File(deployedPath, getDocBase(path) + ".war");
  692           // Find the local context deployment file (if any)
  693           File localXml = new File(configBase, getConfigFile(path) + ".xml");
  694   
  695           // Check if app already exists, or undeploy it if updating
  696           Context context = (Context) host.findChild(path);
  697           if (context != null) {
  698               undeploy(writer, displayPath);
  699           }
  700   
  701           // Copy WAR to appBase
  702           try {
  703               if (!isServiced(path)) {
  704                   addServiced(path);
  705                   try {
  706                       copy(localWar, new File(getAppBase(), getDocBase(path) + ".war"));
  707                       // Perform new deployment
  708                       check(path);
  709                   } finally {
  710                       removeServiced(path);
  711                   }
  712               }
  713           } catch (Exception e) {
  714               log("managerServlet.check[" + displayPath + "]", e);
  715               writer.println(sm.getString("managerServlet.exception",
  716                                           e.toString()));
  717               return;
  718           }
  719           
  720           context = (Context) host.findChild(path);
  721           if (context != null && context.getConfigured()) {
  722               writer.println(sm.getString("managerServlet.deployed", displayPath));
  723           } else {
  724               // Something failed
  725               writer.println(sm.getString("managerServlet.deployFailed", displayPath));
  726           }
  727           
  728       }
  729   
  730   
  731       /**
  732        * Install an application for the specified path from the specified
  733        * web application archive.
  734        *
  735        * @param writer Writer to render results to
  736        * @param config URL of the context configuration file to be installed
  737        * @param path Context path of the application to be installed
  738        * @param war URL of the web application archive to be installed
  739        * @param update true to override any existing webapp on the path
  740        */
  741       protected void deploy(PrintWriter writer, String config,
  742               String path, String war, boolean update) {
  743           
  744           if (config != null && config.length() == 0) {
  745               config = null;
  746           }
  747           if (war != null && war.length() == 0) {
  748               war = null;
  749           }
  750           
  751           if (debug >= 1) {
  752               if (config != null && config.length() > 0) {
  753                   if (war != null) {
  754                       log("install: Installing context configuration at '" +
  755                               config + "' from '" + war + "'");
  756                   } else {
  757                       log("install: Installing context configuration at '" +
  758                               config + "'");
  759                   }
  760               } else {
  761                   if (path != null && path.length() > 0) {
  762                       log("install: Installing web application at '" + path +
  763                               "' from '" + war + "'");
  764                   } else {
  765                       log("install: Installing web application from '" + war + "'");
  766                   }
  767               }
  768           }
  769           
  770           if (path == null || path.length() == 0 || !path.startsWith("/")) {
  771               writer.println(sm.getString("managerServlet.invalidPath",
  772                                           RequestUtil.filter(path)));
  773               return;
  774           }
  775           String displayPath = path;
  776           if("/".equals(path)) {
  777               path = "";
  778           }
  779           
  780           // Check if app already exists, or undeploy it if updating
  781           Context context = (Context) host.findChild(path);
  782           if (update) {
  783               if (context != null) {
  784                   undeploy(writer, displayPath);
  785               }
  786               context = (Context) host.findChild(path);
  787           }
  788           if (context != null) {
  789               writer.println
  790               (sm.getString("managerServlet.alreadyContext",
  791                       displayPath));
  792               return;
  793           }
  794           
  795           if (config != null && (config.startsWith("file:"))) {
  796               config = config.substring("file:".length());
  797           }
  798           if (war != null && (war.startsWith("file:"))) {
  799               war = war.substring("file:".length());
  800           }
  801           
  802           try {
  803               if (!isServiced(path)) {
  804                   addServiced(path);
  805                   try {
  806                       if (config != null) {
  807                           configBase.mkdirs();
  808                           copy(new File(config), 
  809                                   new File(configBase, getConfigFile(path) + ".xml"));
  810                       }
  811                       if (war != null) {
  812                           if (war.endsWith(".war")) {
  813                               copy(new File(war), 
  814                                       new File(getAppBase(), getDocBase(path) + ".war"));
  815                           } else {
  816                               copy(new File(war), 
  817                                       new File(getAppBase(), getDocBase(path)));
  818                           }
  819                       }
  820                       // Perform new deployment
  821                       check(path);
  822                   } finally {
  823                       removeServiced(path);
  824                   }
  825               }
  826               context = (Context) host.findChild(path);
  827               if (context != null && context.getConfigured()) {
  828                   writer.println(sm.getString("managerServlet.deployed", displayPath));
  829               } else {
  830                   // Something failed
  831                   writer.println(sm.getString("managerServlet.deployFailed", displayPath));
  832               }
  833           } catch (Throwable t) {
  834               log("ManagerServlet.install[" + displayPath + "]", t);
  835               writer.println(sm.getString("managerServlet.exception",
  836                       t.toString()));
  837           }
  838           
  839       }
  840   
  841   
  842       /**
  843        * Render a list of the currently active Contexts in our virtual host.
  844        *
  845        * @param writer Writer to render to
  846        */
  847       protected void list(PrintWriter writer) {
  848   
  849           if (debug >= 1)
  850               log("list: Listing contexts for virtual host '" +
  851                   host.getName() + "'");
  852   
  853           writer.println(sm.getString("managerServlet.listed",
  854                                       host.getName()));
  855           Container[] contexts = host.findChildren();
  856           for (int i = 0; i < contexts.length; i++) {
  857               Context context = (Context) contexts[i];
  858               String displayPath = context.getPath();
  859               if( displayPath.equals("") )
  860                   displayPath = "/";
  861               if (context != null ) {
  862                   if (context.getAvailable()) {
  863                       writer.println(sm.getString("managerServlet.listitem",
  864                                                   displayPath,
  865                                                   "running",
  866                                         "" + context.getManager().findSessions().length,
  867                                                   context.getDocBase()));
  868                   } else {
  869                       writer.println(sm.getString("managerServlet.listitem",
  870                                                   displayPath,
  871                                                   "stopped",
  872                                                   "0",
  873                                                   context.getDocBase()));
  874                   }
  875               }
  876           }
  877       }
  878   
  879   
  880       /**
  881        * Reload the web application at the specified context path.
  882        *
  883        * @param writer Writer to render to
  884        * @param path Context path of the application to be restarted
  885        */
  886       protected void reload(PrintWriter writer, String path) {
  887   
  888           if (debug >= 1)
  889               log("restart: Reloading web application at '" + path + "'");
  890   
  891           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
  892               writer.println(sm.getString("managerServlet.invalidPath",
  893                                           RequestUtil.filter(path)));
  894               return;
  895           }
  896           String displayPath = path;
  897           if( path.equals("/") )
  898               path = "";
  899   
  900           try {
  901               Context context = (Context) host.findChild(path);
  902               if (context == null) {
  903                   writer.println(sm.getString
  904                                  ("managerServlet.noContext",
  905                                      RequestUtil.filter(displayPath)));
  906                   return;
  907               }
  908               // It isn't possible for the manager to reload itself
  909               if (context.getPath().equals(this.context.getPath())) {
  910                   writer.println(sm.getString("managerServlet.noSelf"));
  911                   return;
  912               }
  913               context.reload();
  914               writer.println
  915                   (sm.getString("managerServlet.reloaded", displayPath));
  916           } catch (Throwable t) {
  917               log("ManagerServlet.reload[" + displayPath + "]", t);
  918               writer.println(sm.getString("managerServlet.exception",
  919                                           t.toString()));
  920           }
  921   
  922       }
  923   
  924   
  925       /**
  926        * Render a list of available global JNDI resources.
  927        *
  928        * @param type Fully qualified class name of the resource type of interest,
  929        *  or <code>null</code> to list resources of all types
  930        */
  931       protected void resources(PrintWriter writer, String type) {
  932   
  933           if (debug >= 1) {
  934               if (type != null) {
  935                   log("resources:  Listing resources of type " + type);
  936               } else {
  937                   log("resources:  Listing resources of all types");
  938               }
  939           }
  940   
  941           // Is the global JNDI resources context available?
  942           if (global == null) {
  943               writer.println(sm.getString("managerServlet.noGlobal"));
  944               return;
  945           }
  946   
  947           // Enumerate the global JNDI resources of the requested type
  948           if (type != null) {
  949               writer.println(sm.getString("managerServlet.resourcesType",
  950                                           type));
  951           } else {
  952               writer.println(sm.getString("managerServlet.resourcesAll"));
  953           }
  954   
  955           Class clazz = null;
  956           try {
  957               if (type != null) {
  958                   clazz = Class.forName(type);
  959               }
  960           } catch (Throwable t) {
  961               log("ManagerServlet.resources[" + type + "]", t);
  962               writer.println(sm.getString("managerServlet.exception",
  963                                           t.toString()));
  964               return;
  965           }
  966   
  967           printResources(writer, "", global, type, clazz);
  968   
  969       }
  970   
  971   
  972       /**
  973        * List the resources of the given context.
  974        */
  975       protected void printResources(PrintWriter writer, String prefix,
  976                                     javax.naming.Context namingContext,
  977                                     String type, Class clazz) {
  978   
  979           try {
  980               NamingEnumeration items = namingContext.listBindings("");
  981               while (items.hasMore()) {
  982                   Binding item = (Binding) items.next();
  983                   if (item.getObject() instanceof javax.naming.Context) {
  984                       printResources
  985                           (writer, prefix + item.getName() + "/",
  986                            (javax.naming.Context) item.getObject(), type, clazz);
  987                   } else {
  988                       if ((clazz != null) &&
  989                           (!(clazz.isInstance(item.getObject())))) {
  990                           continue;
  991                       }
  992                       writer.print(prefix + item.getName());
  993                       writer.print(':');
  994                       writer.print(item.getClassName());
  995                       // Do we want a description if available?
  996                       writer.println();
  997                   }
  998               }
  999           } catch (Throwable t) {
 1000               log("ManagerServlet.resources[" + type + "]", t);
 1001               writer.println(sm.getString("managerServlet.exception",
 1002                                           t.toString()));
 1003           }
 1004   
 1005       }
 1006   
 1007   
 1008       /**
 1009        * Render a list of security role names (and corresponding descriptions)
 1010        * from the <code>org.apache.catalina.UserDatabase</code> resource that is
 1011        * connected to the <code>users</code> resource reference.  Typically, this
 1012        * will be the global user database, but can be adjusted if you have
 1013        * different user databases for different virtual hosts.
 1014        *
 1015        * @param writer Writer to render to
 1016        */
 1017       protected void roles(PrintWriter writer) {
 1018   
 1019           if (debug >= 1) {
 1020               log("roles:  List security roles from user database");
 1021           }
 1022   
 1023           // Look up the UserDatabase instance we should use
 1024           UserDatabase database = null;
 1025           try {
 1026               InitialContext ic = new InitialContext();
 1027               database = (UserDatabase) ic.lookup("java:comp/env/users");
 1028           } catch (NamingException e) {
 1029               writer.println(sm.getString("managerServlet.userDatabaseError"));
 1030               log("java:comp/env/users", e);
 1031               return;
 1032           }
 1033           if (database == null) {
 1034               writer.println(sm.getString("managerServlet.userDatabaseMissing"));
 1035               return;
 1036           }
 1037   
 1038           // Enumerate the available roles
 1039           writer.println(sm.getString("managerServlet.rolesList"));
 1040           Iterator roles = database.getRoles();
 1041           if (roles != null) {
 1042               while (roles.hasNext()) {
 1043                   Role role = (Role) roles.next();
 1044                   writer.print(role.getRolename());
 1045                   writer.print(':');
 1046                   if (role.getDescription() != null) {
 1047                       writer.print(role.getDescription());
 1048                   }
 1049                   writer.println();
 1050               }
 1051           }
 1052   
 1053   
 1054       }
 1055   
 1056   
 1057       /**
 1058        * Writes System OS and JVM properties.
 1059        * @param writer Writer to render to
 1060        */
 1061       protected void serverinfo(PrintWriter writer) {
 1062           if (debug >= 1)
 1063               log("serverinfo");
 1064           try {
 1065               StringBuffer props = new StringBuffer();
 1066               props.append("OK - Server info");
 1067               props.append("\nTomcat Version: ");
 1068               props.append(ServerInfo.getServerInfo());
 1069               props.append("\nOS Name: ");
 1070               props.append(System.getProperty("os.name"));
 1071               props.append("\nOS Version: ");
 1072               props.append(System.getProperty("os.version"));
 1073               props.append("\nOS Architecture: ");
 1074               props.append(System.getProperty("os.arch"));
 1075               props.append("\nJVM Version: ");
 1076               props.append(System.getProperty("java.runtime.version"));
 1077               props.append("\nJVM Vendor: ");
 1078               props.append(System.getProperty("java.vm.vendor"));
 1079               writer.println(props.toString());
 1080           } catch (Throwable t) {
 1081               getServletContext().log("ManagerServlet.serverinfo",t);
 1082               writer.println(sm.getString("managerServlet.exception",
 1083                                           t.toString()));
 1084           }
 1085       }
 1086   
 1087       /**
 1088        * Session information for the web application at the specified context path.
 1089        * Displays a profile of session lastAccessedTime listing number
 1090        * of sessions for each 10 minute interval up to 10 hours.
 1091        *
 1092        * @param writer Writer to render to
 1093        * @param path Context path of the application to list session information for
 1094        * @param idle Expire all sessions with idle time &ge; idle for this context
 1095        */
 1096       protected void sessions(PrintWriter writer, String path, int idle) {
 1097   
 1098           if (debug >= 1) {
 1099               log("sessions: Session information for web application at '" + path + "'");
 1100               if (idle >= 0)
 1101                   log("sessions: Session expiration for " + idle + " minutes '" + path + "'");
 1102           }
 1103   
 1104           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
 1105               writer.println(sm.getString("managerServlet.invalidPath",
 1106                                           RequestUtil.filter(path)));
 1107               return;
 1108           }
 1109           String displayPath = path;
 1110           if( path.equals("/") )
 1111               path = "";
 1112           try {
 1113               Context context = (Context) host.findChild(path);
 1114               if (context == null) {
 1115                   writer.println(sm.getString("managerServlet.noContext",
 1116                                               RequestUtil.filter(displayPath)));
 1117                   return;
 1118               }
 1119               Manager manager = context.getManager() ;
 1120               if(manager == null) {
 1121                  writer.println(sm.getString("managerServlet.noManager",
 1122                  RequestUtil.filter(displayPath)));
 1123                  return;               
 1124               }
 1125               int maxCount = 60;
 1126               int maxInactiveInterval = manager.getMaxInactiveInterval()/60;
 1127               int histoInterval = maxInactiveInterval / maxCount;
 1128               if ( histoInterval * maxCount < maxInactiveInterval ) 
 1129                   histoInterval++;
 1130               maxCount = maxInactiveInterval / histoInterval;
 1131               if ( histoInterval * maxCount < maxInactiveInterval ) 
 1132                   maxCount++;
 1133   
 1134               writer.println(sm.getString("managerServlet.sessions", displayPath));
 1135               writer.println(sm.getString("managerServlet.sessiondefaultmax",
 1136                                   "" + maxInactiveInterval));
 1137               Session [] sessions = manager.findSessions();
 1138               int [] timeout = new int[maxCount];
 1139               int notimeout = 0;
 1140               int expired = 0;
 1141               long now = System.currentTimeMillis();
 1142               for (int i = 0; i < sessions.length; i++) {
 1143                   int time = (int)((now-sessions[i].getLastAccessedTimeInternal())/1000);
 1144                   if (idle >= 0 && time >= idle*60) {
 1145                       sessions[i].expire();
 1146                       idle++;
 1147                   }
 1148                   time=time/60/histoInterval;
 1149                   if (time < 0)
 1150                       notimeout++;
 1151                   else if (time >= maxCount)
 1152                       timeout[maxCount-1]++;
 1153                   else
 1154                       timeout[time]++;
 1155               }
 1156               if (timeout[0] > 0)
 1157                   writer.println(sm.getString("managerServlet.sessiontimeout",
 1158                                               "<" + histoInterval, "" + timeout[0]));
 1159               for (int i = 1; i < maxCount-1; i++) {
 1160                   if (timeout[i] > 0)
 1161                       writer.println(sm.getString("managerServlet.sessiontimeout",
 1162                                        "" + (i)*histoInterval + " - <" + (i+1)*histoInterval,
 1163                                                   "" + timeout[i]));
 1164               }
 1165               if (timeout[maxCount-1] > 0)
 1166                   writer.println(sm.getString("managerServlet.sessiontimeout",
 1167                                               ">=" + maxCount*histoInterval,
 1168                                               "" + timeout[maxCount-1]));
 1169               if (notimeout > 0)
 1170                   writer.println(sm.getString("managerServlet.sessiontimeout",
 1171                                               "unlimited","" + notimeout));
 1172               if (idle >= 0)
 1173                   writer.println(sm.getString("managerServlet.sessiontimeout",
 1174                                               "" + idle,"expired " + expired));
 1175           } catch (Throwable t) {
 1176               log("ManagerServlet.sessions[" + displayPath + "]", t);
 1177               writer.println(sm.getString("managerServlet.exception",
 1178                                           t.toString()));
 1179           }
 1180   
 1181       }
 1182   
 1183   
 1184       /**
 1185        * Session information for the web application at the specified context path.
 1186        * Displays a profile of session lastAccessedTime listing number
 1187        * of sessions for each 10 minute interval up to 10 hours.
 1188        *
 1189        * @param writer Writer to render to
 1190        * @param path Context path of the application to list session information for
 1191        */
 1192       protected void sessions(PrintWriter writer, String path) {
 1193           sessions(writer, path, -1);
 1194       }
 1195   
 1196   
 1197       /**
 1198        *
 1199        * Extract the expiration request parameter
 1200        *
 1201        * @param path
 1202        * @param req
 1203        */
 1204       protected void expireSessions(PrintWriter writer, String path, HttpServletRequest req) {
 1205           int idle = -1;
 1206           String idleParam = req.getParameter("idle");
 1207           if (idleParam != null) {
 1208               try {
 1209                   idle = Integer.parseInt(idleParam);
 1210               } catch (NumberFormatException e) {
 1211                   log("Could not parse idle parameter to an int: " + idleParam);
 1212               }
 1213           }
 1214           sessions(writer, path, idle);
 1215       }
 1216   
 1217       /**
 1218        * Start the web application at the specified context path.
 1219        *
 1220        * @param writer Writer to render to
 1221        * @param path Context path of the application to be started
 1222        */
 1223       protected void start(PrintWriter writer, String path) {
 1224   
 1225           if (debug >= 1)
 1226               log("start: Starting web application at '" + path + "'");
 1227   
 1228           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
 1229               writer.println(sm.getString("managerServlet.invalidPath",
 1230                                           RequestUtil.filter(path)));
 1231               return;
 1232           }
 1233           String displayPath = path;
 1234           if( path.equals("/") )
 1235               path = "";
 1236   
 1237           try {
 1238               Context context = (Context) host.findChild(path);
 1239               if (context == null) {
 1240                   writer.println(sm.getString("managerServlet.noContext", 
 1241                                               RequestUtil.filter(displayPath)));
 1242                   return;
 1243               }
 1244               ((Lifecycle) context).start();
 1245               if (context.getAvailable())
 1246                   writer.println
 1247                       (sm.getString("managerServlet.started", displayPath));
 1248               else
 1249                   writer.println
 1250                       (sm.getString("managerServlet.startFailed", displayPath));
 1251           } catch (Throwable t) {
 1252               getServletContext().log
 1253                   (sm.getString("managerServlet.startFailed", displayPath), t);
 1254               writer.println
 1255                   (sm.getString("managerServlet.startFailed", displayPath));
 1256               writer.println(sm.getString("managerServlet.exception",
 1257                                           t.toString()));
 1258           }
 1259   
 1260       }
 1261   
 1262   
 1263       /**
 1264        * Stop the web application at the specified context path.
 1265        *
 1266        * @param writer Writer to render to
 1267        * @param path Context path of the application to be stopped
 1268        */
 1269       protected void stop(PrintWriter writer, String path) {
 1270   
 1271           if (debug >= 1)
 1272               log("stop: Stopping web application at '" + path + "'");
 1273   
 1274           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
 1275               writer.println(sm.getString("managerServlet.invalidPath",
 1276                                           RequestUtil.filter(path)));
 1277               return;
 1278           }
 1279           String displayPath = path;
 1280           if( path.equals("/") )
 1281               path = "";
 1282   
 1283           try {
 1284               Context context = (Context) host.findChild(path);
 1285               if (context == null) {
 1286                   writer.println(sm.getString("managerServlet.noContext", 
 1287                                               RequestUtil.filter(displayPath)));
 1288                   return;
 1289               }
 1290               // It isn't possible for the manager to stop itself
 1291               if (context.getPath().equals(this.context.getPath())) {
 1292                   writer.println(sm.getString("managerServlet.noSelf"));
 1293                   return;
 1294               }
 1295               ((Lifecycle) context).stop();
 1296               writer.println(sm.getString("managerServlet.stopped", displayPath));
 1297           } catch (Throwable t) {
 1298               log("ManagerServlet.stop[" + displayPath + "]", t);
 1299               writer.println(sm.getString("managerServlet.exception",
 1300                                           t.toString()));
 1301           }
 1302   
 1303       }
 1304   
 1305   
 1306       /**
 1307        * Undeploy the web application at the specified context path.
 1308        *
 1309        * @param writer Writer to render to
 1310        * @param path Context path of the application to be removed
 1311        */
 1312       protected void undeploy(PrintWriter writer, String path) {
 1313   
 1314           if (debug >= 1)
 1315               log("undeploy: Undeploying web application at '" + path + "'");
 1316   
 1317           if ((path == null) || (!path.startsWith("/") && path.equals(""))) {
 1318               writer.println(sm.getString("managerServlet.invalidPath",
 1319                                           RequestUtil.filter(path)));
 1320               return;
 1321           }
 1322           String displayPath = path;
 1323           if( path.equals("/") )
 1324               path = "";
 1325   
 1326           try {
 1327   
 1328               // Validate the Context of the specified application
 1329               Context context = (Context) host.findChild(path);
 1330               if (context == null) {
 1331                   writer.println(sm.getString("managerServlet.noContext",
 1332                                               RequestUtil.filter(displayPath)));
 1333                   return;
 1334               }
 1335   
 1336               // Identify the appBase of the owning Host of this Context (if any)
 1337               String appBase = null;
 1338               File appBaseDir = null;
 1339               if (context.getParent() instanceof Host) {
 1340                   appBase = ((Host) context.getParent()).getAppBase();
 1341                   appBaseDir = new File(appBase);
 1342                   if (!appBaseDir.isAbsolute()) {
 1343                       appBaseDir = new File(System.getProperty("catalina.base"),
 1344                                             appBase);
 1345                   }
 1346               }
 1347   
 1348               if (!isDeployed(path)) {
 1349                   writer.println(sm.getString("managerServlet.notDeployed",
 1350                           RequestUtil.filter(displayPath)));
 1351                   return;
 1352               }
 1353   
 1354               if (!isServiced(path)) {
 1355                   addServiced(path);
 1356                   try {
 1357                       // Try to stop the context first to be nicer
 1358                       ((Lifecycle) context).stop();
 1359                   } catch (Throwable t) {
 1360                       // Ignore
 1361                   }
 1362                   try {
 1363                       File war = new File(getAppBase(), getDocBase(path) + ".war");
 1364                       File dir = new File(getAppBase(), getDocBase(path));
 1365                       File xml = new File(configBase, getConfigFile(path) + ".xml");
 1366                       if (war.exists()) {
 1367                           war.delete();
 1368                       } else if (dir.exists()) {
 1369                           undeployDir(dir);
 1370                       } else {
 1371                           xml.delete();
 1372                       }
 1373                       // Perform new deployment
 1374                       check(path);
 1375                   } finally {
 1376                       removeServiced(path);
 1377                   }
 1378               }
 1379               writer.println(sm.getString("managerServlet.undeployed",
 1380                                           displayPath));
 1381           } catch (Throwable t) {
 1382               log("ManagerServlet.undeploy[" + displayPath + "]", t);
 1383               writer.println(sm.getString("managerServlet.exception",
 1384                                           t.toString()));
 1385           }
 1386   
 1387       }
 1388   
 1389   
 1390       // -------------------------------------------------------- Support Methods
 1391   
 1392   
 1393       /**
 1394        * Given a context path, get the config file name.
 1395        */
 1396       protected String getConfigFile(String path) {
 1397           String basename = null;
 1398           if (path.equals("")) {
 1399               basename = "ROOT";
 1400           } else {
 1401               basename = path.substring(1).replace('/', '#');
 1402           }
 1403           return (basename);
 1404       }
 1405   
 1406   
 1407       /**
 1408        * Given a context path, get the config file name.
 1409        */
 1410       protected String getDocBase(String path) {
 1411           String basename = null;
 1412           if (path.equals("")) {
 1413               basename = "ROOT";
 1414           } else {
 1415               basename = path.substring(1);
 1416           }
 1417           return (basename);
 1418       }
 1419   
 1420       
 1421       /**
 1422        * Return a File object representing the "application root" directory
 1423        * for our associated Host.
 1424        */
 1425       protected File getAppBase() {
 1426   
 1427           if (appBase != null) {
 1428               return appBase;
 1429           }
 1430   
 1431           File file = new File(host.getAppBase());
 1432           if (!file.isAbsolute())
 1433               file = new File(System.getProperty("catalina.base"),
 1434                               host.getAppBase());
 1435           try {
 1436               appBase = file.getCanonicalFile();
 1437           } catch (IOException e) {
 1438               appBase = file;
 1439           }
 1440           return (appBase);
 1441   
 1442       }
 1443   
 1444   
 1445       /**
 1446        * Invoke the isDeployed method on the deployer.
 1447        */
 1448       protected boolean isDeployed(String name) 
 1449           throws Exception {
 1450           String[] params = { name };
 1451           String[] signature = { "java.lang.String" };
 1452           Boolean result = 
 1453               (Boolean) mBeanServer.invoke(oname, "isDeployed", params, signature);
 1454           return result.booleanValue();
 1455       }
 1456       
 1457   
 1458       /**
 1459        * Invoke the check method on the deployer.
 1460        */
 1461       protected void check(String name) 
 1462           throws Exception {
 1463           String[] params = { name };
 1464           String[] signature = { "java.lang.String" };
 1465           mBeanServer.invoke(oname, "check", params, signature);
 1466       }
 1467       
 1468   
 1469       /**
 1470        * Invoke the isServiced method on the deployer.
 1471        */
 1472       protected boolean isServiced(String name) 
 1473           throws Exception {
 1474           String[] params = { name };
 1475           String[] signature = { "java.lang.String" };
 1476           Boolean result = 
 1477               (Boolean) mBeanServer.invoke(oname, "isServiced", params, signature);
 1478           return result.booleanValue();
 1479       }
 1480       
 1481   
 1482       /**
 1483        * Invoke the addServiced method on the deployer.
 1484        */
 1485       protected void addServiced(String name) 
 1486           throws Exception {
 1487           String[] params = { name };
 1488           String[] signature = { "java.lang.String" };
 1489           mBeanServer.invoke(oname, "addServiced", params, signature);
 1490       }
 1491       
 1492   
 1493       /**
 1494        * Invoke the removeServiced method on the deployer.
 1495        */
 1496       protected void removeServiced(String name) 
 1497           throws Exception {
 1498           String[] params = { name };
 1499           String[] signature = { "java.lang.String" };
 1500           mBeanServer.invoke(oname, "removeServiced", params, signature);
 1501       }
 1502       
 1503   
 1504       /**
 1505        * Delete the specified directory, including all of its contents and
 1506        * subdirectories recursively.
 1507        *
 1508        * @param dir File object representing the directory to be deleted
 1509        */
 1510       protected void undeployDir(File dir) {
 1511   
 1512           String files[] = dir.list();
 1513           if (files == null) {
 1514               files = new String[0];
 1515           }
 1516           for (int i = 0; i < files.length; i++) {
 1517               File file = new File(dir, files[i]);
 1518               if (file.isDirectory()) {
 1519                   undeployDir(file);
 1520               } else {
 1521                   file.delete();
 1522               }
 1523           }
 1524           dir.delete();
 1525   
 1526       }
 1527   
 1528   
 1529       /**
 1530        * Upload the WAR file included in this request, and store it at the
 1531        * specified file location.
 1532        *
 1533        * @param request The servlet request we are processing
 1534        * @param war The file into which we should store the uploaded WAR
 1535        *
 1536        * @exception IOException if an I/O error occurs during processing
 1537        */
 1538       protected void uploadWar(HttpServletRequest request, File war)
 1539           throws IOException {
 1540   
 1541           war.delete();
 1542           ServletInputStream istream = null;
 1543           BufferedOutputStream ostream = null;
 1544           try {
 1545               istream = request.getInputStream();
 1546               ostream =
 1547                   new BufferedOutputStream(new FileOutputStream(war), 1024);
 1548               byte buffer[] = new byte[1024];
 1549               while (true) {
 1550                   int n = istream.read(buffer);
 1551                   if (n < 0) {
 1552                       break;
 1553                   }
 1554                   ostream.write(buffer, 0, n);
 1555               }
 1556               ostream.flush();
 1557               ostream.close();
 1558               ostream = null;
 1559               istream.close();
 1560               istream = null;
 1561           } catch (IOException e) {
 1562               war.delete();
 1563               throw e;
 1564           } finally {
 1565               if (ostream != null) {
 1566                   try {
 1567                       ostream.close();
 1568                   } catch (Throwable t) {
 1569                       ;
 1570                   }
 1571                   ostream = null;
 1572               }
 1573               if (istream != null) {
 1574                   try {
 1575                       istream.close();
 1576                   } catch (Throwable t) {
 1577                       ;
 1578                   }
 1579                   istream = null;
 1580               }
 1581           }
 1582   
 1583       }
 1584   
 1585   
 1586       /**
 1587        * Copy the specified file or directory to the destination.
 1588        *
 1589        * @param src File object representing the source
 1590        * @param dest File object representing the destination
 1591        */
 1592       public static boolean copy(File src, File dest) {
 1593           boolean result = false;
 1594           try {
 1595               if( src != null &&
 1596                       !src.getCanonicalPath().equals(dest.getCanonicalPath()) ) {
 1597                   result = copyInternal(src, dest, new byte[4096]);
 1598               }
 1599           } catch (IOException e) {
 1600               e.printStackTrace();
 1601           }
 1602           return result;
 1603       }
 1604   
 1605       
 1606       /**
 1607        * Copy the specified file or directory to the destination.
 1608        *
 1609        * @param src File object representing the source
 1610        * @param dest File object representing the destination
 1611        */
 1612       public static boolean copyInternal(File src, File dest, byte[] buf) {
 1613           
 1614           boolean result = true;
 1615           
 1616           String files[] = null;
 1617           if (src.isDirectory()) {
 1618               files = src.list();
 1619               result = dest.mkdir();
 1620           } else {
 1621               files = new String[1];
 1622               files[0] = "";
 1623           }
 1624           if (files == null) {
 1625               files = new String[0];
 1626           }
 1627           for (int i = 0; (i < files.length) && result; i++) {
 1628               File fileSrc = new File(src, files[i]);
 1629               File fileDest = new File(dest, files[i]);
 1630               if (fileSrc.isDirectory()) {
 1631                   result = copyInternal(fileSrc, fileDest, buf);
 1632               } else {
 1633                   FileInputStream is = null;
 1634                   FileOutputStream os = null;
 1635                   try {
 1636                       is = new FileInputStream(fileSrc);
 1637                       os = new FileOutputStream(fileDest);
 1638                       int len = 0;
 1639                       while (true) {
 1640                           len = is.read(buf);
 1641                           if (len == -1)
 1642                               break;
 1643                           os.write(buf, 0, len);
 1644                       }
 1645                   } catch (IOException e) {
 1646                       e.printStackTrace();
 1647                       result = false;
 1648                   } finally {
 1649                       if (is != null) {
 1650                           try {
 1651                               is.close();
 1652                           } catch (IOException e) {
 1653                           }
 1654                       }
 1655                       if (os != null) {
 1656                           try {
 1657                               os.close();
 1658                           } catch (IOException e) {
 1659                           }
 1660                       }
 1661                   }
 1662               }
 1663           }
 1664           return result;
 1665           
 1666       }
 1667       
 1668       
 1669   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » manager » [javadoc | source]