KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > mbeanserver > MXBeanLookup


1 /*
2  * @(#)MXBeanLookup.java 1.15 07/09/11
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.jmx.mbeanserver;
9
10 import static com.sun.jmx.mbeanserver.Util.*;
11 import java.util.Map JavaDoc;
12 import java.lang.ref.WeakReference JavaDoc;
13 import java.lang.reflect.InvocationHandler JavaDoc;
14 import java.lang.reflect.Proxy JavaDoc;
15 import java.security.AccessController JavaDoc;
16 import javax.management.InstanceAlreadyExistsException JavaDoc;
17 import javax.management.JMX JavaDoc;
18 import javax.management.MBeanServerConnection JavaDoc;
19 import javax.management.MBeanServerInvocationHandler JavaDoc;
20 import javax.management.ObjectName JavaDoc;
21
22 /**
23  * @since 1.6
24  */

25
26 /*
27  * This class handles the mapping between MXBean references and
28  * ObjectNames. Consider an MXBean interface like this:
29  *
30  * public interface ModuleMXBean {
31  * ProductMXBean getProduct();
32  * void setProduct(ProductMXBean product);
33  * }
34  *
35  * This defines an attribute called "Product" whose originalType will
36  * be ProductMXBean and whose openType will be ObjectName. The
37  * mapping happens as follows.
38  *
39  * When the MXBean's getProduct method is called, it is supposed to
40  * return a reference to another MXBean, or a proxy for another
41  * MXBean. The MXBean layer has to convert this into an ObjectName.
42  * If it's a reference to another MXBean, it needs to be able to look
43  * up the name under which that MXBean has been registered in this
44  * MBeanServer; this is the purpose of the mxbeanToObjectName map. If
45  * it's a proxy, it can check that the MBeanServer matches and if so
46  * extract the ObjectName from the proxy.
47  *
48  * When the setProduct method is called on a proxy for this MXBean,
49  * the argument can be either an MXBean reference (only really logical
50  * if the proxy has a local MBeanServer) or another proxy. So the
51  * mapping logic is the same as for getProduct on the MXBean.
52  *
53  * When the MXBean's setProduct method is called, it needs to convert
54  * the ObjectName into an object implementing the ProductMXBean
55  * interface. We could have a lookup table that reverses
56  * mxbeanToObjectName, but this could violate the general JMX property
57  * that you cannot obtain a reference to an MBean object. So we
58  * always use a proxy for this. However we do have an
59  * objectNameToProxy map that allows us to reuse proxy instances.
60  *
61  * When the getProduct method is called on a proxy for this MXBean, it
62  * must convert the returned ObjectName into an instance of
63  * ProductMXBean. Again it can do this by making a proxy.
64  *
65  * From the above, it is clear that the logic for getX on an MXBean is
66  * the same as for setX on a proxy, and vice versa.
67  */

68 public class MXBeanLookup {
69     private MXBeanLookup(MBeanServerConnection JavaDoc mbsc) {
70     this.mbsc = mbsc;
71     }
72
73     static MXBeanLookup lookupFor(MBeanServerConnection JavaDoc mbsc) {
74         synchronized (mbscToLookup) {
75             WeakReference JavaDoc<MXBeanLookup> weakLookup = mbscToLookup.get(mbsc);
76             MXBeanLookup lookup = (weakLookup == null) ? null : weakLookup.get();
77             if (lookup == null) {
78                 lookup = new MXBeanLookup(mbsc);
79                 mbscToLookup.put(mbsc, new WeakReference JavaDoc<MXBeanLookup>(lookup));
80             }
81             return lookup;
82         }
83     }
84
85     synchronized <T> T objectNameToMXBean(ObjectName JavaDoc name, Class JavaDoc<T> type) {
86         WeakReference JavaDoc<Object JavaDoc> wr = objectNameToProxy.get(name);
87     if (wr != null) {
88         Object JavaDoc proxy = wr.get();
89         if (type.isInstance(proxy))
90         return type.cast(proxy);
91     }
92     InvocationHandler JavaDoc handler =
93         new MBeanServerInvocationHandler JavaDoc(mbsc, name);
94     T proxy = JMX.newMXBeanProxy(mbsc, name, type);
95     objectNameToProxy.put(name, new WeakReference JavaDoc<Object JavaDoc>(proxy));
96     return proxy;
97     }
98
99     synchronized ObjectName JavaDoc mxbeanToObjectName(Object JavaDoc mxbean) {
100         if (mxbean instanceof Proxy JavaDoc) {
101         InvocationHandler JavaDoc ih = Proxy.getInvocationHandler(mxbean);
102         if (ih instanceof MBeanServerInvocationHandler JavaDoc) {
103                 MBeanServerInvocationHandler JavaDoc mbsih =
104                         (MBeanServerInvocationHandler JavaDoc) ih;
105                 if (mbsih.getMBeanServerConnection().equals(mbsc))
106                     return mbsih.getObjectName();
107             }
108             return null;
109         } else
110             return mxbeanToObjectName.get(mxbean);
111     }
112
113     synchronized void addReference(ObjectName JavaDoc name, Object JavaDoc mxbean)
114     throws InstanceAlreadyExistsException JavaDoc {
115         ObjectName JavaDoc existing = mxbeanToObjectName.get(mxbean);
116         if (existing != null) {
117             String JavaDoc multiname = AccessController.doPrivileged(
118                     new GetPropertyAction("jmx.mxbean.multiname"));
119             if (!"true".equalsIgnoreCase(multiname)) {
120                 throw new InstanceAlreadyExistsException JavaDoc(
121                         "MXBean already registered with name " + existing);
122             }
123         }
124         mxbeanToObjectName.put(mxbean, name);
125     }
126
127     synchronized boolean removeReference(ObjectName JavaDoc name, Object JavaDoc mxbean) {
128         if (name.equals(mxbeanToObjectName.get(mxbean))) {
129             mxbeanToObjectName.remove(mxbean);
130             return true;
131         } else
132             return false;
133         /* removeReference can be called when the above condition fails,
134          * notably if you try to register the same MXBean twice.
135          */

136     }
137
138     private final MBeanServerConnection JavaDoc mbsc;
139     private final WeakIdentityHashMap<Object JavaDoc, ObjectName JavaDoc>
140         mxbeanToObjectName = WeakIdentityHashMap.make();
141     private final Map JavaDoc<ObjectName JavaDoc, WeakReference JavaDoc<Object JavaDoc>>
142         objectNameToProxy = newMap();
143     private static WeakIdentityHashMap<MBeanServerConnection JavaDoc,
144                                        WeakReference JavaDoc<MXBeanLookup>>
145         mbscToLookup = WeakIdentityHashMap.make();
146 }
147
Popular Tags