KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > modelmbean > ModelMBeanInvoker


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.mx.modelmbean;
23
24 import java.beans.BeanInfo JavaDoc;
25 import java.beans.IntrospectionException JavaDoc;
26 import java.beans.Introspector JavaDoc;
27 import java.beans.PropertyDescriptor JavaDoc;
28 import java.beans.PropertyEditor JavaDoc;
29 import java.beans.PropertyEditorManager JavaDoc;
30 import java.lang.reflect.Constructor JavaDoc;
31 import java.lang.reflect.Method JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Map JavaDoc;
37
38 import javax.management.Attribute JavaDoc;
39 import javax.management.AttributeChangeNotification JavaDoc;
40 import javax.management.AttributeChangeNotificationFilter JavaDoc;
41 import javax.management.Descriptor JavaDoc;
42 import javax.management.InstanceNotFoundException JavaDoc;
43 import javax.management.JMException JavaDoc;
44 import javax.management.ListenerNotFoundException JavaDoc;
45 import javax.management.MBeanAttributeInfo JavaDoc;
46 import javax.management.MBeanException JavaDoc;
47 import javax.management.MBeanInfo JavaDoc;
48 import javax.management.MBeanNotificationInfo JavaDoc;
49 import javax.management.MBeanOperationInfo JavaDoc;
50 import javax.management.MBeanServer JavaDoc;
51 import javax.management.Notification JavaDoc;
52 import javax.management.NotificationFilter JavaDoc;
53 import javax.management.NotificationListener JavaDoc;
54 import javax.management.ObjectName JavaDoc;
55 import javax.management.RuntimeErrorException JavaDoc;
56 import javax.management.RuntimeOperationsException JavaDoc;
57 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
58 import javax.management.modelmbean.ModelMBean JavaDoc;
59 import javax.management.modelmbean.ModelMBeanAttributeInfo JavaDoc;
60 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
61 import javax.management.modelmbean.ModelMBeanInfoSupport JavaDoc;
62 import javax.management.modelmbean.ModelMBeanOperationInfo JavaDoc;
63
64 import org.jboss.logging.Logger;
65 import org.jboss.mx.interceptor.AbstractInterceptor;
66 import org.jboss.mx.interceptor.Interceptor;
67 import org.jboss.mx.interceptor.ModelMBeanAttributeInterceptor;
68 import org.jboss.mx.interceptor.ModelMBeanInfoInterceptor;
69 import org.jboss.mx.interceptor.ModelMBeanInterceptor;
70 import org.jboss.mx.interceptor.ModelMBeanOperationInterceptor;
71 import org.jboss.mx.interceptor.NullInterceptor;
72 import org.jboss.mx.interceptor.ObjectReferenceInterceptor;
73 import org.jboss.mx.interceptor.PersistenceInterceptor;
74 import org.jboss.mx.interceptor.PersistenceInterceptor2;
75 import org.jboss.mx.persistence.NullPersistence;
76 import org.jboss.mx.persistence.PersistenceManager;
77 import org.jboss.mx.server.AbstractMBeanInvoker;
78 import org.jboss.mx.server.Invocation;
79 import org.jboss.mx.server.InvocationContext;
80 import org.jboss.mx.server.MBeanInvoker;
81 import org.jboss.mx.util.JBossNotificationBroadcasterSupport;
82
83 /**
84  * An extension of the {@link org.jboss.mx.server.MBeanInvoker MBeanInvoker}
85  * that implements the base Model MBean functionality, essentially making the
86  * Model MBean just another invoker of managed resources.
87  *
88  * @see javax.management.modelmbean.ModelMBean
89  * @see org.jboss.mx.server.MBeanInvoker
90  *
91  * @author <a HREF="mailto:juha@jboss.org">Juha Lindfors</a>.
92  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>.
93  * @author Matt Munz
94  * @version $Revision: 56833 $
95  */

