001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.system.jmx;
017:
018: import java.util.Iterator;
019: import javax.management.Attribute;
020: import javax.management.AttributeList;
021: import javax.management.AttributeNotFoundException;
022: import javax.management.DynamicMBean;
023: import javax.management.JMException;
024: import javax.management.ListenerNotFoundException;
025: import javax.management.MBeanInfo;
026: import javax.management.MBeanNotificationInfo;
027: import javax.management.Notification;
028: import javax.management.NotificationBroadcasterSupport;
029: import javax.management.NotificationEmitter;
030: import javax.management.NotificationFilter;
031: import javax.management.NotificationListener;
032: import javax.management.ObjectName;
033: import javax.management.ReflectionException;
034: import javax.management.MBeanRegistration;
035: import javax.management.MBeanServer;
036:
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039: import org.apache.geronimo.gbean.GOperationSignature;
040: import org.apache.geronimo.gbean.AbstractName;
041: import org.apache.geronimo.gbean.AbstractNameQuery;
042: import org.apache.geronimo.kernel.NoSuchAttributeException;
043: import org.apache.geronimo.kernel.NoSuchOperationException;
044: import org.apache.geronimo.kernel.Kernel;
045: import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
046: import org.apache.geronimo.kernel.management.NotificationType;
047:
048: /**
049: * @version $Rev: 606967 $ $Date: 2007-12-26 14:51:43 -0800 (Wed, 26 Dec 2007) $
050: */
051: public final class MBeanGBeanBridge implements MBeanRegistration,
052: DynamicMBean, NotificationEmitter {
053: private static final Log log = LogFactory
054: .getLog(MBeanGBeanBridge.class);
055:
056: /**
057: * The kernel
058: */
059: private final Kernel kernel;
060:
061: /**
062: * The unique name of this service.
063: */
064: private final AbstractName abstractName;
065: private final ObjectName objectName;
066: private final AbstractNameQuery pattern;
067:
068: /**
069: * The mbean info
070: */
071: private final MBeanInfo mbeanInfo;
072:
073: /**
074: * The broadcaster for notifications
075: */
076: private final NotificationBroadcasterSupport notificationBroadcaster = new NotificationBroadcasterSupport();
077: private final LifecycleBridge lifecycleBridge;
078:
079: public MBeanGBeanBridge(Kernel kernel, AbstractName abstractName,
080: ObjectName objectName, MBeanInfo mbeanInfo) {
081: this .kernel = kernel;
082: this .abstractName = abstractName;
083: this .pattern = new AbstractNameQuery(abstractName);
084: this .mbeanInfo = mbeanInfo;
085: this .objectName = objectName;
086: lifecycleBridge = new LifecycleBridge(abstractName, objectName,
087: notificationBroadcaster);
088: }
089:
090: public ObjectName getObjectName() {
091: return objectName;
092: }
093:
094: public NotificationBroadcasterSupport getNotificationBroadcasterSupport() {
095: return notificationBroadcaster;
096: }
097:
098: public ObjectName preRegister(MBeanServer mBeanServer,
099: ObjectName objectName) throws Exception {
100: return objectName;
101: }
102:
103: public void postRegister(Boolean registrationDone) {
104: if (Boolean.TRUE.equals(registrationDone)) {
105: // fire the loaded event from the gbeanMBean.. it was already fired from the GBeanInstance when it was created
106: kernel.getLifecycleMonitor().addLifecycleListener(
107: lifecycleBridge, pattern);
108: lifecycleBridge.loaded(abstractName);
109: }
110: }
111:
112: public void preDeregister() {
113: kernel.getLifecycleMonitor().removeLifecycleListener(
114: lifecycleBridge);
115: lifecycleBridge.unloaded(abstractName);
116: }
117:
118: public void postDeregister() {
119: }
120:
121: public MBeanInfo getMBeanInfo() {
122: return mbeanInfo;
123: }
124:
125: public Object getAttribute(String attributeName)
126: throws ReflectionException, AttributeNotFoundException {
127: try {
128: return kernel.getAttribute(abstractName, attributeName);
129: } catch (NoSuchAttributeException e) {
130: throw (AttributeNotFoundException) new AttributeNotFoundException(
131: attributeName).initCause(e);
132: } catch (Exception e) {
133: throw new ReflectionException(e);
134: }
135: }
136:
137: public void setAttribute(Attribute attribute)
138: throws ReflectionException, AttributeNotFoundException {
139: String attributeName = attribute.getName();
140: Object attributeValue = attribute.getValue();
141: try {
142: kernel.setAttribute(abstractName, attributeName,
143: attributeValue);
144: } catch (NoSuchAttributeException e) {
145: throw (AttributeNotFoundException) new AttributeNotFoundException(
146: attributeName).initCause(e);
147: } catch (Exception e) {
148: throw new ReflectionException(e);
149: }
150: }
151:
152: public AttributeList getAttributes(String[] attributes) {
153: AttributeList results = new AttributeList(attributes.length);
154: for (int i = 0; i < attributes.length; i++) {
155: String name = attributes[i];
156: try {
157: Object value = getAttribute(name);
158: results.add(new Attribute(name, value));
159: } catch (JMException e) {
160: log
161: .warn("Exception while getting attribute "
162: + name, e);
163: }
164: }
165: return results;
166: }
167:
168: public AttributeList setAttributes(AttributeList attributes) {
169: AttributeList results = new AttributeList(attributes.size());
170: for (Iterator iterator = attributes.iterator(); iterator
171: .hasNext();) {
172: Attribute attribute = (Attribute) iterator.next();
173: try {
174: setAttribute(attribute);
175: results.add(attribute);
176: } catch (JMException e) {
177: log.warn("Exception while setting attribute "
178: + attribute.getName(), e);
179: }
180: }
181: return results;
182: }
183:
184: public Object invoke(String operationName, Object[] arguments,
185: String[] types) throws ReflectionException {
186: try {
187: return kernel.invoke(abstractName, operationName,
188: arguments, types);
189: } catch (NoSuchOperationException e) {
190: throw new ReflectionException(
191: (NoSuchMethodException) new NoSuchMethodException(
192: new GOperationSignature(operationName,
193: types).toString()).initCause(e));
194: } catch (Exception e) {
195: throw new ReflectionException(e);
196: }
197: }
198:
199: public MBeanNotificationInfo[] getNotificationInfo() {
200: return new MBeanNotificationInfo[] { new MBeanNotificationInfo(
201: NotificationType.TYPES,
202: "javax.management.Notification", "J2EE Notifications") };
203: }
204:
205: public void addNotificationListener(NotificationListener listener,
206: NotificationFilter filter, Object handback) {
207: notificationBroadcaster.addNotificationListener(listener,
208: filter, handback);
209: }
210:
211: public void removeNotificationListener(NotificationListener listener)
212: throws ListenerNotFoundException {
213: notificationBroadcaster.removeNotificationListener(listener);
214: }
215:
216: public void removeNotificationListener(
217: NotificationListener listener, NotificationFilter filter,
218: Object handback) throws ListenerNotFoundException {
219: notificationBroadcaster.removeNotificationListener(listener,
220: filter, handback);
221: }
222:
223: public String toString() {
224: return abstractName.toString();
225: }
226:
227: private static class LifecycleBridge implements LifecycleListener {
228: /**
229: * Sequence number used for notifications
230: */
231: private long sequence;
232:
233: /**
234: * AbstractName of this MBean
235: */
236: private final AbstractName mbeanAbstractName;
237:
238: /**
239: * ObjectName of this MBean
240: */
241: private final ObjectName objectName;
242:
243: /**
244: * The notification broadcaster to use
245: */
246: private final NotificationBroadcasterSupport notificationBroadcaster;
247:
248: public LifecycleBridge(AbstractName mbeanAbstractName,
249: ObjectName objectName,
250: NotificationBroadcasterSupport notificationBroadcaster) {
251: this .mbeanAbstractName = mbeanAbstractName;
252: this .objectName = objectName;
253: this .notificationBroadcaster = notificationBroadcaster;
254: }
255:
256: public void loaded(AbstractName abstractName) {
257: if (mbeanAbstractName.equals(abstractName)) {
258: notificationBroadcaster
259: .sendNotification(new Notification(
260: NotificationType.OBJECT_CREATED,
261: objectName, nextSequence()));
262: }
263: }
264:
265: public void starting(AbstractName abstractName) {
266: if (mbeanAbstractName.equals(abstractName)) {
267: notificationBroadcaster
268: .sendNotification(new Notification(
269: NotificationType.STATE_STARTING,
270: objectName, nextSequence()));
271: }
272: }
273:
274: public void running(AbstractName abstractName) {
275: if (mbeanAbstractName.equals(abstractName)) {
276: notificationBroadcaster
277: .sendNotification(new Notification(
278: NotificationType.STATE_RUNNING,
279: objectName, nextSequence()));
280: }
281: }
282:
283: public void stopping(AbstractName abstractName) {
284: if (mbeanAbstractName.equals(abstractName)) {
285: notificationBroadcaster
286: .sendNotification(new Notification(
287: NotificationType.STATE_STOPPING,
288: objectName, nextSequence()));
289: }
290: }
291:
292: public void stopped(AbstractName abstractName) {
293: if (mbeanAbstractName.equals(abstractName)) {
294: notificationBroadcaster
295: .sendNotification(new Notification(
296: NotificationType.STATE_STOPPED,
297: objectName, nextSequence()));
298: }
299: }
300:
301: public void failed(AbstractName abstractName) {
302: if (mbeanAbstractName.equals(abstractName)) {
303: notificationBroadcaster
304: .sendNotification(new Notification(
305: NotificationType.STATE_FAILED,
306: objectName, nextSequence()));
307: }
308: }
309:
310: public void unloaded(AbstractName abstractName) {
311: if (mbeanAbstractName.equals(abstractName)) {
312: notificationBroadcaster
313: .sendNotification(new Notification(
314: NotificationType.OBJECT_DELETED,
315: objectName, nextSequence()));
316: }
317: }
318:
319: public synchronized long nextSequence() {
320: return sequence++;
321: }
322: }
323: }
|