KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > server > registry > BasicMBeanRegistry


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.server.registry;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.Vector JavaDoc;
29 import javax.management.Descriptor JavaDoc;
30 import javax.management.DynamicMBean JavaDoc;
31 import javax.management.InstanceAlreadyExistsException JavaDoc;
32 import javax.management.InstanceNotFoundException JavaDoc;
33 import javax.management.MBeanException JavaDoc;
34 import javax.management.MBeanInfo JavaDoc;
35 import javax.management.MBeanRegistration JavaDoc;
36 import javax.management.MBeanRegistrationException JavaDoc;
37 import javax.management.MBeanServer JavaDoc;
38 import javax.management.MBeanServerDelegate JavaDoc;
39 import javax.management.MBeanServerNotification JavaDoc;
40 import javax.management.MalformedObjectNameException JavaDoc;
41 import javax.management.NotCompliantMBeanException JavaDoc;
42 import javax.management.ObjectInstance JavaDoc;
43 import javax.management.ObjectName JavaDoc;
44 import javax.management.ReflectionException JavaDoc;
45 import javax.management.RuntimeErrorException JavaDoc;
46 import javax.management.RuntimeMBeanException JavaDoc;
47 import javax.management.RuntimeOperationsException JavaDoc;
48 import javax.management.loading.ClassLoaderRepository JavaDoc;
49 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
50 import javax.management.modelmbean.RequiredModelMBean JavaDoc;
51
52 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
53 import EDU.oswego.cs.dl.util.concurrent.SynchronizedLong;
54 import org.jboss.logging.Logger;
55 import org.jboss.mx.loading.LoaderRepository;
56 import org.jboss.mx.loading.RepositoryClassLoader;
57 import org.jboss.mx.metadata.MBeanCapability;
58 import org.jboss.mx.modelmbean.ModelMBeanConstants;
59 import org.jboss.mx.modelmbean.RequiredModelMBeanInvoker;
60 import org.jboss.mx.modelmbean.XMBean;
61 import org.jboss.mx.modelmbean.XMBeanConstants;
62 import org.jboss.mx.server.AbstractMBeanInvoker;
63 import org.jboss.mx.server.MBeanInvoker;
64 import org.jboss.mx.server.RawDynamicInvoker;
65 import org.jboss.mx.server.ServerConfig;
66 import org.jboss.mx.server.ServerObjectInstance;
67 import org.jboss.mx.util.ObjectNamePatternHelper;
68 import org.jboss.mx.util.ObjectNamePatternHelper.PropertyPattern;
69 import org.jboss.util.NestedRuntimeException;
70
71 /**
72  * The registry for object name - object reference mapping in the
73  * MBean server.
74  * <p>
75  * The implementation of this class affects the invocation speed
76  * directly, please check any changes for performance.
77  *
78  * @todo JMI_DOMAIN isn't very protected
79  *
80  * @see org.jboss.mx.server.registry.MBeanRegistry
81  *
82  * @author <a HREF="mailto:juha@jboss.org">Juha Lindfors</a>.
83  * @author <a HREF="mailto:trevor@protocool.com">Trevor Squires</a>.
84  * @author <a HREF="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
85  * @author <a HREF="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>.
86  * @author <a HREF="mailto:thomas.diesler@jboss.com">Thomas Diesler</a>.
87  *
88  * @version $Revision: 42608 $
89  */

