KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sape > carbon > services > management > interceptor > DefaultManagementInterceptorImpl


1 /*
2  * The contents of this file are subject to the Sapient Public License
3  * Version 1.0 (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://carbon.sf.net/License.html.
6  *
7  * Software distributed under the License is distributed on an "AS IS" basis,
8  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9  * the specific language governing rights and limitations under the License.
10  *
11  * The Original Code is The Carbon Component Framework.
12  *
13  * The Initial Developer of the Original Code is Sapient Corporation
14  *
15  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
16  */

17
18 package org.sape.carbon.services.management.interceptor;
19
20 import java.beans.BeanInfo JavaDoc;
21 import java.beans.Introspector JavaDoc;
22 import java.beans.PropertyDescriptor JavaDoc;
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25 import java.lang.reflect.Proxy JavaDoc;
26 import java.rmi.dgc.VMID JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collections JavaDoc;
29 import java.util.Comparator JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32
33 import javax.management.Attribute JavaDoc;
34 import javax.management.AttributeList JavaDoc;
35 import javax.management.AttributeNotFoundException JavaDoc;
36 import javax.management.InstanceAlreadyExistsException JavaDoc;
37 import javax.management.InvalidAttributeValueException JavaDoc;
38 import javax.management.MBeanAttributeInfo JavaDoc;
39 import javax.management.MBeanConstructorInfo JavaDoc;
40 import javax.management.MBeanException JavaDoc;
41 import javax.management.MBeanFeatureInfo JavaDoc;
42 import javax.management.MBeanInfo JavaDoc;
43 import javax.management.MBeanNotificationInfo JavaDoc;
44 import javax.management.MBeanOperationInfo JavaDoc;
45 import javax.management.MBeanParameterInfo JavaDoc;
46 import javax.management.MBeanRegistrationException JavaDoc;
47 import javax.management.MBeanServer JavaDoc;
48 import javax.management.MalformedObjectNameException JavaDoc;
49 import javax.management.NotCompliantMBeanException JavaDoc;
50 import javax.management.Notification JavaDoc;
51 import javax.management.NotificationBroadcaster JavaDoc;
52 import javax.management.NotificationBroadcasterSupport JavaDoc;
53 import javax.management.ObjectName JavaDoc;
54 import javax.management.ReflectionException JavaDoc;
55
56 import org.sape.carbon.core.component.Component;
57 import org.sape.carbon.core.component.ComponentConfiguration;
58 import org.sape.carbon.core.component.Lookup;
59 import org.sape.carbon.core.component.event.ComponentEvent;
60 import org.sape.carbon.core.component.event.EventManager;
61 import org.sape.carbon.core.component.lifecycle.LifecycleInterceptor;
62 import org.sape.carbon.core.component.proxy.Interceptor;
63 import org.sape.carbon.core.component.proxy.Invocation;
64 import org.sape.carbon.core.config.Config;
65 import org.sape.carbon.core.config.InvalidConfigurationException;
66 import org.sape.carbon.core.exception.ExceptionUtility;
67 import org.sape.carbon.core.util.reflection.BeanUtil;
68 import org.sape.carbon.core.util.reflection.ClassTree;
69 import org.sape.carbon.services.jmx.server.MBeanServerRetreiveException;
70 import org.sape.carbon.services.jmx.server.MBeanServerService;
71
72 import org.apache.commons.logging.Log;
73 import org.apache.commons.logging.LogFactory;
74
75 /**
76  * <P>This is an interceptor implementation that provides JMX integration for
77  * Carbon Components. It handles the DynamicMBean interface's methods and
78  * provides an XML based storage mechanism for MBeanInfo configurations.</P>
79  *
80  * To configure this interceptor add the following to a component
81  * template configuration:
82  * <PRE>
83  * &lt;!-- The JMX Assistant --&gt;
84  * &lt;DecoratorConfiguration&gt;
85  * &lt;Factory&gt;
86  * org.sape.carbon.services.management.interceptor.ManagementInterceptorFactory
87  * &lt;/Factory&gt;
88  * &lt;CustomConfiguration
89  * ConfigurationInterface="org.sape.carbon.services.management.interceptor.ManagementInterceptorConfiguration"&gt;
90  *
91  * &lt;MBeanServerServiceLocation&gt;/manage/DefaultMBeanServer&lt;/MBeanServerServiceLocation&gt;
92  * &lt;SendNotifications&gt;true&lt;/SendNotifications&gt;
93  * &lt;/CustomConfiguration&gt;
94  * &lt;/DecoratorConfiguration&gt;
95  * </PRE>
96  *
97  *
98  * Copyright 2002 Sapient
99  * @since carbon 1.0
100  * @author Greg Hinkle, March 2002
101  * @version $Revision: 1.13 $($Author: dvoet $ / $Date: 2003/05/05 21:21:33 $)
102  */

