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.ArrayList;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.WeakHashMap;
31
32 import javax.management.MBeanServer;
33 import javax.management.ObjectInstance;
34 import javax.management.ObjectName;
35
36 import org.eclipse.jetty.util.component.AbstractLifeCycle;
37 import org.eclipse.jetty.util.component.AggregateLifeCycle;
38 import org.eclipse.jetty.util.component.Container;
39 import org.eclipse.jetty.util.component.Container.Relationship;
40 import org.eclipse.jetty.util.component.Dumpable;
41 import org.eclipse.jetty.util.log.Log;
42 import org.eclipse.jetty.util.log.Logger;
43 import org.eclipse.jetty.util.log.StdErrLog;
44 import org.eclipse.jetty.util.thread.ShutdownThread;
45
46
47
48
49 public class MBeanContainer extends AbstractLifeCycle implements Container.Listener, Dumpable
50 {
51 private final static Logger LOG = Log.getLogger(MBeanContainer.class.getName());
52
53 private final MBeanServer _server;
54 private final WeakHashMap<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>();
55 private final HashMap<String, Integer> _unique = new HashMap<String, Integer>();
56 private final WeakHashMap<ObjectName,List<Container.Relationship>> _relations = new WeakHashMap<ObjectName,List<Container.Relationship>>();
57 private String _domain = null;
58
59
60
61
62
63
64
65 public synchronized ObjectName findMBean(Object object)
66 {
67 ObjectName bean = _beans.get(object);
68 return bean == null ? null : bean;
69 }
70
71
72
73
74
75
76
77 public synchronized Object findBean(ObjectName oname)
78 {
79 for (Map.Entry<Object, ObjectName> entry : _beans.entrySet())
80 {
81 ObjectName bean = entry.getValue();
82 if (bean.equals(oname))
83 return entry.getKey();
84 }
85 return null;
86 }
87
88
89
90
91
92
93 public MBeanContainer(MBeanServer server)
94 {
95 _server = server;
96 }
97
98
99
100
101
102
103 public MBeanServer getMBeanServer()
104 {
105 return _server;
106 }
107
108
109
110
111
112
113 public void setDomain(String domain)
114 {
115 _domain = domain;
116 }
117
118
119
120
121
122
123 public String getDomain()
124 {
125 return _domain;
126 }
127
128
129
130
131
132
133 public synchronized void add(Relationship relationship)
134 {
135 LOG.debug("add {}",relationship);
136 ObjectName parent = _beans.get(relationship.getParent());
137 if (parent == null)
138 {
139 addBean(relationship.getParent());
140 parent = _beans.get(relationship.getParent());
141 }
142
143 ObjectName child = _beans.get(relationship.getChild());
144 if (child == null)
145 {
146 addBean(relationship.getChild());
147 child = _beans.get(relationship.getChild());
148 }
149
150 if (parent != null && child != null)
151 {
152 List<Container.Relationship> rels = _relations.get(parent);
153 if (rels==null)
154 {
155 rels=new ArrayList<Container.Relationship>();
156 _relations.put(parent,rels);
157 }
158 rels.add(relationship);
159 }
160 }
161
162
163
164
165
166
167 public synchronized void remove(Relationship relationship)
168 {
169 LOG.debug("remove {}",relationship);
170 ObjectName parent = _beans.get(relationship.getParent());
171 ObjectName child = _beans.get(relationship.getChild());
172
173 if (parent != null && child != null)
174 {
175 List<Container.Relationship> rels = _relations.get(parent);
176 if (rels!=null)
177 {
178 for (Iterator<Container.Relationship> i=rels.iterator();i.hasNext();)
179 {
180 Container.Relationship r = i.next();
181 if (relationship.equals(r) || r.getChild()==null)
182 i.remove();
183 }
184 }
185 }
186 }
187
188
189
190
191
192
193 public synchronized void removeBean(Object obj)
194 {
195 LOG.debug("removeBean {}",obj);
196 ObjectName bean = _beans.remove(obj);
197
198 if (bean != null)
199 {
200 List<Container.Relationship> beanRelations= _relations.remove(bean);
201 if (beanRelations != null)
202 {
203 LOG.debug("Unregister {}", beanRelations);
204 List<?> removeList = new ArrayList<Object>(beanRelations);
205 for (Object r : removeList)
206 {
207 Container.Relationship relation = (Relationship)r;
208 relation.getContainer().update(relation.getParent(), relation.getChild(), null, relation.getRelationship(), true);
209 }
210 }
211
212 try
213 {
214 _server.unregisterMBean(bean);
215 LOG.debug("Unregistered {}", bean);
216 }
217 catch (javax.management.InstanceNotFoundException e)
218 {
219 LOG.ignore(e);
220 }
221 catch (Exception e)
222 {
223 LOG.warn(e);
224 }
225 }
226 }
227
228
229
230
231
232
233 public synchronized void addBean(Object obj)
234 {
235 LOG.debug("addBean {}",obj);
236 try
237 {
238 if (obj == null || _beans.containsKey(obj))
239 return;
240
241 Object mbean = ObjectMBean.mbeanFor(obj);
242 if (mbean == null)
243 return;
244
245 ObjectName oname = null;
246 if (mbean instanceof ObjectMBean)
247 {
248 ((ObjectMBean)mbean).setMBeanContainer(this);
249 oname = ((ObjectMBean)mbean).getObjectName();
250 }
251
252
253 if (oname == null)
254 {
255 String type = obj.getClass().getName().toLowerCase(Locale.ENGLISH);
256 int dot = type.lastIndexOf('.');
257 if (dot >= 0)
258 type = type.substring(dot + 1);
259
260 String context = null;
261 if (mbean instanceof ObjectMBean)
262 {
263 context = makeName(((ObjectMBean)mbean).getObjectContextBasis());
264 }
265
266 String name = null;
267 if (mbean instanceof ObjectMBean)
268 {
269 name = makeName(((ObjectMBean)mbean).getObjectNameBasis());
270 }
271
272 StringBuffer buf = new StringBuffer();
273 buf.append("type=").append(type);
274 if (context != null && context.length()>1)
275 {
276 buf.append(buf.length()>0 ? ",":"");
277 buf.append("context=").append(context);
278 }
279 if (name != null && name.length()>1)
280 {
281 buf.append(buf.length()>0 ? ",":"");
282 buf.append("name=").append(name);
283 }
284
285 String basis = buf.toString();
286 Integer count = _unique.get(basis);
287 count = count == null ? 0 : 1 + count;
288 _unique.put(basis, count);
289
290
291 String domain = _domain;
292 if (domain == null)
293 domain = obj.getClass().getPackage().getName();
294
295 oname = ObjectName.getInstance(domain + ":" + basis + ",id=" + count);
296 }
297
298 ObjectInstance oinstance = _server.registerMBean(mbean, oname);
299 LOG.debug("Registered {}", oinstance.getObjectName());
300 _beans.put(obj, oinstance.getObjectName());
301
302 }
303 catch (Exception e)
304 {
305 LOG.warn("bean: " + obj, e);
306 }
307 }
308
309
310
311
312
313 public String makeName(String basis)
314 {
315 if (basis==null)
316 return basis;
317 return basis.replace(':', '_').replace('*', '_').replace('?', '_').replace('=', '_').replace(',', '_').replace(' ', '_');
318 }
319
320
321
322
323
324
325 public void doStart()
326 {
327 ShutdownThread.register(this);
328 }
329
330
331
332
333
334
335 public void doStop()
336 {
337 Set<Object> removeSet = new HashSet<Object>(_beans.keySet());
338 for (Object removeObj : removeSet)
339 {
340 removeBean(removeObj);
341 }
342 }
343
344 public void dump(Appendable out, String indent) throws IOException
345 {
346 AggregateLifeCycle.dumpObject(out,this);
347 AggregateLifeCycle.dump(out, indent, _beans.entrySet());
348 }
349
350 public String dump()
351 {
352 return AggregateLifeCycle.dump(this);
353 }
354 }