90 public class BasicMBeanRegistry
91    implements MBeanRegistry
92 {
93    // Constants -----------------------------------------------------
94

95    /** The server config */
96    private static ServerConfig serverConfig = ServerConfig.getInstance();
97
98    /** The default domain */
99    private static String JavaDoc JMI_DOMAIN = serverConfig.getJMIDomain();
100
101    // Attributes ----------------------------------------------------
102

103    /**
104     * A map of domain name to another map containing object name canonical
105     * key properties to registry entries.
106     * domain -> canonicalKeyProperties -> MBeanEntry
107     */

108    private Map JavaDoc domainMap = new ConcurrentReaderHashMap();
109
110    /**
111     * The default domain for this registry
112     */

113    private String JavaDoc defaultDomain;
114
115    /**
116     * The MBeanServer for which we are the registry.
117     */

118    private MBeanServer JavaDoc server;
119
120    /**
121     * The loader repository for loading classes
122     */

123    private LoaderRepository JavaDoc loaderRepository;
124
125    /**
126     * Sequence number for the MBean server registration notifications.
127     */

128    protected final SynchronizedLong registrationNotificationSequence = new SynchronizedLong (1);
129
130    /**
131     * Sequence number for the MBean server unregistration notifications.
132     */

133    protected final SynchronizedLong unregistrationNotificationSequence = new SynchronizedLong (1);
134
135    /**
136     * Direct reference to the mandatory MBean server delegate MBean.
137     */

138    protected MBeanServerDelegate JavaDoc delegate;
139
140    protected Vector JavaDoc fMbInfosToStore;
141    private ObjectName JavaDoc mbeanInfoService;
142
143
144    // Static --------------------------------------------------------
145

146    /**
147     * The logger
148     */

149    protected static Logger log = Logger.getLogger(BasicMBeanRegistry.class);
150
151
152    // Constructors --------------------------------------------------
153

154    /**
155     * Constructs a new BasicMBeanRegistry.<p>
156     */

157    public BasicMBeanRegistry(MBeanServer JavaDoc server, String JavaDoc defaultDomain, ClassLoaderRepository JavaDoc clr)
158    {
159       // Store the context
160
this.server = server;
161       this.defaultDomain = defaultDomain;
162
163       try
164       {
165          loaderRepository = (LoaderRepository JavaDoc) clr;
166          mbeanInfoService = new ObjectName JavaDoc("user:service=MBeanInfoDB");
167       }
168       catch (Exception JavaDoc e)
169       {
170          throw new NestedRuntimeException("Error instantiating registry", e);
171       }
172    }
173
174
175    // MBeanRegistry Implementation ----------------------------------
176

177    public ObjectInstance JavaDoc registerMBean(Object JavaDoc object, ObjectName JavaDoc name, Map JavaDoc valueMap)
178       throws InstanceAlreadyExistsException JavaDoc, MBeanRegistrationException JavaDoc, NotCompliantMBeanException JavaDoc
179    {
180       ObjectName JavaDoc regName = name;
181       boolean registrationDone = true;
182       boolean invokedPreRegister = false;
183       String JavaDoc magicToken = null;
184       MBeanInvoker invoker = null;
185
186       if (object == null)
187          throw new RuntimeOperationsException JavaDoc(
188                new IllegalArgumentException JavaDoc("Attempting to register null object"));
189
190       // get mbean type, dynamic or standard
191
MBeanCapability mbcap = MBeanCapability.of(object.getClass());
192
193       try
194       {
195
196          if (valueMap != null)
197             magicToken = (String JavaDoc) valueMap.get(JMI_DOMAIN);
198
199          // TODO: allow custom factory for diff invoker types
200
int mbeanType = mbcap.getMBeanType();
201          if (mbeanType == MBeanCapability.STANDARD_MBEAN)
202          {
203             invoker = new XMBean(object, XMBeanConstants.STANDARD_MBEAN);
204          }
205          else if (object instanceof MBeanInvoker)
206          {
207             invoker = (MBeanInvoker)object;
208          }
209          else if (mbeanType == MBeanCapability.DYNAMIC_MBEAN)
210          {
211             if( object instanceof RequiredModelMBean JavaDoc )
212                invoker = new RequiredModelMBeanInvoker((DynamicMBean JavaDoc)object);
213             else
214                invoker = new RawDynamicInvoker((DynamicMBean JavaDoc)object);
215          }
216
217          // Perform the pregistration
218
MBeanEntry entry = new MBeanEntry(regName, invoker, object, valueMap);
219          AbstractMBeanInvoker.setMBeanEntry(entry);
220          regName = invokePreRegister(invoker, regName, magicToken);
221          invokedPreRegister = true;
222
223          try
224          {
225             MBeanInfo JavaDoc info = invoker.getMBeanInfo();
226             verifyMBeanInfo(info, name);
227             entry.setResourceClassName(info.getClassName());
228
229             // Register the mbean
230

231             // Update the registered name to the final value
232
entry.setObjectName(regName);
233
234             add(entry);
235
236             try
237             {
238                // Add the classloader to the repository
239
if (object instanceof ClassLoader JavaDoc)
240                   registerClassLoader((ClassLoader JavaDoc)object);
241
242                try
243                {
244                   if (delegate != null)
245                      sendRegistrationNotification (regName);
246                   else if (serverConfig.getMBeanServerDelegateName().equals(name))
247                      delegate = (MBeanServerDelegate JavaDoc) object;
248
249                   ServerObjectInstance serverObjInst = new ServerObjectInstance
250                         (regName, entry.getResourceClassName(), delegate.getMBeanServerId());
251
252                   persistIfRequired(invoker.getMBeanInfo(), regName);
253
254                   return serverObjInst;
255
256                }
257                catch (Throwable JavaDoc t)
258                {
259                   // Problem, remove a classloader from the repository
260
if (object instanceof ClassLoader JavaDoc)
261                      loaderRepository.removeClassLoader((ClassLoader JavaDoc)object);
262
263                   throw t;
264                }
265             }
266             catch (Throwable JavaDoc t)
267             {
268                // Problem, remove the mbean from the registry
269
remove(regName);
270                throw t;
271             }
272          }
273          // Throw for null MBeanInfo
274
catch (NotCompliantMBeanException JavaDoc e)
275          {
276             throw e;
277          }
278          // Thrown by the registry
279
catch (InstanceAlreadyExistsException JavaDoc e)
280          {
281             throw e;
282          }
283          catch (Throwable JavaDoc t)
284          {
285             // Something is broken
286
log.error("Unexpected Exception:", t);
287             throw t;
288          }
289       }
290       catch (NotCompliantMBeanException JavaDoc e)
291       {
292          registrationDone = false;
293          throw e;
294       }
295       catch (InstanceAlreadyExistsException JavaDoc e)
296       {
297          // It was already registered
298
registrationDone = false;
299          throw e;
300       }
301       catch (MBeanRegistrationException JavaDoc e)
302       {
303          // The MBean cancelled the registration
304
registrationDone = false;
305          log.warn(e.toString());
306          throw e;
307       }
308       catch (RuntimeOperationsException JavaDoc e)
309       {
310          // There was a problem with one the arguments
311
registrationDone = false;
312          throw e;
313       }
314       catch (Exception JavaDoc ex)
315       {
316          // any other exception is mapped to NotCompliantMBeanException
317
registrationDone = false;
318          NotCompliantMBeanException JavaDoc ncex = new NotCompliantMBeanException JavaDoc("Cannot register MBean: " + name);
319          ncex.initCause(ex);
320          throw ncex;
321       }
322       catch (Throwable JavaDoc t)
323       {
324          // Some other error
325
log.error("Cannot register MBean", t);
326          registrationDone = false;
327          return null;
328       }
329       finally
330       {
331          // Tell the MBean the result of the registration
332
if (invoker != null)
333          {
334             try
335             {
336                invoker.postRegister(new Boolean JavaDoc(registrationDone));
337             }
338             catch(Exception JavaDoc e)
339             {
340                // Only throw this if preRegister succeeded
341
if( invokedPreRegister == true )
342                {
343                   if( e instanceof RuntimeException JavaDoc )
344                      throw new RuntimeMBeanException JavaDoc((RuntimeException JavaDoc) e);
345                   else
346                      throw new MBeanRegistrationException JavaDoc(e);
347                }
348             }
349          }
350          AbstractMBeanInvoker.setMBeanEntry(null);
351       }
352     }
353
354    /**
355     * Verifies the MBeanInfo and throws an exception if something is wrong.
356     * @param info a MBeanInfo
357     * @param name a ObjectName
358     * @throws NotCompliantMBeanException when something is wrong with the MBean info
359     */

360    private void verifyMBeanInfo(MBeanInfo JavaDoc info, ObjectName JavaDoc name)
361            throws NotCompliantMBeanException JavaDoc
362    {
363       try
364       {
365          if (info == null)
366             throw new NotCompliantMBeanException JavaDoc("MBeanInfo cannot be null, for: " + name);
367
368          if (info.getClassName() == null)
369             throw new NotCompliantMBeanException JavaDoc("Classname returned from MBeanInfo cannot be null, for: " + name);
370       }
371       catch (NotCompliantMBeanException JavaDoc ncex)
372       {
373          throw ncex;
374       }
375       catch (Throwable JavaDoc t)
376       {
377          NotCompliantMBeanException JavaDoc ncex = new NotCompliantMBeanException JavaDoc("Cannot verify MBeanInfo, for: " + name);
378          ncex.initCause(t);
379          throw ncex;
380       }
381    }
382
383    /**
384      * send a MBeanServerNotification.REGISTRATION_NOTIFICATION notification
385      * to regName
386      *
387      * @param regName
388      */

389     protected void sendRegistrationNotification (ObjectName JavaDoc regName)
390     {
391         long sequence = registrationNotificationSequence.increment ();
392         delegate.sendNotification (
393                 new MBeanServerNotification JavaDoc (
394                         MBeanServerNotification.REGISTRATION_NOTIFICATION,
395                         delegate, sequence, regName));
396     }
397
398     /**
399      * subclasses can override to provide their own pre-registration pre- and post- logic for
400      * <tt>preRegister</tt> and must call preRegister on the MBeanRegistration instance
401      *
402      * @param registrationInterface
403      * @param regName
404      * @return object name
405      * @throws Exception
406      */

407     protected ObjectName JavaDoc handlePreRegistration (MBeanRegistration JavaDoc registrationInterface, ObjectName JavaDoc regName)
408             throws Exception JavaDoc
409     {
410         ObjectName JavaDoc mbean = registrationInterface.preRegister (server, regName);
411         if (regName == null)
412         {
413             return mbean;
414         }
415         else
416         {
417             return regName;
418         }
419     }
420
421
422     /**
423      * subclasses can override to provide any custom preDeregister logic
424      * and must call preDregister on the MBeanRegistration instance
425      *
426      * @param registrationInterface
427      * @throws Exception
428      */

429     protected void handlePreDeregister (MBeanRegistration JavaDoc registrationInterface)
430             throws Exception JavaDoc
431     {
432         registrationInterface.preDeregister ();
433     }
434
435     /**
436      * Subclasses can override if they wish to control the classloader
437      * registration to loader repository.
438      *
439      * @param cl classloader
440      */

441     protected void registerClassLoader(ClassLoader JavaDoc cl)
442     {
443        if( (cl instanceof RepositoryClassLoader) == false )
444        {
445          // Only register non-UCLs as UCLs already have a repository
446
loaderRepository.addClassLoader(cl);
447        }
448     }
449
450
451    public void unregisterMBean(ObjectName JavaDoc name)
452       throws InstanceNotFoundException JavaDoc, MBeanRegistrationException JavaDoc
453    {
454       name = qualifyName(name);
455       if (name.getDomain().equals(JMI_DOMAIN))
456          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc(
457             "Not allowed to unregister: " + name.toString()));
458
459       MBeanEntry entry = get(name);
460       Object JavaDoc resource = entry.getResourceInstance();
461
462       try
463       {
464           // allow subclasses to perform their own pre- and post- pre-deregister logic
465
handlePreDeregister (entry.getInvoker());
466
467       }
468       catch (Exception JavaDoc e)
469       {
470          // don't double wrap MBeanRegistrationException
471
if (e instanceof MBeanRegistrationException JavaDoc)
472             throw (MBeanRegistrationException JavaDoc)e;
473
474          throw new MBeanRegistrationException JavaDoc(e, "preDeregister");
475       }
476
477       // Remove any classloader
478
if (resource instanceof ClassLoader JavaDoc)
479          loaderRepository.removeClassLoader((ClassLoader JavaDoc)resource);
480
481       // It is no longer registered
482
remove(name);
483
484       sendUnRegistrationNotification (name);
485
486       entry.getInvoker().postDeregister();
487    }
488
489   /**
490    * send MBeanServerNotification.UNREGISTRATION_NOTIFICATION notification to
491    * name
492    *
493    * @param name
494    */

