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