001: /*****************************************************************************
002: * Copyright (C) NanoContainer Organization. All rights reserved. *
003: * ------------------------------------------------------------------------- *
004: * The software in this package is published under the terms of the BSD *
005: * style license a copy of which has been included with this distribution in *
006: * the LICENSE.txt file. *
007: * *
008: * Original code by Michael Ward *
009: *****************************************************************************/package org.picocontainer.gems.jmx;
010:
011: import java.util.HashMap;
012: import java.util.Map;
013:
014: import javax.management.DynamicMBean;
015: import javax.management.MBeanInfo;
016: import javax.management.ObjectName;
017:
018: import org.picocontainer.ComponentAdapter;
019: import org.picocontainer.PicoContainer;
020:
021: /**
022: * A DynamicMBeanProvider, that creates DynamicMBeans for registered Pico components on the fly.
023: * @author Michael Ward
024: * @author Jörg Schaible
025: */
026: public class RegisteredMBeanConstructingProvider implements
027: DynamicMBeanProvider {
028:
029: private final DynamicMBeanFactory factory;
030: private final Map registry;
031:
032: /**
033: * Construct a RegisteredMBeanConstructingProvider with a {@link StandardMBeanFactory} as default.
034: */
035: public RegisteredMBeanConstructingProvider() {
036: this (new StandardMBeanFactory());
037: }
038:
039: /**
040: * Construct a RegisteredMBeanConstructingProvider, that uses a specific {@link DynamicMBeanFactory}.
041: * @param factory
042: */
043: public RegisteredMBeanConstructingProvider(
044: final DynamicMBeanFactory factory) {
045: this .factory = factory;
046: this .registry = new HashMap();
047: }
048:
049: /**
050: * Provide a DynamicMBean for the given Pico component. The implementation will lookup the component's key in the
051: * internal registry. Only components that were registered with additional information will be considered and a
052: * {@link DynamicMBean} will be created for them using the {@link DynamicMBeanFactory}. If the component key is of
053: * type class, it is used as management interface.
054: * @see org.picocontainer.gems.jmx.DynamicMBeanProvider#provide(PicoContainer, ComponentAdapter)
055: */
056: public JMXRegistrationInfo provide(
057: final PicoContainer picoContainer,
058: final ComponentAdapter componentAdapter) {
059: final Object key = componentAdapter.getComponentKey();
060: final MBeanInfoWrapper wrapper = (MBeanInfoWrapper) registry
061: .get(key);
062: if (wrapper != null) {
063: final Object instance = componentAdapter
064: .getComponentInstance(picoContainer);
065: final Class management = wrapper.getManagementInterface() != null ? wrapper
066: .getManagementInterface()
067: : key instanceof Class ? (Class) key : instance
068: .getClass();
069: final DynamicMBean mBean = factory.create(instance,
070: management, wrapper.getMBeanInfo());
071: return new JMXRegistrationInfo(wrapper.getObjectName(),
072: mBean);
073: }
074: return null;
075: }
076:
077: /**
078: * Register a specific Pico component by key with an MBeanInfo and an ObjectName.
079: * @param componentKey The key of the Pico component.
080: * @param objectName The {@link ObjectName} of the MBean.
081: * @param management The management interface.
082: * @param mBeanInfo The {@link MBeanInfo} of the MBean.
083: */
084: public void register(final Object componentKey,
085: final ObjectName objectName, final Class management,
086: final MBeanInfo mBeanInfo) {
087: registry.put(componentKey, new MBeanInfoWrapper(mBeanInfo,
088: objectName, management));
089: }
090:
091: /**
092: * Register a specific Pico component by key with an MBeanInfo and an ObjectName.
093: * @param componentKey The key of the Pico component.
094: * @param objectName The {@link ObjectName} of the MBean.
095: * @param mBeanInfo The {@link MBeanInfo} of the MBean.
096: */
097: public void register(final Object componentKey,
098: final ObjectName objectName, final MBeanInfo mBeanInfo) {
099: register(componentKey, objectName, null, mBeanInfo);
100: }
101:
102: /**
103: * Register a specific Pico component with an MBeanInfo and an ObjectName. The implementation class of the
104: * {@link DynamicMBean} must be the key of the Pico component.
105: * @param objectName The {@link ObjectName} of the MBean.
106: * @param mBeanInfo The {@link MBeanInfo} of the MBean.
107: */
108: public void register(final ObjectName objectName,
109: final MBeanInfo mBeanInfo) {
110: try {
111: register(getClass().getClassLoader().loadClass(
112: mBeanInfo.getClassName()), objectName, mBeanInfo);
113: } catch (final ClassNotFoundException e) {
114: throw new JMXRegistrationException("Cannot access class "
115: + mBeanInfo.getClassName() + " of MBean", e);
116: }
117: }
118:
119: /**
120: * Register a specific Pico component by key with an ObjectName.
121: * @param componentKey The key of the Pico component.
122: * @param objectName The {@link ObjectName} of the MBean.
123: */
124: public void register(final Object componentKey,
125: final ObjectName objectName) {
126: registry.put(componentKey, new MBeanInfoWrapper(null,
127: objectName, null));
128: }
129:
130: /**
131: * Simple wrapper to tie a MBeanInfo to an ObjectName
132: */
133: private static class MBeanInfoWrapper {
134: private final MBeanInfo mBeanInfo;
135: private final ObjectName objectName;
136: private final Class managementInterface;
137:
138: MBeanInfoWrapper(final MBeanInfo mBeanInfo,
139: final ObjectName objectName, final Class management) {
140: this .mBeanInfo = mBeanInfo;
141: this .objectName = objectName;
142: this .managementInterface = management;
143: }
144:
145: MBeanInfo getMBeanInfo() {
146: return mBeanInfo;
147: }
148:
149: ObjectName getObjectName() {
150: return objectName;
151: }
152:
153: Class getManagementInterface() {
154: return managementInterface;
155: }
156: }
157:
158: }
|