103 public class DefaultManagementInterceptorImpl
104         extends NotificationBroadcasterSupport JavaDoc
105             implements ManagementInterceptor, Interceptor, EventManager {
106
107     /** Provides a handle to Apache-commons logger */
108     private Log log = LogFactory.getLog(this.getClass());
109
110     /**
111      * This long tracks the next sequence number to send in a notification
112      */

113     private long notificationSequence = 0L;
114
115     /**
116      * A reference to the component that is being monitored by this
117      * interceptor.
118      */

119     protected Component component;
120
121     /**
122      * The ObjectName of the registered component. This ObjectName
123      * is how a component's MBean would be found via JMX.
124      */

125     protected ObjectName JavaDoc objectName;
126
127     /**
128      * A cached copy of the MBeanInfo for this registered component.
129      * Because Components are constructed from multiple
130      * sub-assistants and the Configuration Assistant may be
131      * dynamically mapped, we cache the process to improve speed.
132      */

133     protected MBeanInfo JavaDoc mBeanInfo = null;
134
135     /**
136      * The next interceptor in the chain
137      */

138     protected Interceptor nextInterceptor;
139
140     // A static reference to the component name of the an
141
// MBeanServerProvider (a component service that retrieves
142
// a reference to the MBeanServer to register/deregister with.)
143
/** Key to the name of the MBean. */
144     private static final String JavaDoc PROPERTY_NAME = "name=";
145
146     /** Key to the type of the MBean. */
147     private static final String JavaDoc PROPERTY_TYPE = ",type=";
148
149     /** Key to the environment of the MBean. */
150     private static final String JavaDoc PROPERTY_ENVIRONMENT = ",environment=";
151
152     /** Key to the instance of the MBean. */
153     private static final String JavaDoc PROPERTY_INSTANCE = ",instance=";
154
155     /** Key to the virtual machine id of the MBean. */
156     private static final String JavaDoc PROPERTY_VMID = ",vmid=";
157
158     /** Key to the unique id of the MBean. */
159     private static final String JavaDoc UNIQUE_ID;
160
161     /** Name of the mbean server service. */
162     private String JavaDoc mbeanServerServiceName;
163
164     /** Indicates if this should send notifications. */
165     private boolean shouldSendNotifications;
166
167     /** Holds the configuration of the interceptor. */
168     private ManagementInterceptorConfiguration config;
169
170     /** Holds the component functional interface. */
171     private Class JavaDoc componentFunctionalInterface;
172
173     /** Config location of the management information classes. */
174     public static final String JavaDoc METADATA_CONFIG_LOCATION = "/manage/info/";
175
176     static {
177         String JavaDoc id = new VMID JavaDoc().toString();
178         UNIQUE_ID = id.replace(':', '-');
179     }
180
181     /**
182      * Constructs a ManagementInterceptor that can act as the DynamicMBean
183      * Implementation for a component.
184      *
185      * @param config the configuration for a management interceptor
186      * @param componentFunctionalInterface the functional interface to
187      * the component
188      */

189     public DefaultManagementInterceptorImpl(
190         ManagementInterceptorConfiguration config,
191         Class JavaDoc componentFunctionalInterface) {
192
193         this.mbeanServerServiceName =
194             config.getMBeanServerServiceLocation();
195
196         this.shouldSendNotifications = config.isSendNotifications();
197
198         this.config = config;
199
200         this.componentFunctionalInterface = componentFunctionalInterface;
201
202     }
203
204     /**
205      * This method sets the next interceptor as the next in the chain from the
206      * current interceptor.
207      * @param interceptor the next interceptor in the chain
208      */

209     public void setNextInterceptor(Interceptor interceptor) {
210         this.nextInterceptor = interceptor;
211     }
212
213
214     /**
215      * Obtains the value of a specific attribute of the Dynamic MBean.
216      *
217      * @param attribute The name of the attribute to be retrieved
218      * @return The value of the attribute retrieved.
219      * @exception javax.management.AttributeNotFoundException Thrown when
220      * the specified attribute is not available
221      * @exception javax.management.MBeanException Wraps a
222      * <code>java.lang.Exception</code> thrown by the
223      * MBean's getter.
224      * @exception javax.management.ReflectionException Wraps a
225      * <code>java.lang.Exception</code> thrown while
226      * trying to invoke the getter.
227      */

228     public Object JavaDoc getAttribute(String JavaDoc attribute)
229     throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc {
230
231         try {
232             return BeanUtil.getObjectAttribute(this.component, attribute);
233         } catch (IllegalAccessException JavaDoc iae) {
234             throw new ReflectionException JavaDoc(iae);
235         } catch (InvocationTargetException JavaDoc ite) {
236             throw new ReflectionException JavaDoc(ite);
237         } catch (IllegalArgumentException JavaDoc iae) {
238             throw new ReflectionException JavaDoc(iae);
239         } catch (NoSuchMethodException JavaDoc nsme) {
240             throw new ReflectionException JavaDoc(nsme);
241         }
242     }
243
244
245     /**
246      * Enables the values of several attributes of the Dynamic MBean.
247      *
248      * @param attributes an array of string attributes to be retrieved.
249      *
250      * @return The list of attributes retrieved.
251      */

252     public AttributeList JavaDoc getAttributes(String JavaDoc[] attributes) {
253         AttributeList JavaDoc list = new AttributeList JavaDoc();
254
255         for (int i = 0; i < attributes.length; i++) {
256             Object JavaDoc value = null;
257             try {
258                 value = this.getAttribute(attributes[i]);
259             } catch (Exception JavaDoc e) {
260                 // Ignore exceptions.
261
}
262             list.add(new Attribute JavaDoc(attributes[i], value));
263         }
264         return list;
265     }
266
267
268     /**
269      * <P>This method returns the MBeanInfo object representing the managable
270      * interfaces that are exposed by the Component being assisted. This
271      * metadata will include information about all manageable roles that this
272      * component has been configured to play.
273      * </P>
274      *
275      * @return the MBeanInfo representing this component's manageability
276      */

277     public MBeanInfo JavaDoc getMBeanInfo() {
278         synchronized (this) {
279             if (this.mBeanInfo == null) {
280                 this.mBeanInfo = buildMBeanInfo(this.component);
281             }
282         }
283         return this.mBeanInfo;
284     }
285
286     /**
287      * Gets the class of this component.
288      *
289      * @return class of this component
290      */

291     public Class JavaDoc getComponentType() {
292         return this.component.getClass();
293     }
294
295     /**
296      * <P>This method essentially aggregates all MBean Information about each
297      * interface that a component implements into a single MBeanInfo object.
298      * This is done by loading configuration documents for each interface that
299      * implement a set of <code>configuration</code> versions of the various
300      * Info metadata objects. These objects are then read in to their MBeanInfo
301      * metadata counterparts and aggregated into big lists. Then the final step
302      * is to place them into one large MBeanInfo object and return them.
303      * </P>
304      *
305      * <P>By aggregating the supported management interface for any number of
306      * roles that the component can handle we can give a JMX console user the
307      * full power of Carbon's generic delegation and configuratively additive
308      * functionality.</P>
309      *
310      * @param component the Component that is being represented by this
311      * ManagementInterceptor
312      * @return the MBeanInfo object representing the supported management
313      * methods exposed by this configuration of this component.
314      */

315     protected MBeanInfo JavaDoc buildMBeanInfo(Component component) {
316
317         String JavaDoc name = this.component.getComponentName();
318
319         if (log.isTraceEnabled()) {
320             log.trace(
321                 "Building MBeanInfo object for component ["
322                 + name + "]");
323         }
324
325         // Prepare lists to place the info objects into
326
ArrayList JavaDoc
327             attributesSet = new ArrayList JavaDoc(),
328             constructorsSet = new ArrayList JavaDoc(),
329             operationsSet = new ArrayList JavaDoc(),
330             notificationsSet = new ArrayList JavaDoc();
331
332         ClassTree tree = new ClassTree(component.getClass());
333
334         List JavaDoc classes = tree.getOrderedList();
335         Iterator JavaDoc classesIterator = classes.iterator();
336         while (classesIterator.hasNext()) {
337             Class JavaDoc exposedClass = (Class JavaDoc) classesIterator.next();
338
339             String JavaDoc configName =
340                 METADATA_CONFIG_LOCATION + exposedClass.getName();
341
342             /*
343             // A little too verbose
344             if (log.isTraceEnabled()) {
345                 log.trace(
346                     this.component.getComponentName() + ": exposing jmxwise: " +
347                     exposedClass.getName());
348             }*/

349
350             if (!Config.getInstance().nodeExists(configName)) {
351                 // If there is no metadata, but it is a configuration
352
// interface, then build the attribute information manually.
353
// But don't build it for the proxy class cause that contains
354
// absolutely everything AND implements the configuration
355
// interface.
356
if ((ComponentConfiguration.class.isAssignableFrom(exposedClass))
357                         && (!Proxy.isProxyClass(exposedClass))) {
358
359                     this.addConfigurationAttributes(exposedClass,
360                         attributesSet);
361                 }
362             } else {
363
364                 MBeanInfoConfiguration mbic =
365                     (MBeanInfoConfiguration)
366                     Config.getInstance().fetchConfiguration(configName);
367                 if (mbic != null) {
368
369                     // 1) Load Attributes
370
MBeanInfoConfiguration.MBeanAttributeInfoConfiguration[]
371                         attrs = mbic.getAttributes();
372
373                     for (int j = 0; j < attrs.length; j++) {
374                         MBeanAttributeInfo JavaDoc attributeInfo =
375                             new MBeanAttributeInfo JavaDoc(
376                             attrs[j].getName(),
377                             attrs[j].getType(),
378                             attrs[j].getDescription(),
379                             attrs[j].isReadable(),
380                             attrs[j].isWritable(),
381                             attrs[j].isIs());
382                         // Replace any existing metadata
383
attributesSet.remove(attributeInfo);
384                         attributesSet.add(attributeInfo);
385                     }
386
387                     // 2) Load Constructors
388
MBeanInfoConfiguration.MBeanConstructorInfoConfiguration[]
389                         constructors = mbic.getConstructors();
390
391                     for (int j = 0; j < constructors.length; j++) {
392                         MBeanConstructorInfo JavaDoc constructorInfo =
393                             new MBeanConstructorInfo JavaDoc(
394                                 constructors[j].getName(),
395                                 constructors[j].getDescription(),
396                                 loadParameters(constructors[j].getSignature()));
397
398                         // Replace any existing metadata
399
constructorsSet.remove(constructorInfo);
400                         constructorsSet.add(constructorInfo);
401                     }
402
403                     // 3) Load Operations
404
MBeanInfoConfiguration.MBeanOperationInfoConfiguration[]
405                         operations = mbic.getOperations();
406
407                     for (int j = 0; j < operations.length; j++) {
408                         MBeanOperationInfo JavaDoc operationInfo =
409                             new MBeanOperationInfo JavaDoc(
410                                 operations[j].getName(),
411                                 operations[j].getDescription(),
412                                 loadParameters(operations[j].getSignature()),
413                                 operations[j].getReturnType(),
414                                 operations[j].getImpact().getImpactConstant());
415
416                         // Replace any existing metadata
417
operationsSet.remove(operationInfo);
418                         operationsSet.add(operationInfo);
419                     }
420
421                     // 4) Load Notification descriptors
422
MBeanInfoConfiguration.MBeanNotificationInfoConfiguration[]
423                         notifications = mbic.getNotifications();
424
425                     for (int j = 0; j < notifications.length; j++) {
426                         MBeanInfoConfiguration.MBeanNotificationInfoConfiguration notification
427                             = notifications[j];
428
429                         MBeanNotificationInfo JavaDoc notificationInfo =
430                             new MBeanNotificationInfo JavaDoc(
431                                 notification.getNotifTypes(),
432                                 notification.getName(),
433                                 notification.getDescription());
434
435                         // Replace any existing metadata
436
notificationsSet.remove(notificationInfo);
437                         notificationsSet.add(notificationInfo);
438                     }
439                 }
440             }
441         }
442
443
444         // Setup the description for this component from the component
445
// configuration.
446
String JavaDoc description =
447             ((ComponentConfiguration) this.component).
448                 getComponentDescription();
449         if (description == null) {
450             description = "No description given.";
451         }
452
453
454         Collections.sort(attributesSet, new MBeanFeatureInfoComparator());
455         MBeanAttributeInfo JavaDoc[] attributes =
456             (MBeanAttributeInfo JavaDoc[])
457             attributesSet.toArray(
458                 new MBeanAttributeInfo JavaDoc[attributesSet.size()]);
459
460         Collections.sort(constructorsSet, new MBeanFeatureInfoComparator());
461         MBeanConstructorInfo JavaDoc[] constructors =
462             (MBeanConstructorInfo JavaDoc[])
463             constructorsSet.toArray(
464                 new MBeanConstructorInfo JavaDoc[constructorsSet.size()]);
465
466         Collections.sort(operationsSet, new MBeanFeatureInfoComparator());
467         MBeanOperationInfo JavaDoc[] operations =
468             (MBeanOperationInfo JavaDoc[])
469             operationsSet.toArray(
470                 new MBeanOperationInfo JavaDoc[operationsSet.size()]);
471
472         Collections.sort(notificationsSet, new MBeanFeatureInfoComparator());
473         MBeanNotificationInfo JavaDoc[] notifications =
474             (MBeanNotificationInfo JavaDoc[])
475             notificationsSet.toArray(
476                 new MBeanNotificationInfo JavaDoc[notificationsSet.size()]);
477
478         MBeanInfo JavaDoc info =
479             new MBeanInfo JavaDoc(
480                 name,
481                 description,
482                 attributes,
483                 constructors,
484                 operations,
485                 notifications);
486
487         return info;
488
489     }
490
491     /**
492      * This comporator may be used to order all types of MBeanFeatureInfo
493      * objects by name.
494      * @since carbon 2.0
495      */

496     public static class MBeanFeatureInfoComparator implements Comparator JavaDoc {
497         /**
498          * Compares two MBeanFeatureInfo objects.
499          *
500          * @param o1 the first object to be compared.
501          * @param o2 the second object to be compared.
502          * @return a negative integer, zero, or a positive integer as the
503          * first argument is less than, equal to, or greater than the
504          * second.
505          * @throws ClassCastException if the arguments' types prevent them from
506          * being compared by this Comparator.
507          */

508         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
509
510             MBeanFeatureInfo JavaDoc f1 = (MBeanFeatureInfo JavaDoc) o1;
511             MBeanFeatureInfo JavaDoc f2 = (MBeanFeatureInfo JavaDoc) o2;
512
513             return f1.getName().compareTo(f2.getName());
514         }
515     }
516
517     /**
518      * Introspects on the class type of a configuration in order
519      * to define the MBeanInfo metadata about it. Configuration
520      * interfaces are strictly Java Interfaces that adhere to the
521      * Bean standard for attributes and therefore only have
522      * attributes.
523      *
524      * @param configurationClass the Class type to construct metadata for
525      * @param attributesSet the set of attributes that will be added to for
526      * each attribute in the supplied configuration.
527      */