495   protected void sendUnRegistrationNotification (ObjectName JavaDoc name)
496   {
497       long sequence = unregistrationNotificationSequence.increment ();
498
499       delegate.sendNotification (
500               new MBeanServerNotification JavaDoc (
501                       MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
502                       delegate,
503                       sequence,
504                       name
505               )
506       );
507   }
508
509    public MBeanEntry get(ObjectName JavaDoc name)
510       throws InstanceNotFoundException JavaDoc
511    {
512       if (name == null)
513          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc("null object name"));
514
515       // Determine the domain and retrieve its entries
516
String JavaDoc domain = name.getDomain();
517
518       if (domain.length() == 0)
519          domain = defaultDomain;
520
521       String JavaDoc props = name.getCanonicalKeyPropertyListString();
522       Map JavaDoc mbeanMap = getMBeanMap(domain, false);
523
524       // Retrieve the mbean entry
525
Object JavaDoc o = null;
526       if (null == mbeanMap || null == (o = mbeanMap.get(props)))
527          throw new InstanceNotFoundException JavaDoc(name + " is not registered.");
528
529       // We are done
530
return (MBeanEntry) o;
531    }
532
533    public String JavaDoc getDefaultDomain()
534    {
535       return defaultDomain;
536    }
537
538    public String JavaDoc[] getDomains()
539    {
540       ArrayList JavaDoc domains = new ArrayList JavaDoc(domainMap.size());
541       for (Iterator JavaDoc iterator = domainMap.entrySet().iterator(); iterator.hasNext();)
542       {
543          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
544          String JavaDoc domainName = (String JavaDoc) entry.getKey();
545          Map JavaDoc mbeans = (Map JavaDoc) entry.getValue();
546          if (mbeans != null && mbeans.isEmpty() == false)
547             domains.add(domainName);
548       }
549       return (String JavaDoc[]) domains.toArray(new String JavaDoc[domains.size()]);
550    }
551
552    public ObjectInstance JavaDoc getObjectInstance(ObjectName JavaDoc name)
553       throws InstanceNotFoundException JavaDoc
554    {
555       if (!contains(name))
556          throw new InstanceNotFoundException JavaDoc(name + " not registered.");
557
558       return new ServerObjectInstance(qualifyName(name),
559          get(name).getResourceClassName(), delegate.getMBeanServerId());
560    }
561
562    public Object JavaDoc getValue(ObjectName JavaDoc name, String JavaDoc key)
563       throws InstanceNotFoundException JavaDoc
564    {
565       return get(name).getValue(key);
566    }
567
568    public boolean contains(ObjectName JavaDoc name)
569    {
570       // null safety check
571
if (name == null)
572          return false;
573
574       // Determine the domain and retrieve its entries
575
String JavaDoc domain = name.getDomain();
576
577       if (domain.length() == 0)
578          domain = defaultDomain;
579
580       String JavaDoc props = name.getCanonicalKeyPropertyListString();
581       Map JavaDoc mbeanMap = getMBeanMap(domain, false);
582
583       // Return the result
584
return (null != mbeanMap && mbeanMap.containsKey(props));
585    }
586
587    public int getSize()
588    {
589       int retval = 0;
590        for (Iterator JavaDoc iterator = domainMap.values().iterator(); iterator.hasNext();)
591        {
592           retval += ((Map JavaDoc)iterator.next()).size();
593        }
594      return retval;
595    }
596
597    public List JavaDoc findEntries(ObjectName JavaDoc pattern)
598    {
599       ArrayList JavaDoc retval = new ArrayList JavaDoc();
600
601       // There are a couple of shortcuts we can employ to make this a
602
// bit faster - they're commented.
603

604       // First, if pattern == null or pattern.getCanonicalName() == "*:*" we want the
605
// set of all MBeans.
606
if (pattern == null || pattern.getCanonicalName().equals("*:*"))
607       {
608           for (Iterator JavaDoc domainIter = domainMap.values().iterator(); domainIter.hasNext();)
609              retval.addAll(((Map JavaDoc)domainIter.next()).values());
610       }
611       // Next, if !pattern.isPattern() then we are doing a simple get (maybe defaultDomain).
612
else if (!pattern.isPattern())
613       {
614          // simple get
615
try
616          {
617             retval.add(get(pattern));
618          }
619          catch (InstanceNotFoundException JavaDoc e)
620          {
621             // we don't care
622
}
623       }
624       // Now we have to do a brute force, oh well.
625
else
626       {
627          String JavaDoc patternDomain = pattern.getDomain();
628          if (patternDomain.length() == 0)
629             patternDomain = defaultDomain;
630          PropertyPattern propertyPattern = new PropertyPattern(pattern);
631
632          // Here we go, step through every domain and see if our pattern matches before optionally checking
633
// each ObjectName's properties for a match.
634
for (Iterator JavaDoc domainIter = domainMap.entrySet().iterator(); domainIter.hasNext();)
635          {
636             Map.Entry JavaDoc mapEntry = (Map.Entry JavaDoc) domainIter.next();
637             Map JavaDoc value = (Map JavaDoc) mapEntry.getValue();
638             if (value != null && value.isEmpty() == false)
639             {
640                if (ObjectNamePatternHelper.patternMatch((String JavaDoc) mapEntry.getKey(), patternDomain))
641                {
642                   for (Iterator JavaDoc mbeanIter = value.values().iterator(); mbeanIter.hasNext();)
643                   {
644                      MBeanEntry entry = (MBeanEntry) mbeanIter.next();
645                      if (propertyPattern.patternMatch(entry.getObjectName()))
646                         retval.add(entry);
647                   }
648                }
649             }
650          }
651       }
652
653       return retval;
654    }
655
656
657    /**
658     * Cleans up the registry before the MBean server is released.
659     */

