Source Code Cross Referenced for BasicMBeanRegistry.java in  » EJB-Server-JBoss-4.2.1 » jmx » org » jboss » mx » server » registry » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server JBoss 4.2.1 » jmx » org.jboss.mx.server.registry 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.mx.server.registry;
023:
024:        import java.util.ArrayList;
025:        import java.util.Iterator;
026:        import java.util.List;
027:        import java.util.Map;
028:        import java.util.Vector;
029:        import javax.management.Descriptor;
030:        import javax.management.DynamicMBean;
031:        import javax.management.InstanceAlreadyExistsException;
032:        import javax.management.InstanceNotFoundException;
033:        import javax.management.MBeanException;
034:        import javax.management.MBeanInfo;
035:        import javax.management.MBeanRegistration;
036:        import javax.management.MBeanRegistrationException;
037:        import javax.management.MBeanServer;
038:        import javax.management.MBeanServerDelegate;
039:        import javax.management.MBeanServerNotification;
040:        import javax.management.MalformedObjectNameException;
041:        import javax.management.NotCompliantMBeanException;
042:        import javax.management.ObjectInstance;
043:        import javax.management.ObjectName;
044:        import javax.management.ReflectionException;
045:        import javax.management.RuntimeErrorException;
046:        import javax.management.RuntimeMBeanException;
047:        import javax.management.RuntimeOperationsException;
048:        import javax.management.loading.ClassLoaderRepository;
049:        import javax.management.modelmbean.ModelMBeanInfo;
050:        import javax.management.modelmbean.RequiredModelMBean;
051:
052:        import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
053:        import EDU.oswego.cs.dl.util.concurrent.SynchronizedLong;
054:        import org.jboss.logging.Logger;
055:        import org.jboss.mx.loading.LoaderRepository;
056:        import org.jboss.mx.loading.RepositoryClassLoader;
057:        import org.jboss.mx.metadata.MBeanCapability;
058:        import org.jboss.mx.modelmbean.ModelMBeanConstants;
059:        import org.jboss.mx.modelmbean.RequiredModelMBeanInvoker;
060:        import org.jboss.mx.modelmbean.XMBean;
061:        import org.jboss.mx.modelmbean.XMBeanConstants;
062:        import org.jboss.mx.server.AbstractMBeanInvoker;
063:        import org.jboss.mx.server.MBeanInvoker;
064:        import org.jboss.mx.server.RawDynamicInvoker;
065:        import org.jboss.mx.server.ServerObjectInstance;
066:        import org.jboss.mx.util.ObjectNamePatternHelper;
067:        import org.jboss.mx.util.ObjectNamePatternHelper.PropertyPattern;
068:        import org.jboss.util.NestedRuntimeException;
069:
070:        /**
071:         * The registry for object name - object reference mapping in the
072:         * MBean server.
073:         * <p>
074:         * The implementation of this class affects the invocation speed
075:         * directly, please check any changes for performance.
076:         *
077:         * @todo JMI_DOMAIN isn't very protected
078:         *
079:         * @see org.jboss.mx.server.registry.MBeanRegistry
080:         *
081:         * @author  <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
082:         * @author  <a href="mailto:trevor@protocool.com">Trevor Squires</a>.
083:         * @author  <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
084:         * @author  <a href="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>.
085:         * @author  <a href="mailto:thomas.diesler@jboss.com">Thomas Diesler</a>.
086:         *
087:         * @version $Revision: 57200 $
088:         */
089:        public class BasicMBeanRegistry implements  MBeanRegistry {
090:            // Attributes ----------------------------------------------------
091:
092:            /**
093:             * A map of domain name to another map containing object name canonical
094:             * key properties to registry entries.
095:             * domain -> canonicalKeyProperties -> MBeanEntry
096:             */
097:            private Map domainMap = new ConcurrentReaderHashMap();
098:
099:            /**
100:             * The default domain for this registry
101:             */
102:            private String defaultDomain;
103:
104:            /**
105:             * The MBeanServer for which we are the registry.
106:             */
107:            private MBeanServer server;
108:
109:            /**
110:             * The loader repository for loading classes
111:             */
112:            private LoaderRepository loaderRepository;
113:
114:            /**
115:             * Sequence number for the MBean server registration notifications.
116:             */
117:            protected final SynchronizedLong registrationNotificationSequence = new SynchronizedLong(
118:                    1);
119:
120:            /**
121:             * Sequence number for the MBean server unregistration notifications.
122:             */
123:            protected final SynchronizedLong unregistrationNotificationSequence = new SynchronizedLong(
124:                    1);
125:
126:            /**
127:             * Direct reference to the mandatory MBean server delegate MBean.
128:             */
129:            protected MBeanServerDelegate delegate;
130:
131:            protected Vector fMbInfosToStore;
132:            private ObjectName mbeanInfoService;
133:
134:            // Static --------------------------------------------------------
135:
136:            /**
137:             * The logger
138:             */
139:            protected static Logger log = Logger
140:                    .getLogger(BasicMBeanRegistry.class);
141:
142:            // Constructors --------------------------------------------------
143:
144:            /**
145:             * Constructs a new BasicMBeanRegistry.<p>
146:             */
147:            public BasicMBeanRegistry(MBeanServer server, String defaultDomain,
148:                    ClassLoaderRepository clr) {
149:                // Store the context
150:                this .server = server;
151:                this .defaultDomain = defaultDomain;
152:
153:                try {
154:                    loaderRepository = (LoaderRepository) clr;
155:                    mbeanInfoService = new ObjectName(
156:                            "user:service=MBeanInfoDB");
157:                } catch (Exception e) {
158:                    throw new NestedRuntimeException(
159:                            "Error instantiating registry", e);
160:                }
161:            }
162:
163:            // MBeanRegistry Implementation ----------------------------------
164:
165:            public ObjectInstance registerMBean(Object object, ObjectName name,
166:                    Map valueMap) throws InstanceAlreadyExistsException,
167:                    MBeanRegistrationException, NotCompliantMBeanException {
168:                ObjectName regName = name;
169:                boolean registrationDone = true;
170:                boolean invokedPreRegister = false;
171:                String magicToken = null;
172:                MBeanInvoker invoker = null;
173:
174:                if (object == null)
175:                    throw new RuntimeOperationsException(
176:                            new IllegalArgumentException(
177:                                    "Attempting to register null object"));
178:
179:                // get mbean type, dynamic or standard
180:                MBeanCapability mbcap = MBeanCapability.of(object.getClass());
181:
182:                try {
183:
184:                    if (valueMap != null)
185:                        magicToken = (String) valueMap.get(JMI_DOMAIN);
186:
187:                    // TODO: allow custom factory for diff invoker types
188:                    int mbeanType = mbcap.getMBeanType();
189:                    if (mbeanType == MBeanCapability.STANDARD_MBEAN) {
190:                        invoker = new XMBean(object,
191:                                XMBeanConstants.STANDARD_MBEAN);
192:                    } else if (object instanceof  MBeanInvoker) {
193:                        invoker = (MBeanInvoker) object;
194:                    } else if (mbeanType == MBeanCapability.DYNAMIC_MBEAN) {
195:                        if (object instanceof  RequiredModelMBean)
196:                            invoker = new RequiredModelMBeanInvoker(
197:                                    (DynamicMBean) object);
198:                        else
199:                            invoker = new RawDynamicInvoker(
200:                                    (DynamicMBean) object);
201:                    }
202:
203:                    // Perform the pregistration
204:                    MBeanEntry entry = new MBeanEntry(regName, invoker, object,
205:                            valueMap);
206:                    AbstractMBeanInvoker.setMBeanEntry(entry);
207:                    regName = invokePreRegister(invoker, regName, magicToken);
208:                    invokedPreRegister = true;
209:
210:                    try {
211:                        MBeanInfo info = invoker.getMBeanInfo();
212:                        verifyMBeanInfo(info, name);
213:                        entry.setResourceClassName(info.getClassName());
214:
215:                        // Register the mbean
216:
217:                        // Update the registered name to the final value
218:                        entry.setObjectName(regName);
219:
220:                        add(entry);
221:
222:                        try {
223:                            // Add the classloader to the repository
224:                            if (object instanceof  ClassLoader)
225:                                registerClassLoader((ClassLoader) object);
226:
227:                            try {
228:                                if (delegate != null) {
229:                                    sendRegistrationNotification(regName);
230:                                }
231:
232:                                else if (name.getCanonicalName().equals(
233:                                        MBEAN_SERVER_DELEGATE)) {
234:                                    delegate = (MBeanServerDelegate) object;
235:                                }
236:
237:                                ServerObjectInstance serverObjInst = new ServerObjectInstance(
238:                                        regName, entry.getResourceClassName(),
239:                                        delegate.getMBeanServerId());
240:
241:                                persistIfRequired(invoker.getMBeanInfo(),
242:                                        regName);
243:
244:                                return serverObjInst;
245:
246:                            } catch (Throwable t) {
247:                                // Problem, remove a classloader from the repository
248:                                if (object instanceof  ClassLoader)
249:                                    loaderRepository
250:                                            .removeClassLoader((ClassLoader) object);
251:
252:                                throw t;
253:                            }
254:                        } catch (Throwable t) {
255:                            // Problem, remove the mbean from the registry
256:                            remove(regName);
257:                            throw t;
258:                        }
259:                    }
260:                    // Throw for null MBeanInfo
261:                    catch (NotCompliantMBeanException e) {
262:                        throw e;
263:                    }
264:                    // Thrown by the registry
265:                    catch (InstanceAlreadyExistsException e) {
266:                        throw e;
267:                    } catch (Throwable t) {
268:                        // Something is broken
269:                        log.error("Unexpected Exception:", t);
270:                        throw t;
271:                    }
272:                } catch (NotCompliantMBeanException e) {
273:                    registrationDone = false;
274:                    throw e;
275:                } catch (InstanceAlreadyExistsException e) {
276:                    // It was already registered
277:                    registrationDone = false;
278:                    throw e;
279:                } catch (MBeanRegistrationException e) {
280:                    // The MBean cancelled the registration
281:                    registrationDone = false;
282:                    log.warn(e.toString());
283:                    throw e;
284:                } catch (RuntimeOperationsException e) {
285:                    // There was a problem with one the arguments
286:                    registrationDone = false;
287:                    throw e;
288:                } catch (Exception ex) {
289:                    // any other exception is mapped to NotCompliantMBeanException
290:                    registrationDone = false;
291:                    NotCompliantMBeanException ncex = new NotCompliantMBeanException(
292:                            "Cannot register MBean: " + name);
293:                    ncex.initCause(ex);
294:                    throw ncex;
295:                } catch (Throwable t) {
296:                    // Some other error
297:                    log.error("Cannot register MBean", t);
298:                    registrationDone = false;
299:                    return null;
300:                } finally {
301:                    // Tell the MBean the result of the registration
302:                    if (invoker != null) {
303:                        try {
304:                            invoker.postRegister(new Boolean(registrationDone));
305:                        } catch (Exception e) {
306:                            // Only throw this if preRegister succeeded
307:                            if (invokedPreRegister == true) {
308:                                if (e instanceof  RuntimeException)
309:                                    throw new RuntimeMBeanException(
310:                                            (RuntimeException) e);
311:                                else
312:                                    throw new MBeanRegistrationException(e);
313:                            }
314:                        }
315:                    }
316:                    AbstractMBeanInvoker.setMBeanEntry(null);
317:                }
318:            }
319:
320:            /**
321:             * Verifies the MBeanInfo and throws an exception if something is wrong.
322:             * @param info a MBeanInfo
323:             * @param name a ObjectName
324:             * @throws NotCompliantMBeanException when something is wrong with the MBean info
325:             */
326:            private void verifyMBeanInfo(MBeanInfo info, ObjectName name)
327:                    throws NotCompliantMBeanException {
328:                try {
329:                    if (info == null)
330:                        throw new NotCompliantMBeanException(
331:                                "MBeanInfo cannot be null, for: " + name);
332:
333:                    if (info.getClassName() == null)
334:                        throw new NotCompliantMBeanException(
335:                                "Classname returned from MBeanInfo cannot be null, for: "
336:                                        + name);
337:                } catch (NotCompliantMBeanException ncex) {
338:                    throw ncex;
339:                } catch (Throwable t) {
340:                    NotCompliantMBeanException ncex = new NotCompliantMBeanException(
341:                            "Cannot verify MBeanInfo, for: " + name);
342:                    ncex.initCause(t);
343:                    throw ncex;
344:                }
345:            }
346:
347:            /**
348:             * send a MBeanServerNotification.REGISTRATION_NOTIFICATION notification
349:             * to regName
350:             *
351:             * @param regName
352:             */
353:            protected void sendRegistrationNotification(ObjectName regName) {
354:                long sequence = registrationNotificationSequence.increment();
355:                delegate.sendNotification(new MBeanServerNotification(
356:                        MBeanServerNotification.REGISTRATION_NOTIFICATION,
357:                        delegate, sequence, regName));
358:            }
359:
360:            /**
361:             * subclasses can override to provide their own pre-registration pre- and post- logic for
362:             * <tt>preRegister</tt> and must call preRegister on the MBeanRegistration instance
363:             *
364:             * @param registrationInterface
365:             * @param regName
366:             * @return object name
367:             * @throws Exception
368:             */
369:            protected ObjectName handlePreRegistration(
370:                    MBeanRegistration registrationInterface, ObjectName regName)
371:                    throws Exception {
372:                ObjectName mbean = registrationInterface.preRegister(server,
373:                        regName);
374:                if (regName == null) {
375:                    return mbean;
376:                } else {
377:                    return regName;
378:                }
379:            }
380:
381:            /**
382:             * subclasses can override to provide any custom preDeregister logic
383:             * and must call preDregister on the MBeanRegistration instance
384:             *
385:             * @param registrationInterface
386:             * @throws Exception
387:             */
388:            protected void handlePreDeregister(
389:                    MBeanRegistration registrationInterface) throws Exception {
390:                registrationInterface.preDeregister();
391:            }
392:
393:            /**
394:             * Subclasses can override if they wish to control the classloader
395:             * registration to loader repository.
396:             *
397:             * @param cl classloader
398:             */
399:            protected void registerClassLoader(ClassLoader cl) {
400:                if ((cl instanceof  RepositoryClassLoader) == false) {
401:                    // Only register non-UCLs as UCLs already have a repository
402:                    loaderRepository.addClassLoader(cl);
403:                }
404:            }
405:
406:            public void unregisterMBean(ObjectName name)
407:                    throws InstanceNotFoundException,
408:                    MBeanRegistrationException {
409:                name = qualifyName(name);
410:                if (name.getDomain().equals(JMI_DOMAIN))
411:                    throw new RuntimeOperationsException(
412:                            new IllegalArgumentException(
413:                                    "Not allowed to unregister: "
414:                                            + name.toString()));
415:
416:                MBeanEntry entry = get(name);
417:                Object resource = entry.getResourceInstance();
418:
419:                try {
420:                    // allow subclasses to perform their own pre- and post- pre-deregister logic
421:                    handlePreDeregister(entry.getInvoker());
422:
423:                } catch (Exception e) {
424:                    // don't double wrap MBeanRegistrationException
425:                    if (e instanceof  MBeanRegistrationException)
426:                        throw (MBeanRegistrationException) e;
427:
428:                    throw new MBeanRegistrationException(e, "preDeregister");
429:                }
430:
431:                // Remove any classloader
432:                if (resource instanceof  ClassLoader)
433:                    loaderRepository.removeClassLoader((ClassLoader) resource);
434:
435:                // It is no longer registered
436:                remove(name);
437:
438:                sendUnRegistrationNotification(name);
439:
440:                entry.getInvoker().postDeregister();
441:            }
442:
443:            /**
444:             * send MBeanServerNotification.UNREGISTRATION_NOTIFICATION notification to
445:             * name
446:             *
447:             * @param name
448:             */
449:            protected void sendUnRegistrationNotification(ObjectName name) {
450:                long sequence = unregistrationNotificationSequence.increment();
451:
452:                delegate.sendNotification(new MBeanServerNotification(
453:                        MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
454:                        delegate, sequence, name));
455:            }
456:
457:            public MBeanEntry get(ObjectName name)
458:                    throws InstanceNotFoundException {
459:                if (name == null)
460:                    throw new RuntimeOperationsException(
461:                            new IllegalArgumentException("null object name"));
462:
463:                // Determine the domain and retrieve its entries
464:                String domain = name.getDomain();
465:
466:                if (domain.length() == 0)
467:                    domain = defaultDomain;
468:
469:                String props = name.getCanonicalKeyPropertyListString();
470:                Map mbeanMap = getMBeanMap(domain, false);
471:
472:                // Retrieve the mbean entry
473:                Object o = null;
474:                if (null == mbeanMap || null == (o = mbeanMap.get(props)))
475:                    throw new InstanceNotFoundException(name
476:                            + " is not registered.");
477:
478:                // We are done
479:                return (MBeanEntry) o;
480:            }
481:
482:            public String getDefaultDomain() {
483:                return defaultDomain;
484:            }
485:
486:            public String[] getDomains() {
487:                ArrayList domains = new ArrayList(domainMap.size());
488:                for (Iterator iterator = domainMap.entrySet().iterator(); iterator
489:                        .hasNext();) {
490:                    Map.Entry entry = (Map.Entry) iterator.next();
491:                    String domainName = (String) entry.getKey();
492:                    Map mbeans = (Map) entry.getValue();
493:                    if (mbeans != null && mbeans.isEmpty() == false)
494:                        domains.add(domainName);
495:                }
496:                return (String[]) domains.toArray(new String[domains.size()]);
497:            }
498:
499:            public ObjectInstance getObjectInstance(ObjectName name)
500:                    throws InstanceNotFoundException {
501:                if (!contains(name))
502:                    throw new InstanceNotFoundException(name
503:                            + " not registered.");
504:
505:                return new ServerObjectInstance(qualifyName(name), get(name)
506:                        .getResourceClassName(), delegate.getMBeanServerId());
507:            }
508:
509:            public Object getValue(ObjectName name, String key)
510:                    throws InstanceNotFoundException {
511:                return get(name).getValue(key);
512:            }
513:
514:            public boolean contains(ObjectName name) {
515:                // null safety check
516:                if (name == null)
517:                    return false;
518:
519:                // Determine the domain and retrieve its entries
520:                String domain = name.getDomain();
521:
522:                if (domain.length() == 0)
523:                    domain = defaultDomain;
524:
525:                String props = name.getCanonicalKeyPropertyListString();
526:                Map mbeanMap = getMBeanMap(domain, false);
527:
528:                // Return the result
529:                return (null != mbeanMap && mbeanMap.containsKey(props));
530:            }
531:
532:            public int getSize() {
533:                int retval = 0;
534:                for (Iterator iterator = domainMap.values().iterator(); iterator
535:                        .hasNext();) {
536:                    retval += ((Map) iterator.next()).size();
537:                }
538:                return retval;
539:            }
540:
541:            public List findEntries(ObjectName pattern) {
542:                ArrayList retval = new ArrayList();
543:
544:                // There are a couple of shortcuts we can employ to make this a
545:                // bit faster - they're commented.
546:
547:                // First, if pattern == null or pattern.getCanonicalName() == "*:*" we want the
548:                // set of all MBeans.
549:                if (pattern == null || pattern.getCanonicalName().equals("*:*")) {
550:                    for (Iterator domainIter = domainMap.values().iterator(); domainIter
551:                            .hasNext();)
552:                        retval.addAll(((Map) domainIter.next()).values());
553:                }
554:                // Next, if !pattern.isPattern() then we are doing a simple get (maybe defaultDomain).
555:                else if (!pattern.isPattern()) {
556:                    // simple get
557:                    try {
558:                        retval.add(get(pattern));
559:                    } catch (InstanceNotFoundException e) {
560:                        // we don't care
561:                    }
562:                }
563:                // Now we have to do a brute force, oh well.
564:                else {
565:                    String patternDomain = pattern.getDomain();
566:                    if (patternDomain.length() == 0)
567:                        patternDomain = defaultDomain;
568:                    PropertyPattern propertyPattern = new PropertyPattern(
569:                            pattern);
570:
571:                    // Here we go, step through every domain and see if our pattern matches before optionally checking
572:                    // each ObjectName's properties for a match.
573:                    for (Iterator domainIter = domainMap.entrySet().iterator(); domainIter
574:                            .hasNext();) {
575:                        Map.Entry mapEntry = (Map.Entry) domainIter.next();
576:                        Map value = (Map) mapEntry.getValue();
577:                        if (value != null && value.isEmpty() == false) {
578:                            if (ObjectNamePatternHelper.patternMatch(
579:                                    (String) mapEntry.getKey(), patternDomain)) {
580:                                for (Iterator mbeanIter = value.values()
581:                                        .iterator(); mbeanIter.hasNext();) {
582:                                    MBeanEntry entry = (MBeanEntry) mbeanIter
583:                                            .next();
584:                                    if (propertyPattern.patternMatch(entry
585:                                            .getObjectName()))
586:                                        retval.add(entry);
587:                                }
588:                            }
589:                        }
590:                    }
591:                }
592:
593:                return retval;
594:            }
595:
596:            /**
597:             * Cleans up the registry before the MBean server is released.
598:             */
599:            public void releaseRegistry()
600:            // This is based on patch by Rod Burgett (Bug report: 763378)
601:            // Modified. Server is calling the registry.
602:            {
603:                server = null;
604:                delegate = null;
605:
606:                //  clear each value element from the domainMap
607:                for (Iterator iterator = domainMap.keySet().iterator(); iterator
608:                        .hasNext();) {
609:                    Map nextMap = (Map) domainMap.get(iterator.next());
610:
611:                    if (nextMap.size() > 0) {
612:                        nextMap.clear();
613:                    }
614:                }
615:
616:                domainMap.clear();
617:                domainMap = null;
618:            }
619:
620:            // Protected -----------------------------------------------------
621:
622:            protected ObjectName invokePreRegister(MBeanInvoker invoker,
623:                    ObjectName regName, String magicToken)
624:                    throws MBeanRegistrationException,
625:                    NotCompliantMBeanException {
626:
627:                // if we were given a non-null object name for registration, qualify it
628:                // and expand default domain
629:                if (regName != null)
630:                    regName = qualifyName(regName);
631:
632:                // store the name returned by preRegister() here
633:                ObjectName mbeanName = null;
634:
635:                try {
636:                    // invoke preregister on the invoker, it will delegate to the resource
637:                    // if needed
638:                    mbeanName = invoker.preRegister(server, regName);
639:                }
640:                // if during pre registration, the mbean turns out to be not compliant
641:                catch (NotCompliantMBeanException ncex) {
642:                    throw ncex;
643:
644:                }
645:                // catch all exceptions cause by preRegister, these will abort registration
646:                catch (Exception e) {
647:                    if (e instanceof  MBeanRegistrationException) {
648:                        throw (MBeanRegistrationException) e;
649:                    }
650:
651:                    throw new MBeanRegistrationException(e,
652:                            "preRegister() failed: "
653:                                    + "[ObjectName='"
654:                                    + regName
655:                                    + "', Class="
656:                                    + invoker.getResource().getClass()
657:                                            .getName() + " ("
658:                                    + invoker.getResource() + ")]");
659:                } catch (Throwable t) {
660:                    log.warn("preRegister() failed for " + regName + ": ", t);
661:
662:                    if (t instanceof  Error)
663:                        throw new RuntimeErrorException((Error) t);
664:                    else
665:                        throw new RuntimeException(t.toString());
666:                }
667:
668:                // if registered with null name, use the default name returned by
669:                // the preregister implementation
670:                if (regName == null)
671:                    regName = mbeanName;
672:
673:                return validateAndQualifyName(regName, magicToken);
674:            }
675:
676:            /**
677:             * Adds an MBean entry<p>
678:             *
679:             * WARNING: The object name should be fully qualified.
680:             *
681:             * @param entry the MBean entry to add
682:             * @exception InstanceAlreadyExistsException when the MBean's object name
683:             *            is already registered
684:             */
685:            protected synchronized void add(MBeanEntry entry)
686:                    throws InstanceAlreadyExistsException {
687:                // Determine the MBean's name and properties
688:                ObjectName name = entry.getObjectName();
689:                String domain = name.getDomain();
690:                String props = name.getCanonicalKeyPropertyListString();
691:
692:                // Create a properties -> entry map if we don't have one
693:                Map mbeanMap = getMBeanMap(domain, true);
694:
695:                // Make sure we aren't already registered
696:                if (mbeanMap.get(props) != null)
697:                    throw new InstanceAlreadyExistsException(name
698:                            + " already registered.");
699:
700:                // Ok, we are registered
701:                mbeanMap.put(props, entry);
702:            }
703:
704:            /**
705:             * Removes an MBean entry
706:             *
707:             * WARNING: The object name should be fully qualified.
708:             *
709:             * @param name the object name of the entry to remove
710:             * @exception InstanceNotFoundException when the object name is not
711:             *            registered
712:             */
713:            protected synchronized void remove(ObjectName name)
714:                    throws InstanceNotFoundException {
715:                // Determine the MBean's name and properties
716:                String domain = name.getDomain();
717:                String props = name.getCanonicalKeyPropertyListString();
718:                Map mbeanMap = getMBeanMap(domain, false);
719:
720:                // Remove the entry, raise an exception when it didn't exist
721:                if (null == mbeanMap || null == mbeanMap.remove(props))
722:                    throw new InstanceNotFoundException(name
723:                            + " not registered.");
724:            }
725:
726:            /**
727:             * Validates and qualifies an MBean<p>
728:             *
729:             * Validates the name is not a pattern.<p>
730:             *
731:             * Adds the default domain if no domain is specified.<p>
732:             *
733:             * Checks the name is not in the reserved domain JMImplementation when
734:             * the magicToken is not {@link org.jboss.mx.server.ServerConstants#JMI_DOMAIN JMI_DOMAIN}
735:             *
736:             * @param name the name to validate
737:             * @param magicToken used to get access to the reserved domain
738:             * @return the original name or the name prepended with the default domain
739:             *         if no domain is specified.
740:             * @exception RuntimeOperationsException containing an
741:             *            IllegalArgumentException for a problem with the name
742:             */
743:            protected ObjectName validateAndQualifyName(ObjectName name,
744:                    String magicToken) {
745:                // Check for qualification
746:                ObjectName result = qualifyName(name);
747:
748:                // Make sure the name is not a pattern
749:                if (result.isPattern())
750:                    throw new RuntimeOperationsException(
751:                            new IllegalArgumentException(
752:                                    "Object name is a pattern:" + name));
753:
754:                // Check for reserved domain
755:                if (magicToken != JMI_DOMAIN
756:                        && result.getDomain().equals(JMI_DOMAIN))
757:                    throw new RuntimeOperationsException(
758:                            new IllegalArgumentException("Domain " + JMI_DOMAIN
759:                                    + " is reserved"));
760:
761:                // I can't think of anymore tests, we're done
762:                return result;
763:            }
764:
765:            /**
766:             * Qualify an object name with the default domain<p>
767:             *
768:             * Adds the default domain if no domain is specified.
769:             *
770:             * @param name the name to qualify
771:             * @return the original name or the name prepended with the default domain
772:             *         if no domain is specified.
773:             * @exception RuntimeOperationsException containing an
774:             *            IllegalArgumentException when there is a problem
775:             */
776:            protected ObjectName qualifyName(ObjectName name) {
777:                if (name == null)
778:                    throw new RuntimeOperationsException(
779:                            new IllegalArgumentException("Null object name"));
780:                try {
781:                    if (name.getDomain().length() == 0)
782:                        return new ObjectName(defaultDomain + ":"
783:                                + name.getCanonicalKeyPropertyListString());
784:                    else
785:                        return name;
786:                } catch (MalformedObjectNameException e) {
787:                    throw new RuntimeOperationsException(
788:                            new IllegalArgumentException(e.toString()));
789:                }
790:            }
791:
792:            /**
793:             * Adds the given MBean Info object to the persistence queue if it explicity denotes
794:             * (via metadata) that it should be stored.
795:             * @todo -- add notification of registration of MBeanInfoDb.
796:             *   It is possible that some MBeans whose MBean Info should be stored are
797:             *   registered before the MBean Info Storage delegate is available.  These
798:             *   MBeans are remembered by the registry and should be added to the storage delegate
799:             *   as soon as it is available.  In the current mechanism, they are added only if another
800:             *   MBean requesting MBean info persistence is registered after the delegate is registered.
801:             *   Someone more familiar with the server could make this more robust by adding
802:             *   a notification mechanism such that the queue is flushed as soon as the
803:             *   delegate is available.  - Matt Munz
804:             * @todo does this code need to be here? can't a notification listener be
805:             *       registered with the MBeanServerDelegate that stores a backlog
806:             *       until the service becomes available?
807:             * @todo the mbInfoStores is a memory leak if the service is never registered
808:             * @todo mbInfoStores is not synchronized correctly
809:             *       Thread1 adds
810:             *       Thread1 clones and invokes
811:             *       Thread2 adds
812:             *       Thread1 clears
813:             *       Thread2's add is lost
814:             * @todo Don't use Vector, performs too fine grained synchronization,
815:             *       probably not important in this case.
816:             */
817:            protected void persistIfRequired(MBeanInfo info, ObjectName name)
818:                    throws MalformedObjectNameException,
819:                    InstanceNotFoundException, MBeanException,
820:                    ReflectionException {
821:                if (!(info instanceof  ModelMBeanInfo)) {
822:                    return;
823:                }
824:                ModelMBeanInfo mmbInfo = (ModelMBeanInfo) info;
825:                Descriptor descriptor;
826:                try {
827:                    descriptor = mmbInfo.getMBeanDescriptor();
828:                } catch (MBeanException cause) {
829:                    log.error("Error trying to get descriptors.", cause);
830:                    return;
831:                }
832:                if (descriptor == null)
833:                    return;
834:                String persistInfo = (String) descriptor
835:                        .getFieldValue(ModelMBeanConstants.PERSIST_INFO);
836:                if (persistInfo == null)
837:                    return; // use default -- no persistence
838:                log.debug("persistInfo: " + persistInfo);
839:                Boolean shouldPersist = new Boolean(persistInfo);
840:                if (!shouldPersist.booleanValue()) {
841:                    return;
842:                }
843:                mbInfosToStore().add(name);
844:                // see if MBeanDb is available
845:                if (contains(mbeanInfoService)) {
846:                    // flush queue to the MBeanDb
847:                    log.debug("flushing queue");
848:                    server.invoke(mbeanInfoService, "add",
849:                            new Object[] { mbInfosToStore().clone() },
850:                            new String[] { mbInfosToStore().getClass()
851:                                    .getName() });
852:                    log.debug("clearing queue");
853:                    mbInfosToStore().clear();
854:                } else {
855:                    log
856:                            .debug("service is not registered.  items remain in queue");
857:                }
858:            }
859:
860:            /**
861:             * ObjectName objects bound to MBean Info objects that are waiting to be stored in the
862:             * persistence store.
863:             */
864:            protected Vector mbInfosToStore() {
865:                if (fMbInfosToStore == null) {
866:                    fMbInfosToStore = new Vector(10);
867:                }
868:                return fMbInfosToStore;
869:            }
870:
871:            /**
872:             *
873:             * getMBeanMap should be called from a synchronized method if createIfMissing=true
874:             *
875:             * @param domain a <code>String</code> value
876:             * @param createIfMissing a <code>boolean</code> value
877:             * @return a <code>Map</code> value
878:             */
879:            private Map getMBeanMap(String domain, boolean createIfMissing) {
880:                Map mbeanMap = (Map) domainMap.get(domain);
881:                if (mbeanMap == null && createIfMissing) {
882:                    mbeanMap = new ConcurrentReaderHashMap();
883:                    domainMap.put(domain, mbeanMap);
884:                }
885:                return mbeanMap;
886:            }
887:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.