528     private void addConfigurationAttributes(
529             Class JavaDoc configurationClass, List JavaDoc attributesSet) {
530
531         try {
532             // Maps are now only supported as full Map gets and sets as Maps
533
// are not a valid JavaBean Indexed Property Type.
534
BeanInfo JavaDoc info = Introspector.getBeanInfo(configurationClass);
535
536             PropertyDescriptor JavaDoc[] descs = info.getPropertyDescriptors();
537
538             for (int i = 0; i < descs.length; i++) {
539                 PropertyDescriptor JavaDoc desc = descs[i];
540
541                 MBeanAttributeInfo JavaDoc mbeanAttributeInfo =
542                     new MBeanAttributeInfo JavaDoc(
543                         desc.getName(),
544                         //"Automatic field access",
545
// (supports Extra Info classes)
546
desc.getShortDescription(),
547                         desc.getReadMethod(),
548                         desc.getWriteMethod());
549
550                 attributesSet.add(mbeanAttributeInfo);
551             }
552         } catch (java.beans.IntrospectionException JavaDoc ie) {
553             log.warn("Unable to add configuration to management metadata for"
554                 + " interface [" + configurationClass + "]",
555                 ie);
556         } catch (javax.management.IntrospectionException JavaDoc ie) {
557             log.warn("Unable to add configuration to management metadata for"
558                 + " interface [" + configurationClass + "]",
559                 ie);
560         }
561
562
563     }
564
565
566     /**
567      * <P>Loads an array ParameterInfoConfiguration into a JMX
568      * ParameterInfo.
569      * </P>
570      * @param config the array of parameter info configurations to be
571      * translated into the strictly JMX MBeanParameterInfo
572      * objects.
573      * @return an array of MBeanParameterInfo objects.
574      */