660    public void releaseRegistry()
661       // This is based on patch by Rod Burgett (Bug report: 763378)
662
// Modified. Server is calling the registry.
663
{
664        server = null;
665        delegate = null;
666
667        // clear each value element from the domainMap
668
for (Iterator JavaDoc iterator = domainMap.keySet().iterator(); iterator.hasNext();)
669        {
670           Map JavaDoc nextMap = (Map JavaDoc) domainMap.get(iterator.next());
671
672           if ( nextMap.size() > 0 )
673           {
674              nextMap.clear();
675           }
676        }
677
678        domainMap.clear();
679        domainMap = null;
680    }
681
682
683    // Protected -----------------------------------------------------
684

685    protected ObjectName JavaDoc invokePreRegister(MBeanInvoker invoker, ObjectName JavaDoc regName, String JavaDoc magicToken)
686       throws MBeanRegistrationException JavaDoc, NotCompliantMBeanException JavaDoc
687    {
688
689       // if we were given a non-null object name for registration, qualify it
690
// and expand default domain
691
if (regName != null)
692          regName = qualifyName(regName);
693
694       // store the name returned by preRegister() here
695
ObjectName JavaDoc mbeanName = null;
696
697       try
698       {
699          // invoke preregister on the invoker, it will delegate to the resource
700
// if needed
701
mbeanName = invoker.preRegister(server, regName);
702       }
703       // if during pre registration, the mbean turns out to be not compliant
704
catch (NotCompliantMBeanException JavaDoc ncex)
705       {
706          throw ncex;
707
708       }
709       // catch all exceptions cause by preRegister, these will abort registration
710
catch (Exception JavaDoc e)
711       {
712          if (e instanceof MBeanRegistrationException JavaDoc)
713          {
714             throw (MBeanRegistrationException JavaDoc)e;
715          }
716
717          throw new MBeanRegistrationException JavaDoc(e,
718                "preRegister() failed: " +
719                "[ObjectName='" + regName +
720                "', Class=" + invoker.getResource().getClass().getName() +
721                " (" + invoker.getResource() + ")]"
722          );
723       }
724       catch (Throwable JavaDoc t)
725       {
726          log.warn("preRegister() failed for " + regName + ": ", t);
727
728          if (t instanceof Error JavaDoc)
729             throw new RuntimeErrorException JavaDoc((Error JavaDoc)t);
730          else
731             throw new RuntimeException JavaDoc(t.toString());
732       }
733
734
735       // if registered with null name, use the default name returned by
736
// the preregister implementation
737
if (regName == null)
738          regName = mbeanName;
739
740       return validateAndQualifyName(regName, magicToken);
741    }
742
743    /**
744     * Adds an MBean entry<p>
745     *
746     * WARNING: The object name should be fully qualified.
747     *
748     * @param entry the MBean entry to add
749     * @exception InstanceAlreadyExistsException when the MBean's object name
750     * is already registered
751     */