96 public abstract class ModelMBeanInvoker extends AbstractMBeanInvoker
97    implements ModelMBean JavaDoc, ModelMBeanConstants
98 {
99    Logger log = Logger.getLogger(ModelMBeanInvoker.class.getName());
100
101    // Attributes ----------------------------------------------------
102

103    /**
104     * The resource type string of the managed resource, such as
105     * {@link ModelMBeanConstants#OBJECT_REF} or
106     * {@link XMBeanConstants#STANDARD_INTERFACE}. This type string can be
107     * used by the invoker to determine the behavior implemented by the
108     * invocation chain and how the managed resource is exposed to the client
109     * programs.
110     */

111    protected String JavaDoc resourceType = null;
112    
113    /**
114     * Persistence manager.
115     */

116    protected PersistenceManager persistence = new NullPersistence();
117
118    /**
119     * Notification broadcaster for this Model MBean.
120     */

121    protected JBossNotificationBroadcasterSupport notifier = new JBossNotificationBroadcasterSupport();
122
123    /**
124     * Notification sequence number for generic Model MBean notifications.
125     */

126    protected long notifierSequence = 1;
127
128    /**
129     * Notification sequence number for attribute change notifications.
130     */

131    protected long attrNotifierSequence = 1;
132
133
134    // Constructors --------------------------------------------------
135

136    /**
137     * Default constructor.
138     */

139    public ModelMBeanInvoker()
140    {
141    }
142
143    /**
144     * Creates a Model MBean instance and initializes it with the given
145     * Model MBean metadata.
146     *
147     * @param info Model MBean metadata
148     */

149    public ModelMBeanInvoker(ModelMBeanInfo JavaDoc info) throws MBeanException JavaDoc
150    {
151       setModelMBeanInfo(info);
152    }
153
154
155
156    // ModelMBean implementation -------------------------------------
157

158    /**
159     * Sets the MBean metadata for this Model MBean instance.
160     *
161     * @param info Model MBean metadata
162     */

163    public void setModelMBeanInfo(ModelMBeanInfo JavaDoc info)
164       throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc
165    {
166       if (info == null)
167          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("MBeanInfo cannot be null"));
168
169       // need to type to an instance of MBeanInfo -- therefore the extra copy here
170
this.info = new ModelMBeanInfoSupport JavaDoc(info);
171
172       // Apply the MBeanInfo injection if requested
173
ModelMBeanInfo JavaDoc minfo = info;
174       Descriptor JavaDoc mbeanDescriptor = null;
175       try
176       {
177          mbeanDescriptor = minfo.getDescriptor("",
178                         ModelMBeanConstants.MBEAN_DESCRIPTOR);
179       }
180       catch (MBeanException JavaDoc e)
181       {
182          log.warn("Failed to obtain descriptor: "+ModelMBeanConstants.MBEAN_DESCRIPTOR, e);
183          return;
184       }
185
186       String JavaDoc type = (String JavaDoc) mbeanDescriptor.getFieldValue(
187          ModelMBeanConstants.MBEAN_INFO_INJECTION_TYPE);
188       if( type != null )
189       {
190          inject(ModelMBeanConstants.MBEAN_INFO_INJECTION_TYPE,
191             type, MBeanInfo JavaDoc.class, info);
192       }
193    }
194
195    /**
196     * Sets the managed resource for this Model MBean instance. The resource
197     * type must be known to the Model MBean implementation (see
198     * {@link #isSupportedResourceType} for more information).
199     *
200     * @param ref reference to the managed resource
201     * @param resourceType resource type identification string
202     */

203    public void setManagedResource(Object JavaDoc ref, String JavaDoc resourceType)
204       throws MBeanException JavaDoc, InstanceNotFoundException JavaDoc, InvalidTargetObjectTypeException JavaDoc
205    {
206       if (!isSupportedResourceType(ref, resourceType))
207          throw new InvalidTargetObjectTypeException JavaDoc("Unsupported resource type: " + resourceType);
208
209       setResource(ref);
210       this.resourceType = resourceType;
211
212       if (getServer() != null)
213       {
214          try
215          {
216             this.init(getServer(), resourceEntry.getObjectName());
217          }
218          catch(Exception JavaDoc e)
219          {
220             throw new MBeanException JavaDoc(e, "Failed to init from resource");
221          }
222       }
223    }
224
225    // ModelMBeanNotificationBroadcaster implementation --------------
226