575     private MBeanParameterInfo JavaDoc[] loadParameters(
576             MBeanInfoConfiguration.MBeanParameterInfoConfiguration[] config) {
577
578         MBeanParameterInfo JavaDoc[] params = new MBeanParameterInfo JavaDoc[config.length];
579         for (int j = 0; j < config.length; j++) {
580             params[j] =
581                 new MBeanParameterInfo JavaDoc(
582                     config[j].getName(),
583                     config[j].getType(),
584                     config[j].getDescription());
585         }
586         return params;
587     }
588
589     /**
590      * This should return the list of interfaces that a decorator wishes to
591      * expose through the component proxy. This is used by the
592      * component factory to determine what interfaces the component proxy will
593      * implement.
594      *
595      * @return Class[] an array of interfaces
596      */

597     public Class JavaDoc[] getExposedInterfaces() {
598         return new Class JavaDoc[] {
599             ManagementInterceptor.class,
600             NotificationBroadcaster JavaDoc.class,
601             EventManager.class };
602     }
603
604
605
606     /**
607      * <P>Handles the invocation of operations on the component represented
608      * by this MBean Assistant.</P>
609      * @param actionName The name of the action to be invoked.
610      * @param params An array containing the parameters to be set when the
611      * action is invoked.
612      * @param signature An array containing the signature of the action.
613      * The class objects will be loaded through the same class loader as
614      * the one used for loading the MBean on which the action is invoked.
615      * @return The object returned by the action, which represents the
616      * result of invoking the action on the MBean specified.
617      * @throws javax.management.MBeanException Wraps a java.lang.Exception
618      * thrown by the MBean's invoked method.
619      * @throws javax.management.ReflectionException Wraps an exception
620      * during reflection
621      */

