1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * 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
18 package org.apache.geronimo.system.jmx;
19
20 import java.util.Iterator;
21 import javax.management.Attribute;
22 import javax.management.AttributeList;
23 import javax.management.AttributeNotFoundException;
24 import javax.management.DynamicMBean;
25 import javax.management.JMException;
26 import javax.management.ListenerNotFoundException;
27 import javax.management.MBeanInfo;
28 import javax.management.MBeanNotificationInfo;
29 import javax.management.Notification;
30 import javax.management.NotificationBroadcasterSupport;
31 import javax.management.NotificationEmitter;
32 import javax.management.NotificationFilter;
33 import javax.management.NotificationListener;
34 import javax.management.ObjectName;
35 import javax.management.ReflectionException;
36 import javax.management.MBeanRegistration;
37 import javax.management.MBeanServer;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.geronimo.gbean.GOperationSignature;
42 import org.apache.geronimo.gbean.AbstractName;
43 import org.apache.geronimo.gbean.AbstractNameQuery;
44 import org.apache.geronimo.kernel.NoSuchAttributeException;
45 import org.apache.geronimo.kernel.NoSuchOperationException;
46 import org.apache.geronimo.kernel.Kernel;
47 import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
48 import org.apache.geronimo.kernel.management.NotificationType;
49
50 /**
51 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
52 */
53 public final class MBeanGBeanBridge implements MBeanRegistration, DynamicMBean, NotificationEmitter {
54 private static final Log log = LogFactory.getLog(MBeanGBeanBridge.class);
55
56 /**
57 * The kernel
58 */
59 private final Kernel kernel;
60
61 /**
62 * The unique name of this service.
63 */
64 private final AbstractName abstractName;
65 private final ObjectName objectName;
66 private final AbstractNameQuery pattern;
67
68 /**
69 * The mbean info
70 */
71 private final MBeanInfo mbeanInfo;
72
73 /**
74 * The broadcaster for notifications
75 */
76 private final NotificationBroadcasterSupport notificationBroadcaster = new NotificationBroadcasterSupport();
77 private final LifecycleBridge lifecycleBridge;
78
79 public MBeanGBeanBridge(Kernel kernel, AbstractName abstractName, ObjectName objectName, MBeanInfo mbeanInfo) {
80 this.kernel = kernel;
81 this.abstractName = abstractName;
82 this.pattern = new AbstractNameQuery(abstractName);
83 this.mbeanInfo = mbeanInfo;
84 this.objectName = objectName;
85 lifecycleBridge = new LifecycleBridge(abstractName, objectName, notificationBroadcaster);
86 }
87
88 public ObjectName getObjectName() {
89 return objectName;
90 }
91
92 public ObjectName preRegister(MBeanServer mBeanServer, ObjectName objectName) throws Exception {
93 return objectName;
94 }
95
96 public void postRegister(Boolean registrationDone) {
97 if (Boolean.TRUE.equals(registrationDone)) {
98
99 kernel.getLifecycleMonitor().addLifecycleListener(lifecycleBridge, pattern);
100 lifecycleBridge.loaded(abstractName);
101 }
102 }
103
104 public void preDeregister() {
105 kernel.getLifecycleMonitor().removeLifecycleListener(lifecycleBridge);
106 lifecycleBridge.unloaded(abstractName);
107 }
108
109 public void postDeregister() {
110 }
111
112 public MBeanInfo getMBeanInfo() {
113 return mbeanInfo;
114 }
115
116 public Object getAttribute(String attributeName) throws ReflectionException, AttributeNotFoundException {
117 try {
118 return kernel.getAttribute(abstractName, attributeName);
119 } catch (NoSuchAttributeException e) {
120 throw new AttributeNotFoundException(attributeName);
121 } catch (Exception e) {
122 throw new ReflectionException(e);
123 }
124 }
125
126 public void setAttribute(Attribute attribute) throws ReflectionException, AttributeNotFoundException {
127 String attributeName = attribute.getName();
128 Object attributeValue = attribute.getValue();
129 try {
130 kernel.setAttribute(abstractName, attributeName, attributeValue);
131 } catch (NoSuchAttributeException e) {
132 throw new AttributeNotFoundException(attributeName);
133 } catch (Exception e) {
134 throw new ReflectionException(e);
135 }
136 }
137
138 public AttributeList getAttributes(String[] attributes) {
139 AttributeList results = new AttributeList(attributes.length);
140 for (int i = 0; i < attributes.length; i++) {
141 String name = attributes[i];
142 try {
143 Object value = getAttribute(name);
144 results.add(new Attribute(name, value));
145 } catch (JMException e) {
146 log.warn("Exception while getting attribute " + name, e);
147 }
148 }
149 return results;
150 }
151
152 public AttributeList setAttributes(AttributeList attributes) {
153 AttributeList results = new AttributeList(attributes.size());
154 for (Iterator iterator = attributes.iterator(); iterator.hasNext();) {
155 Attribute attribute = (Attribute) iterator.next();
156 try {
157 setAttribute(attribute);
158 results.add(attribute);
159 } catch (JMException e) {
160 log.warn("Exception while setting attribute " + attribute.getName(), e);
161 }
162 }
163 return results;
164 }
165
166 public Object invoke(String operationName, Object[] arguments, String[] types) throws ReflectionException {
167 try {
168 return kernel.invoke(abstractName, operationName, arguments, types);
169 } catch (NoSuchOperationException e) {
170 throw new ReflectionException(new NoSuchMethodException(new GOperationSignature(operationName, types).toString()));
171 } catch (Exception e) {
172 throw new ReflectionException(e);
173 }
174 }
175
176 public MBeanNotificationInfo[] getNotificationInfo() {
177 return new MBeanNotificationInfo[]{
178 new MBeanNotificationInfo(NotificationType.TYPES, "javax.management.Notification", "J2EE Notifications")
179 };
180 }
181
182 public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) {
183 notificationBroadcaster.addNotificationListener(listener, filter, handback);
184 }
185
186 public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException {
187 notificationBroadcaster.removeNotificationListener(listener);
188 }
189
190 public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) throws ListenerNotFoundException {
191 notificationBroadcaster.removeNotificationListener(listener, filter, handback);
192 }
193
194 public String toString() {
195 return abstractName.toString();
196 }
197
198 private static class LifecycleBridge implements LifecycleListener {
199 /**
200 * Sequence number used for notifications
201 */
202 private long sequence;
203
204 /**
205 * AbstractName of this MBean
206 */
207 private final AbstractName mbeanAbstractName;
208
209 /**
210 * ObjectName of this MBean
211 */
212 private final ObjectName objectName;
213
214 /**
215 * The notification broadcaster to use
216 */
217 private final NotificationBroadcasterSupport notificationBroadcaster;
218
219 public LifecycleBridge(AbstractName mbeanAbstractName, ObjectName objectName, NotificationBroadcasterSupport notificationBroadcaster) {
220 this.mbeanAbstractName = mbeanAbstractName;
221 this.objectName = objectName;
222 this.notificationBroadcaster = notificationBroadcaster;
223 }
224
225 public void loaded(AbstractName abstractName) {
226 if (mbeanAbstractName.equals(abstractName)) {
227 notificationBroadcaster.sendNotification(new Notification(NotificationType.OBJECT_CREATED, objectName, nextSequence()));
228 }
229 }
230
231 public void starting(AbstractName abstractName) {
232 if (mbeanAbstractName.equals(abstractName)) {
233 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_STARTING, objectName, nextSequence()));
234 }
235 }
236
237 public void running(AbstractName abstractName) {
238 if (mbeanAbstractName.equals(abstractName)) {
239 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_RUNNING, objectName, nextSequence()));
240 }
241 }
242
243 public void stopping(AbstractName abstractName) {
244 if (mbeanAbstractName.equals(abstractName)) {
245 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_STOPPING, objectName, nextSequence()));
246 }
247 }
248
249 public void stopped(AbstractName abstractName) {
250 if (mbeanAbstractName.equals(abstractName)) {
251 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_STOPPED, objectName, nextSequence()));
252 }
253 }
254
255 public void failed(AbstractName abstractName) {
256 if (mbeanAbstractName.equals(abstractName)) {
257 notificationBroadcaster.sendNotification(new Notification(NotificationType.STATE_FAILED, objectName, nextSequence()));
258 }
259 }
260
261 public void unloaded(AbstractName abstractName) {
262 if (mbeanAbstractName.equals(abstractName)) {
263 notificationBroadcaster.sendNotification(new Notification(NotificationType.OBJECT_DELETED, objectName, nextSequence()));
264 }
265 }
266
267 public synchronized long nextSequence() {
268 return sequence++;
269 }
270 }
271 }