1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.jmx;
20
21 import java.io.IOException;
22 import java.util.HashMap;
23 import java.util.Locale;
24 import java.util.Map;
25 import java.util.WeakHashMap;
26
27 import javax.management.InstanceNotFoundException;
28 import javax.management.MBeanRegistrationException;
29 import javax.management.MBeanServer;
30 import javax.management.ObjectInstance;
31 import javax.management.ObjectName;
32
33 import org.eclipse.jetty.util.component.Container;
34 import org.eclipse.jetty.util.component.ContainerLifeCycle;
35 import org.eclipse.jetty.util.component.Dumpable;
36 import org.eclipse.jetty.util.log.Log;
37 import org.eclipse.jetty.util.log.Logger;
38
39
40
41
42 public class MBeanContainer implements Container.InheritedListener, Dumpable
43 {
44 private final static Logger LOG = Log.getLogger(MBeanContainer.class.getName());
45
46 private final MBeanServer _mbeanServer;
47 private final WeakHashMap<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>();
48 private final HashMap<String, Integer> _unique = new HashMap<String, Integer>();
49 private String _domain = null;
50
51
52
53
54
55
56
57 public synchronized ObjectName findMBean(Object object)
58 {
59 ObjectName bean = _beans.get(object);
60 return bean == null ? null : bean;
61 }
62
63
64
65
66
67
68
69 public synchronized Object findBean(ObjectName oname)
70 {
71 for (Map.Entry<Object, ObjectName> entry : _beans.entrySet())
72 {
73 ObjectName bean = entry.getValue();
74 if (bean.equals(oname))
75 return entry.getKey();
76 }
77 return null;
78 }
79
80
81
82
83
84
85 public MBeanContainer(MBeanServer server)
86 {
87 _mbeanServer = server;
88 }
89
90
91
92
93
94
95 public MBeanServer getMBeanServer()
96 {
97 return _mbeanServer;
98 }
99
100
101
102
103
104
105 public void setDomain(String domain)
106 {
107 _domain = domain;
108 }
109
110
111
112
113
114
115 public String getDomain()
116 {
117 return _domain;
118 }
119
120
121 @Override
122 public void beanAdded(Container parent, Object obj)
123 {
124 LOG.debug("beanAdded {}->{}",parent,obj);
125
126
127 ObjectName pname=null;
128 if (parent!=null)
129 {
130 pname=_beans.get(parent);
131 if (pname==null)
132 {
133
134 beanAdded(null,parent);
135 pname=_beans.get(parent);
136 }
137 }
138
139
140 if (obj == null || _beans.containsKey(obj))
141 return;
142
143 try
144 {
145
146 Object mbean = ObjectMBean.mbeanFor(obj);
147 if (mbean == null)
148 return;
149
150
151 ObjectName oname = null;
152 if (mbean instanceof ObjectMBean)
153 {
154 ((ObjectMBean)mbean).setMBeanContainer(this);
155 oname = ((ObjectMBean)mbean).getObjectName();
156 }
157
158
159 if (oname == null)
160 {
161
162 String domain = _domain;
163 if (domain == null)
164 domain = obj.getClass().getPackage().getName();
165
166
167 String type = obj.getClass().getName().toLowerCase(Locale.ENGLISH);
168 int dot = type.lastIndexOf('.');
169 if (dot >= 0)
170 type = type.substring(dot + 1);
171
172
173 StringBuffer buf = new StringBuffer();
174
175 String context = (mbean instanceof ObjectMBean)?makeName(((ObjectMBean)mbean).getObjectContextBasis()):null;
176 if (context==null && pname!=null)
177 context=pname.getKeyProperty("context");
178
179 if (context != null && context.length()>1)
180 buf.append("context=").append(context).append(",");
181
182 buf.append("type=").append(type);
183
184 String name = (mbean instanceof ObjectMBean)?makeName(((ObjectMBean)mbean).getObjectNameBasis()):context;
185 if (name != null && name.length()>1)
186 buf.append(",").append("name=").append(name);
187
188 String basis = buf.toString();
189 Integer count = _unique.get(basis);
190 count = count == null ? 0 : 1 + count;
191 _unique.put(basis, count);
192
193 oname = ObjectName.getInstance(domain + ":" + basis + ",id=" + count);
194 }
195
196 ObjectInstance oinstance = _mbeanServer.registerMBean(mbean, oname);
197 LOG.debug("Registered {}", oinstance.getObjectName());
198 _beans.put(obj, oinstance.getObjectName());
199
200 }
201 catch (Exception e)
202 {
203 LOG.warn("bean: " + obj, e);
204 }
205 }
206
207 @Override
208 public void beanRemoved(Container parent, Object obj)
209 {
210 LOG.debug("beanRemoved {}",obj);
211 ObjectName bean = _beans.remove(obj);
212
213 if (bean != null)
214 {
215 try
216 {
217 _mbeanServer.unregisterMBean(bean);
218 LOG.debug("Unregistered {}", bean);
219 }
220 catch (javax.management.InstanceNotFoundException e)
221 {
222 LOG.ignore(e);
223 }
224 catch (Exception e)
225 {
226 LOG.warn(e);
227 }
228 }
229 }
230
231
232
233
234
235 public String makeName(String basis)
236 {
237 if (basis==null)
238 return basis;
239 return basis.replace(':', '_').replace('*', '_').replace('?', '_').replace('=', '_').replace(',', '_').replace(' ', '_');
240 }
241
242 @Override
243 public void dump(Appendable out, String indent) throws IOException
244 {
245 ContainerLifeCycle.dumpObject(out,this);
246 ContainerLifeCycle.dump(out, indent, _beans.entrySet());
247 }
248
249 @Override
250 public String dump()
251 {
252 return ContainerLifeCycle.dump(this);
253 }
254
255 public void destroy()
256 {
257 for (ObjectName oname : _beans.values())
258 if (oname!=null)
259 {
260 try
261 {
262 _mbeanServer.unregisterMBean(oname);
263 }
264 catch (MBeanRegistrationException | InstanceNotFoundException e)
265 {
266 LOG.warn(e);
267 }
268 }
269 }
270 }