622     public Object JavaDoc invoke(
623             String JavaDoc actionName, Object JavaDoc[] params, String JavaDoc[] signature)
624         throws MBeanException JavaDoc, ReflectionException JavaDoc {
625
626
627         Class JavaDoc[] paramTypes = new Class JavaDoc[signature.length];
628         try {
629             for (int i = 0; i < signature.length; i++) {
630                 paramTypes[i] =
631                     Class.forName(
632                         signature[i],
633                         true,
634                         this.getClass().getClassLoader());
635             }
636         } catch (ClassNotFoundException JavaDoc cnfe) {
637             throw new ReflectionException JavaDoc(cnfe);
638         }
639
640         Class JavaDoc objectClass = this.component.getClass();
641
642         try {
643             Method JavaDoc method = objectClass.getMethod(actionName, paramTypes);
644
645             return method.invoke(this.component, params);
646
647         } catch (NoSuchMethodException JavaDoc e) {
648             throw new ReflectionException JavaDoc(e);
649         } catch (IllegalAccessException JavaDoc e) {
650             throw new ReflectionException JavaDoc(e);
651         } catch (InvocationTargetException JavaDoc e) {
652             throw new ReflectionException JavaDoc(e);
653         }
654
655     }
656
657
658     /**
659      * Sets the value of a specific attribute of the Dynamic MBean
660      *
661      * @param attribute The identification of the attribute to
662      * be set and the value it is to be set to.
663      * @exception javax.management.AttributeNotFoundException Thrown when
664      * the specified attribute is not found
665      * @exception javax.management.InvalidAttributeValueException Thrown
666      * when the value that is being set was not valid for the
667      * attribute
668      * @exception javax.management.MBeanException Wraps a
669      * <code>java.lang.Exception</code> thrown by the
670      * MBean's setter.
671      * @exception javax.management.ReflectionException Wraps a
672      * <code>java.lang.Exception</code> thrown while
673      * trying to invoke the MBean's setter.
674      */