227    public void addNotificationListener(NotificationListener JavaDoc listener,
228       NotificationFilter JavaDoc filter,
229       Object JavaDoc handback)
230    {
231       notifier.addNotificationListener(listener, filter, handback);
232    }
233
234    public void removeNotificationListener(NotificationListener JavaDoc listener)
235       throws ListenerNotFoundException JavaDoc
236    {
237       notifier.removeNotificationListener(listener);
238    }
239
240    public void removeNotificationListener(NotificationListener JavaDoc listener,
241       NotificationFilter JavaDoc filter,
242       Object JavaDoc handback)
243       throws ListenerNotFoundException JavaDoc
244    {
245       notifier.removeNotificationListener(listener, filter, handback);
246    }
247
248    /**
249     * Sends a notification with a given string message. The notification
250     * type will be set as
251     * {@link ModelMBeanConstants#GENERIC_MODELMBEAN_NOTIFICATION GENERIC_MODELMBEAN_NOTIFICATION}.
252     *
253     * @param ntfyText notification message
254     */

255    public void sendNotification(String JavaDoc ntfyText)
256       throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc
257    {
258       if( ntfyText == null )
259       {
260          throw new RuntimeOperationsException JavaDoc(
261            new IllegalArgumentException JavaDoc("ntfyText cannot be null")
262          );
263       }
264       Notification JavaDoc notif = new Notification JavaDoc(
265          GENERIC_MODELMBEAN_NOTIFICATION, // type
266
this, // source
267
1, // always 1 - by spec
268
ntfyText // message
269
);
270
271       sendNotification(notif);
272    }
273
274    /**
275     * Sends a notification.
276     *
277     * @param ntfyObj notification to send
278     */

279    public void sendNotification(Notification JavaDoc ntfyObj)
280       throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc
281    {
282       if( ntfyObj == null )
283       {
284          throw new RuntimeOperationsException JavaDoc(
285             new IllegalArgumentException JavaDoc("ntfyText cannot be null")
286          );
287       }
288       notifier.sendNotification(ntfyObj);
289    }
290
291    /**
292     * Sends an attribute change notification.
293     *
294     * @param notification attribute change notification to send
295     */

296    public void sendAttributeChangeNotification(AttributeChangeNotification JavaDoc notification)
297       throws MBeanException JavaDoc
298    {
299       if( notification == null )
300       {
301          throw new RuntimeOperationsException JavaDoc(
302             new IllegalArgumentException JavaDoc("notification cannot be null")
303          );
304       }
305       notifier.sendNotification(notification);
306    }
307
308    /**
309     * Sends an attribute change notification.
310     *
311     * @param oldValue attribute with the old value
312     * @param newValue attribute with the new value
313     * @throws IllegalArgumentException - An Attribute object passed in parameter
314     * is null or the names of the two Attribute objects in parameter are not
315     * the same.
316     */

