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