675     public void setAttribute(Attribute JavaDoc attribute)
676             throws AttributeNotFoundException JavaDoc,
677             InvalidAttributeValueException JavaDoc,
678             MBeanException JavaDoc,
679             ReflectionException JavaDoc {
680
681         String JavaDoc name = attribute.getName();
682         Object JavaDoc value = attribute.getValue();
683
684         try {
685             BeanUtil.setObjectAttribute(this.component, name, value);
686         } catch (NoSuchMethodException JavaDoc e) {
687             throw new ReflectionException JavaDoc(e);
688         } catch (IllegalAccessException JavaDoc e) {
689             throw new ReflectionException JavaDoc(e);
690         } catch (InvocationTargetException JavaDoc ite) {
691             throw new InvalidAttributeValueException JavaDoc(
692                 "The value for attribute [" + name + "] was ["
693                 + value + "] and is not valid: "
694                 + ExceptionUtility.printStackTracesToString(ite));
695
696         } catch (IllegalArgumentException JavaDoc iae) {
697             throw new InvalidAttributeValueException JavaDoc(
698                 "The value for attribute [" + name + "] was ["
699                 + value + "] and is not valid: "
700                 + ExceptionUtility.printStackTracesToString(iae));
701         }
702     }
703
704
705     /**
706      * Sets as many attributes as it can from the provided list and returns a
707      * list of the attributes that were successfully set. Those that failed
708      * to be set will not be in the return list.
709      * @param attributeList the list of attributes to set.
710      * @return the list of attributes that were successfully set.
711      */