317    public void sendAttributeChangeNotification(Attribute JavaDoc oldValue, Attribute JavaDoc newValue)
318       throws MBeanException JavaDoc, RuntimeOperationsException JavaDoc
319    {
320       if( oldValue == null || newValue == null )
321       {
322          throw new RuntimeOperationsException JavaDoc(
323             new IllegalArgumentException JavaDoc("Attribute cannot be null")
324          );
325       }
326       if (!(oldValue.getName().equals(newValue.getName())))
327       {
328          throw new RuntimeOperationsException JavaDoc(
329             new IllegalArgumentException JavaDoc("Attribute name mismatch between oldvalue and newvalue")
330          );
331       }
332
333       String JavaDoc attr = oldValue.getName();
334       String JavaDoc type = ((ModelMBeanInfo JavaDoc) info).getAttribute(attr).getType();
335
336       AttributeChangeNotification JavaDoc notif = new AttributeChangeNotification JavaDoc(
337          this, // source
338
1, // always 1 - by spec
339
System.currentTimeMillis(), // time stamp
340
"" + attr + " changed from " + oldValue + " to " + newValue,
341          attr, type, // name & type
342
oldValue.getValue(),
343          newValue.getValue() // values
344
);
345
346       notifier.sendNotification(notif);
347    }
348
349    public MBeanNotificationInfo JavaDoc[] getNotificationInfo()
350    {
351       return info.getNotifications();
352    }
353
354    /**
355     */

356    public void addAttributeChangeNotificationListener(
357       NotificationListener JavaDoc listener,
358       String JavaDoc attributeName,
359       Object JavaDoc handback) throws MBeanException JavaDoc
360    {
361       // Check the attribute info
362
ModelMBeanInfo JavaDoc minfo = (ModelMBeanInfo JavaDoc) info;
363       AttributeChangeNotificationFilter JavaDoc filter = null;
364       if (attributeName != null)
365       {
366          ModelMBeanAttributeInfo JavaDoc ainfo = minfo.getAttribute(attributeName);
367          if( ainfo == null )
368          {
369             throw new RuntimeOperationsException JavaDoc(
370                new IllegalArgumentException JavaDoc("Attribute does not exist: "+attributeName));
371          }
372          filter = new AttributeChangeNotificationFilter JavaDoc();
373          filter.enableAttribute(attributeName);
374       }
375       else
376       {
377          filter = new AttributeChangeNotificationFilter JavaDoc();
378          MBeanAttributeInfo JavaDoc[] allAttributes = minfo.getAttributes();
379          for (int i = 0; i < allAttributes.length; ++i)
380             filter.enableAttribute(allAttributes[i].getName());
381       }
382       notifier.addNotificationListener(listener, filter, handback);
383    }
384
385    /**
386     */

387    public void removeAttributeChangeNotificationListener(
388       NotificationListener JavaDoc listener,
389       String JavaDoc attributeName) throws MBeanException JavaDoc, ListenerNotFoundException JavaDoc
390    {
391       if( attributeName != null )
392       {
393          // Check the attribute info
394
ModelMBeanInfo JavaDoc minfo = (ModelMBeanInfo JavaDoc) info;
395          ModelMBeanAttributeInfo JavaDoc ainfo = minfo.getAttribute(attributeName);
396          if( ainfo == null )
397          {
398             throw new RuntimeOperationsException JavaDoc(
399                new IllegalArgumentException JavaDoc("Attribute does not exist: "+attributeName));
400          }
401       }
402       notifier.removeNotificationListener(listener);
403    }
404
405    // PersistentMBean implementation --------------------------------
406
public void load() throws MBeanException JavaDoc, InstanceNotFoundException JavaDoc
407    {
408       if (info == null)
409          return;
410
411       persistence.load(this, info);
412    }
413
414    public void store() throws MBeanException JavaDoc, InstanceNotFoundException JavaDoc
415    {
416       persistence.store(info);
417    }
418
419
420    // MBeanRegistration implementation ------------------------------
421

422    /**
423     * The default implementation of <tt>preRegister</tt> invokes the
424     * {@link #configureInterceptorStack} method which sets up the interceptors
425     * for this Model MBean instance. Subclasses may override the
426     * <tt>configureInterceptorStack()</tt> method to implement their own
427     * interceptor stack configurations. See the JavaDoc for
428     * <tt>configureInterceptorStack()</tt> for more information. <p>
429     *
430     * After the interceptor configuration, this implementation invokes the
431     * {@link #load} method on this Model MBean instance. This will attempt
432     * to load a pre-existing management attribute state for this Model MBean
433     * instance. See the Javadoc for <tt>load()</tt> for more information.
434     */

