001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)RuntimeConfiguration.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.management.config;
030:
031: import com.sun.jbi.EnvironmentContext;
032: import com.sun.jbi.StringTranslator;
033: import com.sun.jbi.platform.PlatformContext;
034: import com.sun.jbi.management.ConfigurationCategory;
035: import com.sun.jbi.management.LocalStringKeys;
036: import com.sun.jbi.management.message.MessageBuilder;
037: import com.sun.jbi.management.system.ManagementContext;
038: import com.sun.jbi.management.system.ManagementException;
039: import com.sun.jbi.management.registry.GenericQuery;
040: import com.sun.jbi.management.registry.Registry;
041: import com.sun.jbi.management.registry.Updater;
042: import com.sun.jbi.management.registry.xml.RegistryDocument;
043: import com.sun.jbi.management.util.StringHelper;
044:
045: import java.util.Map;
046: import java.util.ArrayList;
047: import java.util.List;
048: import java.util.HashMap;
049: import java.util.concurrent.ConcurrentHashMap;
050: import java.util.logging.Logger;
051: import javax.management.Attribute;
052: import javax.management.AttributeList;
053: import javax.management.AttributeNotFoundException;
054: import javax.management.InvalidAttributeValueException;
055: import javax.management.Descriptor;
056: import javax.management.MBeanException;
057: import javax.management.MBeanInfo;
058: import javax.management.ObjectName;
059: import javax.management.ReflectionException;
060:
061: // Notification classes
062: import javax.management.NotificationListener;
063: import javax.management.NotificationFilter;
064: import javax.management.AttributeChangeNotification;
065: import javax.management.MBeanNotificationInfo;
066:
067: import javax.management.MBeanAttributeInfo;
068: import javax.management.MBeanServerConnection;
069: import javax.management.modelmbean.ModelMBeanAttributeInfo;
070: import javax.management.modelmbean.ModelMBeanInfo;
071: import javax.management.modelmbean.ModelMBeanInfoSupport;
072: import javax.management.modelmbean.ModelMBeanConstructorInfo;
073: import javax.management.modelmbean.ModelMBeanNotificationInfo;
074: import javax.management.modelmbean.ModelMBeanOperationInfo;
075:
076: /**
077: * This is the basic RuntimeConfiguration MBean. It is a dynamic model MBean.
078: *
079: * @author Sun Microsystems, Inc.
080: */
081: public class RuntimeConfiguration extends
082: javax.management.modelmbean.RequiredModelMBean implements
083: javax.management.NotificationEmitter {
084:
085: /** Message Builder */
086: protected static MessageBuilder sMsgBuilder;
087:
088: /** Context information */
089: private PlatformContext mPlatformCtx;
090: private static EnvironmentContext sEnvCtx;
091: private ManagementContext mMgtCtx;
092: private static StringTranslator sTranslator;
093: private static Logger sLog;
094: protected ConfigurationCategory mCategory;
095: protected String mTarget;
096: private static boolean isGlobalAttribSetInited;
097:
098: // -- Listeners interested in notifications from this MBean
099: protected List<NotificationListenerInfo> mListeners;
100: protected static MBeanNotificationInfo[] sNotificationInfo = null;
101:
102: /** Primitive types to their class object mapping */
103: protected static HashMap<String, String> sTypeMap;
104:
105: private static String MASKED_ATTRIB_VALUE = "*******";
106:
107: /** notification sequence number */
108: private long mSeqNumber = 0;
109:
110: static {
111: initPrimitiveTypeMap();
112: initNotificationInfos();
113: }
114:
115: /** Creates a new RuntimeConfiguration MBean.
116: * @param mbeanInfo metadata returned by the 'real' MBean in the
117: * target instance.
118: * @param mbeanName name of this MBean registered in the DAS.
119: */
120: public RuntimeConfiguration(ModelMBeanInfo mbeanInfo,
121: ConfigurationCategory category, String target)
122: throws Exception {
123:
124: super (mbeanInfo);
125: sMsgBuilder = new MessageBuilder(getTranslator());
126: mCategory = category;
127: mTarget = (target == null ? getPlatformContext()
128: .getTargetName() : target);
129: }
130:
131: /*---------------------------------------------------------------------------------*\
132: * Dynamic MBean Attribute getters/setters *
133: \*---------------------------------------------------------------------------------*/
134:
135: /**
136: * Obtain the value of a specific attribute of the Dynamic MBean.
137: *
138: * @param attribute The name of the attribute to be retrieved
139: * @return The value of the attribute retrieved.
140: * @exception AttributeNotFoundException
141: * @exception MBeanException Wraps a <CODE>java.lang.Exception</CODE>
142: * thrown by the MBean's getter.
143: * @exception ReflectionException Wraps a <CODE>java.lang.Exception</CODE>
144: * thrown while trying to invoke the getter.
145: * @see #setAttribute
146: */
147: public Object getAttribute(String attribute)
148: throws AttributeNotFoundException, MBeanException,
149: ReflectionException {
150: Object regValue = null;
151: /**
152: * If the framework is ready ( i.e. JAXB initialized ) get the attribute from
153: * the JAXB model
154: *
155: * If framework not ready then get the attribute from the registry using DOM/XPath
156: *
157: * If the attribute is not defined in the registry ( for target or global domain config )
158: * the return the default value of the attribute, the domain setting has not been
159: * updated and is identical to the default
160: */
161: try {
162: String strValue = null;
163: if (getEnvironmentContext().isFrameworkReady(false)) {
164: // Initialization complete can use registry
165: strValue = getRegistry().getGenericQuery()
166: .getAttribute(mTarget, mCategory, attribute);
167: } else {
168: // Get the attribute from the registry using DOM
169: RegistryDocument regDoc = new RegistryDocument(
170: getEnvironmentContext().getReadOnlyRegistry());
171:
172: strValue = regDoc.getConfigurationAttribute(mTarget,
173: mCategory, attribute);
174: }
175:
176: ModelMBeanAttributeInfo attribInfo = getAttributeInfo(attribute);
177:
178: if (isPassword(attribute)) {
179: // No need to decrypt and return clear text. Mask the value
180: regValue = MASKED_ATTRIB_VALUE;
181: } else if (attribInfo != null && strValue != null) {
182: regValue = (Object) StringHelper.convertStringToType(
183: attribInfo.getType(), strValue);
184: }
185:
186: if (regValue == null) {
187: // Get the factory default value
188: if (attribInfo != null) {
189: Descriptor descr = attribInfo.getDescriptor();
190: regValue = descr.getFieldValue("default");
191: }
192: }
193:
194: } catch (Exception ex) {
195: javax.jbi.JBIException jbiEx;
196: try {
197: jbiEx = new javax.jbi.JBIException(sMsgBuilder
198: .buildExceptionMessage("getAttribute", ex));
199: } catch (ManagementException mex) {
200: jbiEx = new javax.jbi.JBIException(ex.getMessage());
201: }
202: throw new MBeanException(jbiEx);
203: }
204:
205: if (regValue == null) {
206: throw new AttributeNotFoundException(attribute);
207: } else {
208: return regValue;
209: }
210: }
211:
212: /**
213: * Sets the values of several attributes of the Dynamic MBean.
214: *
215: * @param attributes A list of attributes: The identification of the
216: * attributes to be set and the values they are to be set to.
217: * @return The list of attributes that were set, with their new values.
218: * @see #getAttributes
219: */
220: public AttributeList setAttributes(AttributeList attributes) {
221: AttributeList updatedAttributes = new AttributeList();
222:
223: for (int i = 0; i < attributes.size(); i++) {
224: Attribute attr = (Attribute) attributes.get(i);
225: try {
226: setAttribute(attr);
227: updatedAttributes.add(attr);
228: } catch (Exception ex) {
229: // Log exception that attribute name could not be set
230: String errMsg = getTranslator().getString(
231: LocalStringKeys.CS_SET_ATTRIBUTE_FAILED,
232: attr.getName(), attr.getValue(),
233: ex.getMessage());
234: getLogger().fine(errMsg);
235: continue;
236: }
237: }
238: return updatedAttributes;
239: }
240:
241: /**
242: * Get the values of several attributes of the Dynamic MBean.
243: *
244: * @param attributeNames A list of the attributes to be retrieved.
245: * @return The list of attributes retrieved.
246: * @see #setAttributes
247: */
248: public AttributeList getAttributes(String[] attributeNames) {
249: AttributeList list = new AttributeList();
250:
251: for (String attrName : attributeNames) {
252: try {
253: Object attrValue = getAttribute(attrName);
254: list.add(new Attribute(attrName, attrValue));
255: } catch (Exception ex) {
256: // Log the exception that attrName could not be retrieved
257: String errMsg = getTranslator().getString(
258: LocalStringKeys.CS_GET_ATTRIBUTE_FAILED,
259: attrName, ex.getMessage());
260: getLogger().fine(errMsg);
261: continue;
262: }
263: }
264:
265: return list;
266: }
267:
268: /**
269: * Allows an action to be invoked on the Dynamic MBean.
270: *
271: * @param actionName The name of the action to be invoked.
272: * @param params An array containing the parameters to be set when the
273: * action is invoked.
274: * @param signature An array containing the signature of the action. The
275: * class objects will be loaded through the same class loader as the
276: * one used for loading the MBean on which the action is invoked.
277: * @return The object returned by the action, which represents the result of
278: * invoking the action on the MBean specified.
279: * @exception MBeanException Wraps a <CODE>java.lang.Exception</CODE> thrown
280: * by the MBean's invoked method.
281: * @exception ReflectionException Wraps a <CODE>java.lang.Exception</CODE>
282: * thrown while trying to invoke the method
283: */
284: public Object invoke(String actionName, Object[] params,
285: String[] signature) throws MBeanException,
286: ReflectionException {
287: if (actionName.equals("persist")) {
288: try {
289: this .persist();
290: } catch (Exception ex) {
291: javax.jbi.JBIException jbiEx;
292: try {
293: jbiEx = new javax.jbi.JBIException(sMsgBuilder
294: .buildExceptionMessage("invoke", ex));
295: } catch (ManagementException mex) {
296: jbiEx = new javax.jbi.JBIException(ex.getMessage());
297: }
298:
299: throw new MBeanException(jbiEx);
300: }
301: return new Object();
302: } else if (actionName.equals("deleteOverride")) {
303: try {
304: if (params.length < 1 || signature.length < 1) {
305: throw new Exception("Insufficient parameters");
306: }
307:
308: if (!(params[0] instanceof java.lang.String)) {
309: throw new Exception("Incorrect type "
310: + params[0].getClass().getName());
311: }
312:
313: if (params.length > 0) {
314: this .deleteOverride((String) params[0]);
315: }
316: } catch (Exception ex) {
317: javax.jbi.JBIException jbiEx;
318: try {
319: jbiEx = new javax.jbi.JBIException(
320: sMsgBuilder.buildExceptionMessage(
321: "deleteOverride", ex));
322: } catch (ManagementException mex) {
323: jbiEx = new javax.jbi.JBIException(ex.getMessage());
324: }
325: throw new MBeanException(jbiEx);
326: }
327: // ??
328: return new Object();
329: } else {
330: throw new UnsupportedOperationException("invoke");
331: }
332: }
333:
334: /**
335: *
336: */
337: public static ModelMBeanInfo createMBeanInfo(
338: ModelMBeanAttributeInfo[] attributeInfos) throws Exception {
339: // -- Introspect each and every attribute info
340: // (a) Check if all required fields are present in descriptor
341: checkMBeanAttributeInfos(attributeInfos);
342: ModelMBeanInfo mbeanInfo = null;
343:
344: ModelMBeanConstructorInfo[] constructorInfos = new ModelMBeanConstructorInfo[0];
345: ModelMBeanOperationInfo[] operationInfos = new ModelMBeanOperationInfo[0];
346:
347: MBeanNotificationInfo[] mbeanNotInfos = initNotificationInfos();
348: ModelMBeanNotificationInfo[] notificationInfos = new ModelMBeanNotificationInfo[mbeanNotInfos.length];
349:
350: int i = 0;
351: for (MBeanNotificationInfo mbeanNotInfo : mbeanNotInfos) {
352: notificationInfos[i] = new ModelMBeanNotificationInfo(
353: mbeanNotInfo.getNotifTypes(), mbeanNotInfo
354: .getName(), mbeanNotInfo.getDescription());
355: i++;
356: }
357:
358: mbeanInfo = new ModelMBeanInfoSupport(
359: "com.sun.jbi.management.facade.RuntimeConfigurationMBean.class",
360: "Runtime Configuration MBean", attributeInfos,
361: constructorInfos, operationInfos, notificationInfos);
362: return mbeanInfo;
363: }
364:
365: /*---------------------------------------------------------------------------------*\
366: * Protected operations *
367: \*---------------------------------------------------------------------------------*/
368:
369: /**
370: * This operations checks :
371: *
372: * (a) If an attribute with the same identification exists in the current configuration
373: * (b) If the type of the value passed matches the expected value.
374: *
375: * @param attribute - the attribute to be validated
376: * @exception AttributeNotFoundException if attribute with the same identification
377: * is not present in the configuration set.
378: * @exception InvalidAttributeValueException if the type of the attribute is different
379: * from what is expected.
380: */
381: protected void checkIsValidAttribute(Attribute attribute)
382: throws javax.management.AttributeNotFoundException,
383: javax.management.InvalidAttributeValueException {
384: String attrName = attribute.getName();
385: Object attrValue = attribute.getValue();
386:
387: String type = getMatchingAttribute(attrName);
388: if (type != null) {
389: if (attrValue != null) {
390: if (!(type.equals(attrValue.getClass().getName()))) {
391: String errMsg = getTranslator().getString(
392: LocalStringKeys.CS_INVALID_ATTRIBUTE_VALUE,
393: attrName, type,
394: attrValue.getClass().getName());
395: throw new InvalidAttributeValueException(errMsg);
396: }
397: }
398: } else {
399: throw new AttributeNotFoundException(attrName);
400: }
401:
402: }
403:
404: /**
405: * @name - the identification of the attribute to look for
406: * @return the type of the attribute from the MBeanAttributeInfo's for this MBean
407: * if one with the same name exists. If a match is not found a null value is
408: * returned.
409: */
410: protected String getMatchingAttribute(String name) {
411: MBeanInfo mbeanInfo = this .getMBeanInfo();
412: MBeanAttributeInfo[] attribInfos = mbeanInfo.getAttributes();
413: String type = null;
414:
415: for (MBeanAttributeInfo attribInfo : attribInfos) {
416: if (attribInfo.getName().equals(name)) {
417: type = attribInfo.getType();
418:
419: if (sTypeMap.containsKey(type)) {
420: type = (String) sTypeMap.get(type);
421: }
422: }
423: }
424: return type;
425: }
426:
427: /**
428: * @return the management string translator
429: */
430: protected static StringTranslator getTranslator() {
431: if (sTranslator == null) {
432: com.sun.jbi.EnvironmentContext envCtx = com.sun.jbi.util.EnvironmentAccess
433: .getContext();
434: sTranslator = envCtx
435: .getStringTranslator("com.sun.jbi.management");
436: }
437: return sTranslator;
438: }
439:
440: /**
441: * @return the management logger.
442: */
443: protected static Logger getLogger() {
444: if (sLog == null) {
445: sLog = Logger.getLogger("com.sun.jbi.management");
446: }
447: return sLog;
448: }
449:
450: /**
451: * @return the management context
452: */
453: protected ManagementContext getManagementContext() {
454: if (mMgtCtx == null) {
455: mMgtCtx = new ManagementContext(getEnvironmentContext());
456: }
457: return mMgtCtx;
458: }
459:
460: /**
461: * @return the platform context
462: */
463: protected PlatformContext getPlatformContext() {
464: if (mPlatformCtx == null) {
465: mPlatformCtx = getEnvironmentContext().getPlatformContext();
466: }
467: return mPlatformCtx;
468: }
469:
470: /**
471: * @return the EnvironmentContext
472: */
473: protected static EnvironmentContext getEnvironmentContext() {
474: if (sEnvCtx == null) {
475: sEnvCtx = com.sun.jbi.util.EnvironmentAccess.getContext();
476: }
477: return sEnvCtx;
478: }
479:
480: /**
481: * Persist the factory defaults to the registry for the global configuration.
482: * This operation is invoked before any updates to the global/domain configuration,
483: * so global configuration is equivalent to the factory defaults.
484: *
485: * This operation is invoked only on the domain facade MBean and the Global Configuration
486: * MBean
487: */
488: protected void persist() throws Exception {
489: com.sun.jbi.management.registry.Registry registry = getRegistry();
490: if (registry != null) {
491: Updater updater = registry.getUpdater();
492:
493: ModelMBeanAttributeInfo[] attribInfos = (ModelMBeanAttributeInfo[]) this
494: .getMBeanInfo().getAttributes();
495:
496: for (ModelMBeanAttributeInfo attribInfo : attribInfos) {
497: javax.management.Descriptor descr = attribInfo
498: .getDescriptor();
499:
500: String value = descr.getFieldValue("default")
501: .toString();
502: String persistAttrValue = value;
503: if (isPassword(attribInfo.getName())) {
504: com.sun.jbi.security.KeyStoreUtil ksUtil = getPlatformContext()
505: .getKeyStoreUtil();
506: persistAttrValue = ksUtil.encrypt(value);
507: }
508: updater.setAttribute("domain", mCategory, attribInfo
509: .getName(), persistAttrValue);
510: }
511: }
512: }
513:
514: /**
515: * This operation is called when a configuration attribute is to use the
516: * global configuration, the overriden attribute needs to be deleted from the
517: * target configiration
518: *
519: * @param attrName - attribute to be deleted
520: */
521: protected void deleteOverride(String attrName) throws Exception {
522:
523: }
524:
525: /**
526: * @param attribName - identification of the attribute
527: * @return the ModelMBeanAttributeInfo for the specified attribute
528: */
529: protected ModelMBeanAttributeInfo getAttributeInfo(String attribute)
530: throws Exception {
531: ModelMBeanInfo mbeanInfo = (ModelMBeanInfo) this .getMBeanInfo();
532: ModelMBeanAttributeInfo attribInfo = null;
533: if (mbeanInfo != null) {
534: attribInfo = mbeanInfo.getAttribute(attribute);
535: }
536: return attribInfo;
537: }
538:
539: /**
540: * Get a handle to the registry
541: *
542: * @return the persisted registry instance
543: */
544: protected com.sun.jbi.management.registry.Registry getRegistry() {
545: return (com.sun.jbi.management.registry.Registry) getEnvironmentContext()
546: .getRegistry();
547: }
548:
549: /**
550: * Persist the domain configuration if required.
551: */
552: protected void persistDomainConfig() throws MBeanException {
553: try {
554: // If the registry configs element is empty then add the domain configuration
555: GenericQuery query = getRegistry().getGenericQuery();
556:
557: ObjectName configMBeanFilter = new ObjectName(
558: "com.sun.jbi:Target=domain,ServiceName=ConfigurationService,*");
559:
560: if (!(getEnvironmentContext().getPlatformContext()
561: .isAdminServer())) {
562: configMBeanFilter = new ObjectName(
563: "com.sun.jbi:JbiName=domain,ServiceName=ConfigurationService,*");
564: }
565:
566: if (!query.isGlobalConfigurationDefined()) {
567: // Invoke persist() on domain configuration MBeans for all categories
568: MBeanServerConnection mbns = getPlatformContext()
569: .getMBeanServerConnection(
570: getEnvironmentContext()
571: .getPlatformContext()
572: .getInstanceName());
573:
574: java.util.Set<ObjectName> nameSet = mbns.queryNames(
575: configMBeanFilter, null);
576:
577: ObjectName[] domainConfigMBeans = nameSet
578: .toArray(new ObjectName[nameSet.size()]);
579:
580: for (ObjectName domainConfigMBean : domainConfigMBeans) {
581: mbns.invoke(domainConfigMBean, "persist",
582: new Object[] {}, new String[] {});
583: }
584: }
585: } catch (Exception ex) {
586: String errMsg = getTranslator()
587: .getString(
588: LocalStringKeys.JBI_ADMIN_GLOBAL_CFG_PERSIST_FAILED,
589: mCategory.toString(), ex.getMessage());
590: javax.jbi.JBIException jbiEx = new javax.jbi.JBIException(
591: errMsg);
592: throw new MBeanException(jbiEx, errMsg);
593: }
594: }
595:
596: /**
597: * @return true if the attribute is a password field, false otherwise
598: */
599: protected boolean isPassword(String attrName) {
600: boolean isPassword = false;
601: ModelMBeanAttributeInfo attribInfo = null;
602:
603: try {
604: attribInfo = getAttributeInfo(attrName);
605: } catch (Exception ex) {
606: sLog.log(java.util.logging.Level.FINE,
607: "Failed to get Attribute Info for " + attrName, ex);
608: }
609:
610: if (attribInfo != null) {
611: javax.management.Descriptor descr = attribInfo
612: .getDescriptor();
613: Boolean isPwd = (Boolean) descr
614: .getFieldValue(DescriptorSupport.RequiredFieldName.IS_PASSWORD
615: .getFieldName());
616:
617: isPassword = isPwd.booleanValue();
618: }
619:
620: return isPassword;
621: }
622:
623: /**
624: * @return the listeners list
625: */
626: protected List<NotificationListenerInfo> getListeners() {
627: if (mListeners == null) {
628: mListeners = new java.util.ArrayList();
629: }
630: return mListeners;
631: }
632:
633: /**
634: * Send the notification to all interested listeners
635: *
636: * @param attribute the attribute being updated.
637: */
638: protected void notifyListenersOfAttributeChange(Attribute attribute)
639: throws Exception {
640: getLogger().fine(
641: "Notifying listeners of attribute change "
642: + attribute.toString());
643:
644: // Notify all listeners of the attribute change
645: AttributeChangeNotification attribChangeNotif = new AttributeChangeNotification(
646: this , mSeqNumber++, System.currentTimeMillis(),
647: getTranslator().getString(
648: LocalStringKeys.ATTRIBUTE_CHANGE_NOTIF_MSG),
649: attribute.getName(), getAttributeInfo(
650: attribute.getName()).getType(),
651: getAttribute(attribute.getName()), attribute.getValue());
652:
653: for (NotificationListenerInfo listener : getListeners()) {
654: NotificationFilter filter = listener
655: .getNotificationFilter();
656:
657: boolean sendNotif = true;
658: if (filter != null) {
659: if (!filter.isNotificationEnabled(attribChangeNotif)) {
660: getLogger().fine(
661: "Notification not enabled in listener "
662: + attribute.toString());
663: sendNotif = false;
664: }
665: }
666:
667: if (sendNotif) {
668: getLogger().fine(
669: "Notifying a listener of attribute change "
670: + attribute.toString());
671: listener.getNotificationListener().handleNotification(
672: attribChangeNotif, listener.getHandback());
673: }
674: }
675:
676: }
677:
678: /*---------------------------------------------------------------------------------*\
679: * Notification Emitter operations *
680: \*---------------------------------------------------------------------------------*/
681:
682: /**
683: * Adds a listener to this MBean.
684: *
685: *
686: * @param listener
687: * The listener object which will handle the notifications
688: * emitted by the broadcaster.
689: * @param filter
690: * The filter object. If filter is null, no filtering will be
691: * performed before handling notifications.
692: * @param handback
693: * An opaque object to be sent back to the listener when a
694: * notification is emitted. This object cannot be used by the
695: * Notification broadcaster object. It should be resent unchanged
696: * with the notification to the listener.
697: * @throws IllegalArgumentException - Listener parameter is null.
698: */
699: public void addNotificationListener(NotificationListener listener,
700: NotificationFilter filter, Object handback)
701: throws IllegalArgumentException {
702:
703: if (listener == null) {
704: throw new IllegalArgumentException();
705: }
706:
707: getListeners()
708: .add(
709: new NotificationListenerInfo(listener, filter,
710: handback));
711: }
712:
713: /**
714: *
715: */
716: public void removeNotificationListener(NotificationListener listener)
717: throws javax.management.ListenerNotFoundException {
718: List<NotificationListenerInfo> listeners = getListeners();
719: List<NotificationListenerInfo> listenersToRemove = new ArrayList();
720: for (NotificationListenerInfo listenerInfo : listeners) {
721: if (listenerInfo.getNotificationListener().equals(listener)) {
722: listenersToRemove.add(listenerInfo);
723: }
724: }
725:
726: if (listenersToRemove.isEmpty()) {
727: throw new javax.management.ListenerNotFoundException();
728: }
729:
730: listeners.removeAll(listenersToRemove);
731:
732: }
733:
734: /**
735: * Remove a specific listener from the set. One that matches the
736: * filter and handback
737: */
738: public void removeNotificationListener(
739: NotificationListener listener, NotificationFilter filter,
740: Object handback)
741: throws javax.management.ListenerNotFoundException {
742: List<NotificationListenerInfo> listeners = getListeners();
743:
744: List<NotificationListenerInfo> listenersToRemove = new ArrayList();
745: for (NotificationListenerInfo listenerInfo : listeners) {
746: if (listenerInfo.getNotificationListener().equals(listener)) {
747: boolean filterMatches = false;
748: boolean handbackMatches = false;
749: if (filter == null) {
750: filterMatches = ((listenerInfo
751: .getNotificationFilter() == null) ? true
752: : false);
753: } else {
754: filterMatches = filter.equals(listenerInfo
755: .getNotificationFilter());
756: }
757:
758: if (handback == null) {
759: handbackMatches = ((listenerInfo.getHandback() == null) ? true
760: : false);
761: } else {
762: handbackMatches = handback.equals(listenerInfo
763: .getHandback());
764: }
765:
766: if (filterMatches && handbackMatches) {
767: listenersToRemove.add(listenerInfo);
768: }
769: }
770: }
771:
772: if (listenersToRemove.isEmpty()) {
773: throw new javax.management.ListenerNotFoundException();
774: }
775:
776: listeners.removeAll(listenersToRemove);
777: }
778:
779: /**
780: *
781: */
782: public MBeanNotificationInfo[] getNotificationInfo() {
783: return initNotificationInfos();
784: }
785:
786: /*---------------------------------------------------------------------------------*\
787: * Private operations *
788: \*---------------------------------------------------------------------------------*/
789:
790: private static MBeanNotificationInfo[] initNotificationInfos() {
791: if (sNotificationInfo == null) {
792: sNotificationInfo = new MBeanNotificationInfo[1];
793:
794: sNotificationInfo[0] = new MBeanNotificationInfo(
795: new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE },
796: "javax.management.AttributeChangeNotification",
797: getTranslator().getString(
798: LocalStringKeys.ATTRIBUTE_CHANGE_NOTIF_MSG));
799: }
800: return sNotificationInfo;
801: }
802:
803: /**
804: * Initialize the data structure which maps primitive types to their wrapper classes
805: */
806: private static void initPrimitiveTypeMap() {
807: sTypeMap = new HashMap();
808: sTypeMap.put("int", "java.lang.Integer");
809: sTypeMap.put("float", "java.lang.Float");
810: sTypeMap.put("long", "java.lang.Long");
811: sTypeMap.put("double", "java.lang.Double");
812: sTypeMap.put("byte", "java.lang.Byte");
813: sTypeMap.put("char", "java.lang.Character");
814: sTypeMap.put("boolean", "java.lang.Boolean");
815: sTypeMap.put("short", "java.lang.Short");
816: }
817:
818: /**
819: * Checks the descriptopr of each and every MBeanArributeInfo.
820: *
821: * @exception ManagementException if the descriptor is null or invalid.
822: */
823: private static void checkMBeanAttributeInfos(
824: ModelMBeanAttributeInfo[] mbeanAttrInfos)
825: throws ManagementException {
826: for (ModelMBeanAttributeInfo attribInfo : mbeanAttrInfos) {
827: Descriptor descr = attribInfo.getDescriptor();
828:
829: if (descr == null) {
830: String[] params = new String[] { attribInfo.getName() };
831: String errMsg = getTranslator()
832: .getString(
833: LocalStringKeys.CS_ATTRIBUTE_DESCR_NULL,
834: params);
835: throw new ManagementException(
836: sMsgBuilder
837: .buildFrameworkMessage(
838: "checkMBeanAttributeInfos",
839: MessageBuilder.TaskResult.FAILED,
840: MessageBuilder.MessageType.ERROR,
841: MessageBuilder
842: .getMessageString(errMsg),
843: params,
844: MessageBuilder
845: .getMessageToken(errMsg)));
846: }
847:
848: if (!descr.isValid()) {
849: String[] params = new String[] { attribInfo.getName() };
850: String errMsg = getTranslator().getString(
851: LocalStringKeys.CS_ATTRIBUTE_DESCR_INVALID,
852: params);
853: throw new ManagementException(
854: sMsgBuilder
855: .buildFrameworkMessage(
856: "checkMBeanAttributeInfos",
857: MessageBuilder.TaskResult.FAILED,
858: MessageBuilder.MessageType.ERROR,
859: MessageBuilder
860: .getMessageString(errMsg),
861: params,
862: MessageBuilder
863: .getMessageToken(errMsg)));
864: }
865: }
866: }
867:
868: /**
869: * @return true if the configuration MBean allows attributes of type to be
870: * null.
871: */
872: private boolean canValueBeNull(String type) {
873: boolean canBeNull = false;
874:
875: if (type == "java.util.logging.Level") {
876: canBeNull = true;
877: }
878:
879: return canBeNull;
880: }
881: }
|