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 package org.apache.catalina.mbeans;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import javax.management.MBeanException;
23 import javax.management.MalformedObjectNameException;
24 import javax.management.ObjectName;
25
26 import org.apache.catalina.Container;
27 import org.apache.catalina.ContainerListener;
28 import org.apache.catalina.JmxEnabled;
29 import org.apache.catalina.LifecycleException;
30 import org.apache.catalina.LifecycleListener;
31 import org.apache.catalina.Valve;
32 import org.apache.catalina.core.ContainerBase;
33 import org.apache.catalina.core.StandardContext;
34 import org.apache.catalina.core.StandardHost;
35 import org.apache.catalina.startup.ContextConfig;
36 import org.apache.catalina.startup.HostConfig;
37
38 public class ContainerMBean extends BaseCatalinaMBean<ContainerBase> {
39
40     /**
41      * Add a new child Container to those associated with this Container,
42      * if supported. Won't start the child yet. Has to be started with a call to
43      * Start method after necessary configurations are done.
44      *
45      * @param type ClassName of the child to be added
46      * @param name Name of the child to be added
47      *
48      * @exception MBeanException if the child cannot be added
49      */

50     public void addChild(String type, String name) throws MBeanException{
51
52         Container contained = (Container) newInstance(type);
53         contained.setName(name);
54
55         if(contained instanceof StandardHost){
56             HostConfig config = new HostConfig();
57             contained.addLifecycleListener(config);
58         } else if(contained instanceof StandardContext){
59             ContextConfig config = new ContextConfig();
60             contained.addLifecycleListener(config);
61         }
62
63         boolean oldValue= true;
64
65         ContainerBase container = doGetManagedResource();
66         try {
67             oldValue = container.getStartChildren();
68             container.setStartChildren(false);
69             container.addChild(contained);
70             contained.init();
71         } catch (LifecycleException e){
72             throw new MBeanException(e);
73         } finally {
74             if(container != null) {
75                 container.setStartChildren(oldValue);
76             }
77         }
78     }
79
80
81     /**
82      * Remove an existing child Container from association with this parent
83      * Container.
84      *
85      * @param name Name of the existing child Container to be removed
86      * @throws MBeanException if the child cannot be removed
87      */

88     public void removeChild(String name) throws MBeanException{
89         if (name != null) {
90             Container container = doGetManagedResource();
91             Container contained = container.findChild(name);
92             container.removeChild(contained);
93         }
94     }
95
96
97     /**
98      * Adds a valve to this Container instance.
99      *
100      * @param valveType ClassName of the valve to be added
101      * @return the MBean name of the new valve
102      * @throws MBeanException if adding the valve failed
103      */

104     public String addValve(String valveType) throws MBeanException{
105         Valve valve = (Valve) newInstance(valveType);
106
107         Container container = doGetManagedResource();
108         container.getPipeline().addValve(valve);
109
110         if (valve instanceof JmxEnabled) {
111             return ((JmxEnabled)valve).getObjectName().toString();
112         } else {
113             return null;
114         }
115     }
116
117
118     /**
119      * Remove an existing Valve.
120      *
121      * @param valveName MBean Name of the Valve to remove
122      *
123      * @exception MBeanException if a component cannot be removed
124      */

125     public void removeValve(String valveName) throws MBeanException{
126         Container container = doGetManagedResource();
127
128         ObjectName oname;
129         try {
130             oname = new ObjectName(valveName);
131         } catch (MalformedObjectNameException e) {
132             throw new MBeanException(e);
133         } catch (NullPointerException e) {
134             throw new MBeanException(e);
135         }
136
137         if (container != null) {
138             Valve[] valves = container.getPipeline().getValves();
139             for (int i = 0; i < valves.length; i++) {
140                 if (valves[i] instanceof JmxEnabled) {
141                     ObjectName voname = ((JmxEnabled) valves[i]).getObjectName();
142                     if (voname.equals(oname)) {
143                         container.getPipeline().removeValve(valves[i]);
144                     }
145                 }
146             }
147         }
148     }
149
150
151     /**
152      * Add a LifecycleEvent listener to this component.
153      *
154      * @param type ClassName of the listener to add
155      * @throws MBeanException if adding the listener failed
156      */

157     public void addLifecycleListener(String type) throws MBeanException{
158         LifecycleListener listener = (LifecycleListener) newInstance(type);
159         Container container = doGetManagedResource();
160         container.addLifecycleListener(listener);
161     }
162
163
164     /**
165      * Remove a LifecycleEvent listeners from this component.
166      *
167      * @param type The ClassName of the listeners to be removed.
168      * Note that all the listeners having given ClassName will be removed.
169      * @throws MBeanException propagated from the managed resource access
170      */

171     public void removeLifecycleListeners(String type) throws MBeanException{
172         Container container = doGetManagedResource();
173
174         LifecycleListener[] listeners = container.findLifecycleListeners();
175         for (LifecycleListener listener : listeners){
176             if (listener.getClass().getName().equals(type)) {
177                 container.removeLifecycleListener(listener);
178             }
179         }
180     }
181
182
183     /**
184      * List the class name of each of the lifecycle listeners added to this
185      * container.
186      * @return the lifecycle listeners class names
187      * @throws MBeanException propagated from the managed resource access
188      */

189     public String[] findLifecycleListenerNames() throws MBeanException {
190         Container container = doGetManagedResource();
191         List<String> result = new ArrayList<>();
192
193         LifecycleListener[] listeners = container.findLifecycleListeners();
194         for(LifecycleListener listener: listeners){
195             result.add(listener.getClass().getName());
196         }
197
198         return result.toArray(new String[result.size()]);
199     }
200
201
202     /**
203      * List the class name of each of the container listeners added to this
204      * container.
205      * @return the container listeners class names
206      * @throws MBeanException propagated from the managed resource access
207      */

208     public String[] findContainerListenerNames() throws MBeanException {
209         Container container = doGetManagedResource();
210         List<String> result = new ArrayList<>();
211
212         ContainerListener[] listeners = container.findContainerListeners();
213         for(ContainerListener listener: listeners){
214             result.add(listener.getClass().getName());
215         }
216
217         return result.toArray(new String[result.size()]);
218     }
219 }
220