435    public ObjectName JavaDoc invokePreRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name)
436       throws Exception JavaDoc
437    {
438       // Check for null metadata and prevent registration if metadata
439
// has not been set
440
if (info == null)
441       {
442          throw new RuntimeErrorException JavaDoc(
443             new Error JavaDoc("MBeanInfo has not been set."));
444       }
445
446       // Set the mbean descriptor on the info context for use by interceptor config
447
final ModelMBeanInfo JavaDoc minfo = (ModelMBeanInfo JavaDoc) info;
448       Descriptor JavaDoc mbeanDescriptor = minfo.getMBeanDescriptor();
449       getMBeanInfoCtx = new InvocationContext();
450       getMBeanInfoCtx.setInvoker(this);
451       getMBeanInfoCtx.setDescriptor(mbeanDescriptor);
452       getMBeanInfoCtx.setDispatcher(new AbstractInterceptor("MBeanInfo Dispatcher")
453       {
454          public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
455          {
456             return minfo;
457          }
458       });
459       // JBAS-33 - No need to register the "getMBeanInfo" context to the operationsContextMap,
460
// this is only accessible through AbstractMBeanInvoker.getMBeanInfo().
461
// Registering it will result in duplicate interceptor construction.
462

463       // Need to install the setManagedResource op
464
// TODO, this is probably uneccessary now so revisit this
465
String JavaDoc[] signature = new String JavaDoc[]{"java.lang.Object", "java.lang.String"};
466       OperationKey opKey = new OperationKey("setManagedResource", signature);
467       InvocationContext ctx = new InvocationContext();
468       ctx.setInvoker(this);
469       ctx.setDispatcher(new AbstractInterceptor("SetMangedResource Dispatcher")
470       {
471          public Object JavaDoc invoke(Invocation invocation) throws Throwable JavaDoc
472          {
473             Object JavaDoc[] args = invocation.getArgs();
474             setManagedResource(args[0], (String JavaDoc) args[1]);
475             return null;
476          }
477       });
478       operationContextMap.put(opKey, ctx);
479
480       if (getResource() == null )
481       {
482          return name;
483       }
484       else
485       {
486          init(server, name);
487       }
488
489       return super.invokePreRegister(server, name);
490    }
491
492    // Protected ---------------------------------------------------
493

494    /**
495     *
496     * @param server
497     * @param name
498     * @throws Exception
499     */

500    protected void init(MBeanServer JavaDoc server, ObjectName JavaDoc name)
501       throws Exception JavaDoc
502    {
503       ModelMBeanInfo JavaDoc minfo = (ModelMBeanInfo JavaDoc) info;
504       configureInterceptorStack(minfo, server, name);
505       initDispatchers();
506
507       // add the resource classname to the MBean info
508
Object JavaDoc resource = getResource();
509       if (resource != null)
510       {
511          Descriptor JavaDoc mbeanDescriptor = minfo.getMBeanDescriptor();
512          String JavaDoc resClassName = getResource().getClass().getName();
513          mbeanDescriptor.setField(ModelMBeanConstants.RESOURCE_CLASS, resClassName);
514          minfo.setMBeanDescriptor(mbeanDescriptor);
515       }
516
517       //Set initial values provided in descriptors
518
setValuesFromMBeanInfo();
519
520       initPersistence(server, name);
521
522       //Set (and override) values from mbean persistence store.
523
load();
524    }
525
526    /**
527     * initializes the persistence manager based on the info for this bean.
528     * If this is successful, loads the bean from the persistence store.
529     */