712     public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attributeList) {
713         AttributeList JavaDoc resultList = new AttributeList JavaDoc();
714         for (int i = 0; i < attributeList.size(); i++) {
715             Attribute JavaDoc attribute = (Attribute JavaDoc) attributeList.get(i);
716
717             try {
718                 setAttribute(attribute);
719                 resultList.add(attribute);
720             } catch (AttributeNotFoundException JavaDoc anfe) {
721                 if (log.isWarnEnabled()) {
722                     log.warn(
723                         "Unable to set attribute through JMX.",
724                         anfe);
725                 }
726             } catch (InvalidAttributeValueException JavaDoc iave) {
727                 if (log.isWarnEnabled()) {
728                     log.warn(
729                         "Unable to set attribute through JMX.",
730                         iave);
731                 }
732             } catch (MBeanException JavaDoc mbe) {
733                 if (log.isWarnEnabled()) {
734                     log.warn(
735                         "Unable to set attribute through JMX.",
736                         mbe);
737                 }
738             } catch (ReflectionException JavaDoc re) {
739                 if (log.isWarnEnabled()) {
740                     log.warn(
741                         "Unable to set attribute through JMX.",
742                         re);
743                 }
744             }
745         }
746
747         return resultList;
748     }
749
750
751     /**
752      * Called after creation to pass a reference to the component to each of
753      * its assistants.
754      *
755      * @param component a reference to the component that this interceptor is
756      * assisting
757      */