752    protected synchronized void add(MBeanEntry entry)
753       throws InstanceAlreadyExistsException JavaDoc
754    {
755       // Determine the MBean's name and properties
756
ObjectName JavaDoc name = entry.getObjectName();
757       String JavaDoc domain = name.getDomain();
758       String JavaDoc props = name.getCanonicalKeyPropertyListString();
759
760       // Create a properties -> entry map if we don't have one
761
Map JavaDoc mbeanMap = getMBeanMap(domain, true);
762
763       // Make sure we aren't already registered
764
if (mbeanMap.get(props) != null)
765          throw new InstanceAlreadyExistsException JavaDoc(name + " already registered.");
766
767       // Ok, we are registered
768
mbeanMap.put(props, entry);
769    }
770
771    /**
772     * Removes an MBean entry
773     *
774     * WARNING: The object name should be fully qualified.
775     *
776     * @param name the object name of the entry to remove
777     * @exception InstanceNotFoundException when the object name is not
778     * registered
779     */

780    protected synchronized void remove(ObjectName JavaDoc name)
781       throws InstanceNotFoundException JavaDoc
782    {
783       // Determine the MBean's name and properties
784
String JavaDoc domain = name.getDomain();
785       String JavaDoc props = name.getCanonicalKeyPropertyListString();
786       Map JavaDoc mbeanMap = getMBeanMap(domain, false);
787
788       // Remove the entry, raise an exception when it didn't exist
789
if (null == mbeanMap || null == mbeanMap.remove(props))
790          throw new InstanceNotFoundException JavaDoc(name + " not registered.");
791    }
792
793    /**
794     * Validates and qualifies an MBean<p>
795     *
796     * Validates the name is not a pattern.<p>
797     *
798     * Adds the default domain if no domain is specified.<p>
799     *
800     * Checks the name is not in the reserved domain JMImplementation when
801     * the magicToken is not {@link org.jboss.mx.server.ServerConstants#JMI_DOMAIN JMI_DOMAIN}
802     *
803     * @param name the name to validate
804     * @param magicToken used to get access to the reserved domain
805     * @return the original name or the name prepended with the default domain
806     * if no domain is specified.
807     * @exception RuntimeOperationsException containing an
808     * IllegalArgumentException for a problem with the name
809     */