530    protected void initPersistence(MBeanServer JavaDoc server, ObjectName JavaDoc name)
531       throws MBeanException JavaDoc, InstanceNotFoundException JavaDoc
532    {
533       Descriptor JavaDoc[] descriptors;
534       ModelMBeanInfo JavaDoc minfo = (ModelMBeanInfo JavaDoc) getMetaData();
535       
536       try
537       {
538          descriptors = minfo.getDescriptors(MBEAN_DESCRIPTOR);
539       }
540       catch (MBeanException JavaDoc e)
541       {
542          log.error("Failed to obtain MBEAN_DESCRIPTORs", e);
543          return;
544       }
545
546       if (descriptors == null)
547       {
548          return;
549       }
550       String JavaDoc persistMgrName = null;
551       for (int i = 0; ((i < descriptors.length) && (persistMgrName == null)); i++)
552       {
553          persistMgrName = (String JavaDoc) descriptors[i].getFieldValue(PERSISTENCE_MANAGER);
554       }
555       if (persistMgrName == null)
556       {
557          log.trace("No " + PERSISTENCE_MANAGER
558             + " descriptor found, null persistence will be used");
559          return;
560       }
561
562       try
563       {
564          persistence = (PersistenceManager) server.instantiate(persistMgrName);
565          log.debug("Loaded persistence mgr: " + persistMgrName);
566          
567          // Add the ObjectName to the ModelMBean Descriptor
568
// so that it can be used by the PersistentManager (if needed)
569
Descriptor JavaDoc descriptor = minfo.getMBeanDescriptor();
570          descriptor.setField(ModelMBeanConstants.OBJECT_NAME, name);
571          minfo.setMBeanDescriptor(descriptor);
572       }
573       catch (Exception JavaDoc cause)
574       {
575          log.error("Unable to instantiate the persistence manager:"
576             + persistMgrName, cause);
577       }
578    }
579
580    protected void initOperationContexts(MBeanOperationInfo JavaDoc[] operations)
581    {
582       // make sure we invoke the super class initialization sequence first
583
super.initOperationContexts(operations);
584
585       for (int i = 0; i < operations.length; ++i)
586       {
587          OperationKey key = new OperationKey(operations[i]);
588
589          InvocationContext ctx = (InvocationContext) operationContextMap.get(key);
590          ModelMBeanOperationInfo JavaDoc info = (ModelMBeanOperationInfo JavaDoc) operations[i];
591          ctx.setDescriptor(info.getDescriptor());
592       }
593    }
594
595    protected void initAttributeContexts(MBeanAttributeInfo JavaDoc[] attributes)
596    {
597       super.initAttributeContexts(attributes);
598
599       for (int i = 0; i < attributes.length; ++i)
600       {
601          ModelMBeanAttributeInfo JavaDoc info = (ModelMBeanAttributeInfo JavaDoc) attributes[i];
602          String JavaDoc name = info.getName();
603          InvocationContext ctx = (InvocationContext) attributeContextMap.get(name);
604          ctx.setDescriptor(info.getDescriptor());
605          ctx.setReadable(info.isReadable());
606          ctx.setWritable(info.isWritable());
607       }
608    }
609
610    /**
611     * Build the getMBeanInfo, operation, and attribute interceptor stacks
612     * and associated these with the corresponding InvocationContexts.
613     *
614     * @param info - the ModelMBean metadata
615     * @param server - the MBeanServer the ModelMBean is registering with
616     * @param name - the ModelMBean name
617     * @throws Exception
618     */