758     public void setComponentReference(Component component) {
759         this.component = component;
760
761         // Do not register self
762
if (this.component instanceof MBeanServerService) {
763             log.trace(
764                 "Unable to register component ["
765                 + this.component.getComponentName()
766                 + "] in MBean Server");
767            return;
768         }
769
770         if (log.isTraceEnabled()) {
771             log.trace(
772                 "Registering ["
773                     + this.component.getComponentName()
774                     + "] in MBean Server");
775         }
776
777         MBeanServerService mbeanServer =
778             (MBeanServerService)
779             Lookup.getInstance().fetchComponent("/manage/DefaultMBeanServer");
780
781
782         // There is a chance that this component is not there
783
if (mbeanServer == null) {
784             log.info(
785                 "Unable to register component ["
786                 + this.component.getComponentName() + "] in "
787                 + "MBean Server as we could not get a reference to the "
788                 + "MBeanServerService component.");
789             return;
790         }
791
792         MBeanServer JavaDoc server = null;
793
794         try {
795             server = mbeanServer.getMBeanServer();
796         } catch (MBeanServerRetreiveException e) {
797             // There is a chance that there was a configuration
798
// error with the MBeanServer. Instead of breaking
799
// with a NullPointer, simple log a message and do
800
// not register the component.
801
log.info(
802                 "Unable to register component ["
803                 + this.component.getComponentName() + "] in "
804                 + "MBean Server as we could not get a reference to the "
805                 + "MBeanServer from the MBeanServerService. Caught "
806                 + "Exception: " + e + ExceptionUtility.captureStackTrace(e));
807
808             return;
809         }
810
811         try {
812             StringBuffer JavaDoc objectNameBuffer = new StringBuffer JavaDoc(100);
813             objectNameBuffer.append(config.getObjectNameDomain());
814             objectNameBuffer.append(":");
815
816             objectNameBuffer.append(
817                 DefaultManagementInterceptorImpl.PROPERTY_NAME);
818
819             objectNameBuffer.append(this.component.getComponentName());
820
821             objectNameBuffer.append(
822                 DefaultManagementInterceptorImpl.PROPERTY_TYPE);
823
824             objectNameBuffer.append(
825                 this.componentFunctionalInterface.getName());
826
827             if (this.config.getEnvironmentName() != null) {
828                 objectNameBuffer.append(
829                     DefaultManagementInterceptorImpl.PROPERTY_ENVIRONMENT);
830
831                 objectNameBuffer.append(this.config.getEnvironmentName());
832             }
833
834             if (this.config.getInstanceName() != null) {
835                 objectNameBuffer.append(
836                     DefaultManagementInterceptorImpl.PROPERTY_INSTANCE);
837
838                 objectNameBuffer.append(this.config.getInstanceName());
839             }
840
841             if (config.isUsingVMID()) {
842                 objectNameBuffer.append(
843                     DefaultManagementInterceptorImpl.PROPERTY_VMID);
844
845                 objectNameBuffer.append(
846                     DefaultManagementInterceptorImpl.UNIQUE_ID);
847             }
848
849             this.objectName = new ObjectName JavaDoc(objectNameBuffer.toString());
850             server.registerMBean(this.component, this.objectName);
851
852         } catch (MalformedObjectNameException JavaDoc mone) {
853             throw new InvalidConfigurationException(
854                 this.getClass(),
855                 null, null,
856                 mone);
857         } catch (InstanceAlreadyExistsException JavaDoc iaee) {
858             throw new InvalidConfigurationException(
859                 this.getClass(),
860                 null, null,
861                 iaee);
862         } catch (MBeanRegistrationException JavaDoc mre) {
863             throw new InvalidConfigurationException(
864                 this.getClass(),
865                 null, null,
866                 mre);
867         } catch (NotCompliantMBeanException JavaDoc ncme) {
868             throw new InvalidConfigurationException(
869                 this.getClass(),
870                 null, null,
871                 ncme);
872         }
873     }
874
875     /**
876      * Intercepts calls to the <code>LifecycleInterceptor</code> interface in
877      * order to handle deregistering the MBean from the MBeanServer when
878      * the component is destroyed.
879      *
880      * @param invocation the invocation to execute
881      * @return the results of the invocation's execution
882      * @throws Throwable indicates an error in the invokation chain
883      */

884     public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc {
885
886         Method JavaDoc method = invocation.getMethod();
887         String JavaDoc methodName = method.getName();
888
889         // Unregister a component if it is being destroyed
890
if ((LifecycleInterceptor.class.isAssignableFrom(
891                     invocation.getTarget().getClass()))
892
893                 && (methodName.equals("destroyComponent"))
894                 && (this.objectName != null)) {
895
896             if (log.isInfoEnabled()) {
897                 log.info("Unregistering mbean ["
898                     + this.objectName.getCanonicalName() + "]");
899             }
900             try {
901                 MBeanServerService mbeanServerService =
902                     (MBeanServerService)
903                     Lookup.getInstance().fetchComponent(
904                         this.mbeanServerServiceName);
905
906                 mbeanServerService.getMBeanServer().unregisterMBean(
907                     this.objectName);
908
909             } catch (Exception JavaDoc e) {
910                 log.debug(
911                     "Unable to unregister MBeanServerService component ["
912                         + this.objectName.getCanonicalName() + "]");
913             }
914         }
915
916         return this.nextInterceptor.invoke(invocation);
917     }
918
919
920
921     /**
922      * Sends the supplied event to any listeners who may be listening for
923      * events on the managed component. Will only send events when configured
924      * to send them in the ComponentTemplate.
925      * @param componentEvent The event that occured on the component.
926      */

927     public void sendEvent(ComponentEvent componentEvent) {
928         if (this.shouldSendNotifications) {
929             Notification JavaDoc notification =
930                 new Notification JavaDoc(
931                     componentEvent.getName(),
932                     componentEvent.getSource(),
933                     this.notificationSequence++,
934                     componentEvent.getMessage());
935
936             sendNotification(notification);
937         }
938     }
939
940 }
941
Popular Tags