810    protected ObjectName JavaDoc validateAndQualifyName(ObjectName JavaDoc name,
811                                                String JavaDoc magicToken)
812    {
813       // Check for qualification
814
ObjectName JavaDoc result = qualifyName(name);
815
816       // Make sure the name is not a pattern
817
if (result.isPattern())
818          throw new RuntimeOperationsException JavaDoc(
819                new IllegalArgumentException JavaDoc("Object name is a pattern:" + name));
820
821       // Check for reserved domain
822
if (magicToken != JMI_DOMAIN &&
823           result.getDomain().equals(JMI_DOMAIN))
824          throw new RuntimeOperationsException JavaDoc(new IllegalArgumentException JavaDoc(
825                      "Domain " + JMI_DOMAIN + " is reserved"));
826
827       // I can't think of anymore tests, we're done
828
return result;
829    }
830
831    /**
832     * Qualify an object name with the default domain<p>
833     *
834     * Adds the default domain if no domain is specified.
835     *
836     * @param name the name to qualify
837     * @return the original name or the name prepended with the default domain
838     * if no domain is specified.
839     * @exception RuntimeOperationsException containing an
840     * IllegalArgumentException when there is a problem
841     */

842    protected ObjectName JavaDoc qualifyName(ObjectName JavaDoc name)
843    {
844       if (name == null)
845          throw new RuntimeOperationsException JavaDoc(
846                new IllegalArgumentException JavaDoc("Null object name"));
847       try
848       {
849          if (name.getDomain().length() == 0)
850             return new ObjectName JavaDoc(defaultDomain + ":" +
851                                   name.getCanonicalKeyPropertyListString());
852          else
853             return name;
854       }
855       catch (MalformedObjectNameException JavaDoc e)
856       {
857          throw new RuntimeOperationsException JavaDoc(
858                new IllegalArgumentException JavaDoc(e.toString()));
859       }
860    }
861
862    /**
863     * Adds the given MBean Info object to the persistence queue if it explicity denotes
864     * (via metadata) that it should be stored.
865     * @todo -- add notification of registration of MBeanInfoDb.
866     * It is possible that some MBeans whose MBean Info should be stored are
867     * registered before the MBean Info Storage delegate is available. These
868     * MBeans are remembered by the registry and should be added to the storage delegate
869     * as soon as it is available. In the current mechanism, they are added only if another
870     * MBean requesting MBean info persistence is registered after the delegate is registered.
871     * Someone more familiar with the server could make this more robust by adding
872     * a notification mechanism such that the queue is flushed as soon as the
873     * delegate is available. - Matt Munz
874     * @todo does this code need to be here? can't a notification listener be
875     * registered with the MBeanServerDelegate that stores a backlog
876     * until the service becomes available?
877     * @todo the mbInfoStores is a memory leak if the service is never registered
878     * @todo mbInfoStores is not synchronized correctly
879     * Thread1 adds
880     * Thread1 clones and invokes
881     * Thread2 adds
882     * Thread1 clears
883     * Thread2's add is lost
884     * @todo Don't use Vector, performs too fine grained synchronization,
885     * probably not important in this case.
886     */