619    protected void configureInterceptorStack(ModelMBeanInfo JavaDoc info, MBeanServer JavaDoc server, ObjectName JavaDoc name)
620       throws Exception JavaDoc
621    {
622       // Get the MBeanInfo accessor interceptor stack. This is the interceptor
623
// stack declared at the model mbean level. In 3.2.3 and earlier this was
624
// the interceptor stack for all operation and attribute access so we
625
// use this as the default interceptor stack, for all attributes/operations.
626

627       List JavaDoc defaultInterceptors = getInterceptors(getMBeanInfoCtx.getDescriptor());
628       
629       List JavaDoc interceptors = null;
630       if (defaultInterceptors != null)
631       {
632          interceptors = new ArrayList JavaDoc(defaultInterceptors);
633       }
634       if (interceptors == null)
635       {
636          // Set the default interceptor stack
637
interceptors = getMBeanInfoCtx.getInterceptors();
638       }
639       // We always add the ModelMBeanInfoInterceptor as we expect that
640
// users are specifying additional interceptors, not overriding the
641
// source of the ModelMBeanInfo.
642

643       String JavaDoc mbeanName = name != null ? name.toString() : info.getClassName();
644       interceptors.add(new ModelMBeanInfoInterceptor(mbeanName));
645       getMBeanInfoCtx.setInterceptors(interceptors);
646
647       // Get any custom interceptors specified at the attribute level
648
for (Iterator JavaDoc it = attributeContextMap.entrySet().iterator(); it.hasNext();)
649       {
650          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
651
652          InvocationContext ctx = (InvocationContext) entry.getValue();
653          List JavaDoc list = getInterceptors(ctx.getDescriptor());
654          if (list == null)
655          {
656             // Use the mbean inteceptors if sepecified
657
if (defaultInterceptors != null)
658             {
659                list = new ArrayList JavaDoc(defaultInterceptors);
660             }
661             else
662             {
663                list = new ArrayList JavaDoc();
664             }
665          }
666          // Add the attribute accessor semantic interceptors
667
list.add(new PersistenceInterceptor());
668          list.add(new ModelMBeanAttributeInterceptor());
669          ctx.setInterceptors(list);
670       }
671
672       // Get any custom interceptors specified at the operation level
673
for (Iterator JavaDoc it = operationContextMap.entrySet().iterator(); it.hasNext();)
674       {
675          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
676
677          InvocationContext ctx = (InvocationContext) entry.getValue();
678          List JavaDoc list = getInterceptors(ctx.getDescriptor());
679          if (list == null && defaultInterceptors != null)
680             list = new ArrayList JavaDoc(defaultInterceptors);
681          
682          // Add operation caching (not for standard mbeans)
683
if (dynamicResource)
684          {
685             if (list == null)
686             {
687                list = new ArrayList JavaDoc();
688             }
689             list.add(new ModelMBeanOperationInterceptor());
690          }
691             
692          if (list != null)
693          {
694             // Add a noop interceptor since the 3.2.3- interceptors always had
695
// to delegate to the next in order to dispatch the operation. Now
696
// there is no interceptor for this so this prevents NPEs.
697

698             list.add(new NullInterceptor());
699             ctx.setInterceptors(list);
700          }
701       }
702    }
703
704    /**
705     *
706     * @param d
707     * @return
708     * @throws Exception
709     */

710    protected List JavaDoc getInterceptors(Descriptor JavaDoc d) throws Exception JavaDoc
711    {
712       if (d == null)
713          return null;
714       Descriptor JavaDoc[] interceptorDescriptors = (Descriptor JavaDoc[]) d.getFieldValue(INTERCEPTORS);
715       if (interceptorDescriptors == null)
716          return null;
717
718       ArrayList JavaDoc interceptors = new ArrayList JavaDoc();
719       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
720       for (int i = 0; i < interceptorDescriptors.length; i++)
721       {
722          Descriptor JavaDoc desc = interceptorDescriptors[i];
723          String JavaDoc code = (String JavaDoc) desc.getFieldValue("code");
724          // Ignore the legacy required interceptors
725
if (code.equals(ModelMBeanInterceptor.class.getName()) ||
726             code.equals(ObjectReferenceInterceptor.class.getName()) ||
727             code.equals(PersistenceInterceptor2.class.getName()))
728          {
729             log.debug("Ignoring obsolete legacy interceptor: " + code);
730             continue;
731          }
732
733          Class JavaDoc interceptorClass = loader.loadClass(code);
734          Interceptor interceptor = null;
735          // Check for a ctor(MBeanInvoker)
736
Class JavaDoc[] ctorSig = {MBeanInvoker.class};
737          try
738          {
739             Constructor JavaDoc ctor = interceptorClass.getConstructor(ctorSig);
740             Object JavaDoc[] ctorArgs = {this};
741             interceptor = (Interceptor) ctor.newInstance(ctorArgs);
742          }
743          catch (Throwable JavaDoc t)
744          {
745             log.debug("Could not invoke CTOR(MBeanInvoker) for '"
746                   + interceptorClass + "', trying default CTOR: " + t.getMessage());
747             
748             // Try the default ctor
749
interceptor = (Interceptor) interceptorClass.newInstance();
750          }
751          interceptors.add(interceptor);
752
753          // Apply any interceptor attributes
754
String JavaDoc[] names = desc.getFieldNames();
755          HashMap JavaDoc propertyMap = new HashMap JavaDoc();
756          if (names.length > 1)
757          {
758             BeanInfo JavaDoc beanInfo = Introspector.getBeanInfo(interceptorClass);
759             PropertyDescriptor JavaDoc[] props = beanInfo.getPropertyDescriptors();
760             for (int p = 0; p < props.length; p++)
761             {
762                String JavaDoc fieldName = props[p].getName();
763                propertyMap.put(fieldName, props[p]);
764             }
765             // Map each attribute to the corresponding interceptor property
766
for (int n = 0; n < names.length; n++)
767             {
768                String JavaDoc name = names[n];
769                if (name.equals("code"))
770                   continue;
771                String JavaDoc text = (String JavaDoc) desc.getFieldValue(name);
772                PropertyDescriptor JavaDoc pd = (PropertyDescriptor JavaDoc) propertyMap.get(name);
773                if (pd == null)
774                   throw new IntrospectionException JavaDoc("No PropertyDescriptor for attribute:" + name);
775                Method JavaDoc setter = pd.getWriteMethod();
776                if (setter != null)
777                {
778                   Class JavaDoc ptype = pd.getPropertyType();
779                   PropertyEditor JavaDoc editor = PropertyEditorManager.findEditor(ptype);
780                   if (editor == null)
781                      throw new IntrospectionException JavaDoc("Cannot convert string to interceptor attribute:" + name);
782                   editor.setAsText(text);
783                   Object JavaDoc args[] = {editor.getValue()};
784                   setter.invoke(interceptor, args);
785                }
786             }
787          }
788       }
789
790       if (interceptors.size() == 0)
791          interceptors = null;
792       return interceptors;
793    }
794
795    protected void setValuesFromMBeanInfo() throws JMException JavaDoc
796    {
797       for (Iterator JavaDoc it = attributeContextMap.entrySet().iterator(); it.hasNext();)
798       {
799          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
800          String JavaDoc key = (String JavaDoc) entry.getKey();
801
802          InvocationContext ctx = (InvocationContext) entry.getValue();
803          //Initialize value from descriptor.
804
Object JavaDoc value = ctx.getDescriptor().getFieldValue(XMBeanConstants.CACHED_VALUE);
805          if (value != null)
806          {
807             setAttribute(new Attribute JavaDoc(key, value));
808          } // end of if ()
809
}
810
811    }
812
813    protected boolean isSupportedResourceType(Object JavaDoc resource, String JavaDoc resourceType)
814    {
815       if (resourceType.equalsIgnoreCase(OBJECT_REF))
816          return true;
817
818       return false;
819    }
820
821    protected void override(Invocation invocation) throws MBeanException JavaDoc
822    {
823       // Do we allow for dynamic descriptor changes
824
if (dynamicResource && info != null)
825       {
826          Descriptor JavaDoc current = invocation.getDescriptor();
827          if (current != null)
828          {
829             ModelMBeanInfo JavaDoc mminfo = (ModelMBeanInfo JavaDoc) info;
830             Descriptor JavaDoc descriptor = mminfo.getDescriptor((String JavaDoc) current.getFieldValue(NAME), (String JavaDoc) current.getFieldValue(DESCRIPTOR_TYPE));
831             if (descriptor != null)
832                invocation.setDescriptor(descriptor);
833          }
834       }
835    }
836    
837 }
838
839
Popular Tags