887    protected void persistIfRequired(MBeanInfo JavaDoc info, ObjectName JavaDoc name)
888      throws
889        MalformedObjectNameException JavaDoc,
890        InstanceNotFoundException JavaDoc,
891        MBeanException JavaDoc,
892        ReflectionException JavaDoc
893    {
894      if(!(info instanceof ModelMBeanInfo JavaDoc))
895      {
896          return;
897      }
898      ModelMBeanInfo JavaDoc mmbInfo = (ModelMBeanInfo JavaDoc) info;
899      Descriptor JavaDoc descriptor;
900      try
901      {
902         descriptor = mmbInfo.getMBeanDescriptor();
903      }
904      catch(MBeanException JavaDoc cause)
905      {
906        log.error("Error trying to get descriptors.", cause);
907        return;
908      }
909      if (descriptor == null)
910         return;
911      String JavaDoc persistInfo = (String JavaDoc) descriptor.getFieldValue(ModelMBeanConstants.PERSIST_INFO);
912      if (persistInfo == null)
913         return; // use default -- no persistence
914
log.debug("persistInfo: " + persistInfo);
915      Boolean JavaDoc shouldPersist = new Boolean JavaDoc(persistInfo);
916      if(!shouldPersist.booleanValue())
917      {
918         return;
919      }
920      mbInfosToStore().add(name);
921      // see if MBeanDb is available
922
if(contains(mbeanInfoService))
923      {
924        // flush queue to the MBeanDb
925
log.debug("flushing queue");
926        server.invoke(
927          mbeanInfoService,
928          "add",
929          new Object JavaDoc[] { mbInfosToStore().clone() },
930          new String JavaDoc[] { mbInfosToStore().getClass().getName() });
931        log.debug("clearing queue");
932        mbInfosToStore().clear();
933      }
934      else
935      {
936        log.debug("service is not registered. items remain in queue");
937      }
938    }
939
940    /**
941     * ObjectName objects bound to MBean Info objects that are waiting to be stored in the
942     * persistence store.
943     */

944    protected Vector JavaDoc mbInfosToStore()
945    {
946       if(fMbInfosToStore == null)
947       {
948          fMbInfosToStore = new Vector JavaDoc(10);
949       }
950       return fMbInfosToStore;
951    }
952
953    /**
954     * The <code>getMBeanMap</code> method provides synchronized access
955     * to the mbean map for a domain. This is actually a solution to a
956     * bug that resulted in wiping out the jboss domain mbeanMap for no
957     * apparent reason.
958     *
959     * @param domain a <code>String</code> value
960     * @param createIfMissing a <code>boolean</code> value
961     * @return a <code>Map</code> value
962     */

963    private Map JavaDoc getMBeanMap(String JavaDoc domain, boolean createIfMissing)
964    {
965       Map JavaDoc mbeanMap = (Map JavaDoc) domainMap.get(domain);
966       if (mbeanMap == null && createIfMissing)
967       {
968         mbeanMap = new ConcurrentReaderHashMap();
969         domainMap.put(domain, mbeanMap);
970       }
971       return mbeanMap;
972    }
973 }
Popular Tags