Source Code Cross Referenced for RequiredModelMBean.java in  » JMX » mx4j » javax » management » modelmbean » 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 » JMX » mx4j » javax.management.modelmbean 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (C) The MX4J Contributors.
0003:         * All rights reserved.
0004:         *
0005:         * This software is distributed under the terms of the MX4J License version 1.0.
0006:         * See the terms of the MX4J License in the documentation provided with this software.
0007:         */
0008:
0009:        package javax.management.modelmbean;
0010:
0011:        import java.lang.reflect.InvocationTargetException;
0012:        import java.lang.reflect.Method;
0013:        import java.util.Date;
0014:        import java.util.Iterator;
0015:        import javax.management.Attribute;
0016:        import javax.management.AttributeChangeNotification;
0017:        import javax.management.AttributeChangeNotificationFilter;
0018:        import javax.management.AttributeList;
0019:        import javax.management.AttributeNotFoundException;
0020:        import javax.management.Descriptor;
0021:        import javax.management.InstanceNotFoundException;
0022:        import javax.management.InvalidAttributeValueException;
0023:        import javax.management.ListenerNotFoundException;
0024:        import javax.management.MBeanAttributeInfo;
0025:        import javax.management.MBeanException;
0026:        import javax.management.MBeanInfo;
0027:        import javax.management.MBeanNotificationInfo;
0028:        import javax.management.MBeanRegistration;
0029:        import javax.management.MBeanServer;
0030:        import javax.management.MalformedObjectNameException;
0031:        import javax.management.Notification;
0032:        import javax.management.NotificationBroadcasterSupport;
0033:        import javax.management.NotificationEmitter;
0034:        import javax.management.NotificationFilter;
0035:        import javax.management.NotificationListener;
0036:        import javax.management.ObjectName;
0037:        import javax.management.ReflectionException;
0038:        import javax.management.RuntimeErrorException;
0039:        import javax.management.RuntimeOperationsException;
0040:        import javax.management.ServiceNotFoundException;
0041:        import javax.management.loading.ClassLoaderRepository;
0042:
0043:        import mx4j.ImplementationException;
0044:        import mx4j.log.FileLogger;
0045:        import mx4j.log.Log;
0046:        import mx4j.log.Logger;
0047:        import mx4j.log.MBeanLogger;
0048:        import mx4j.persist.FilePersister;
0049:        import mx4j.persist.MBeanPersister;
0050:        import mx4j.persist.PersisterMBean;
0051:        import mx4j.util.Utils;
0052:
0053:        /**
0054:         * @version $Revision: 1.22 $
0055:         */
0056:        public class RequiredModelMBean implements  ModelMBean,
0057:                MBeanRegistration, NotificationEmitter {
0058:            private static final String OBJECT_RESOURCE_TYPE = "ObjectReference";
0059:            private static final ModelMBeanInfoSupport DEFAULT_INFO;
0060:            private static final ModelMBeanNotificationInfo GENERIC_INFO;
0061:            private static final ModelMBeanNotificationInfo ATTR_CHANGE_INFO;
0062:            static {
0063:                String[] fields = new String[] { "name=GENERIC",
0064:                        "descriptorType=notification", "log=T", "severity=6",
0065:                        "displayName=jmx.modelmbean.generic" };
0066:                GENERIC_INFO = new ModelMBeanNotificationInfo(
0067:                        new String[] { "jmx.modelmbean.generic" }, "GENERIC",
0068:                        "", new DescriptorSupport(fields));
0069:                fields = new String[] { "name=ATTRIBUTE_CHANGE",
0070:                        "descriptorType=notification", "log=T", "severity=6",
0071:                        "displayName=jmx.attribute.change" };
0072:                ATTR_CHANGE_INFO = new ModelMBeanNotificationInfo(
0073:                        new String[] { "jmx.attribute.change" },
0074:                        "ATTRIBUTE_CHANGE", "", new DescriptorSupport(fields));
0075:                DEFAULT_INFO = new ModelMBeanInfoSupport(
0076:                        RequiredModelMBean.class.getName(), null, null, null,
0077:                        null, null);
0078:            }
0079:
0080:            private static final int ALWAYS_STALE = 1;
0081:            private static final int NEVER_STALE = 2;
0082:            private static final int STALE = 3;
0083:            private static final int NOT_STALE = 4;
0084:
0085:            private static final int PERSIST_NEVER = -1;
0086:            private static final int PERSIST_ON_TIMER = -2;
0087:            private static final int PERSIST_ON_UPDATE = -3;
0088:            private static final int PERSIST_NO_MORE_OFTEN_THAN = -4;
0089:
0090:            private MBeanServer m_mbeanServer;
0091:            private Object m_managedResource;
0092:            private ModelMBeanInfo m_modelMBeanInfo;
0093:            private NotificationBroadcasterSupport m_generalBroadcaster = new NotificationBroadcasterSupport();
0094:
0095:            public RequiredModelMBean() throws MBeanException,
0096:                    RuntimeOperationsException {
0097:                m_modelMBeanInfo = DEFAULT_INFO;
0098:            }
0099:
0100:            public RequiredModelMBean(ModelMBeanInfo info)
0101:                    throws MBeanException, RuntimeOperationsException {
0102:                if (info == null)
0103:                    throw new RuntimeOperationsException(
0104:                            new IllegalArgumentException(
0105:                                    "ModelMBeanInfo parameter can't be null"));
0106:                else
0107:                    setModelMBeanInfo(info);
0108:            }
0109:
0110:            private Logger getLogger() {
0111:                return Log.getLogger(getClass().getName());
0112:            }
0113:
0114:            public ObjectName preRegister(MBeanServer server, ObjectName name)
0115:                    throws Exception {
0116:                if (name == null)
0117:                    throw new IllegalArgumentException("ObjectName is null");
0118:                m_mbeanServer = server;
0119:                return name;
0120:            }
0121:
0122:            public void postRegister(Boolean registrationDone) {
0123:                if (!registrationDone.booleanValue())
0124:                    clear();
0125:            }
0126:
0127:            public void preDeregister() throws Exception {
0128:            }
0129:
0130:            public void postDeregister() {
0131:                clear();
0132:            }
0133:
0134:            private void clear() {
0135:                m_mbeanServer = null;
0136:                // PENDING: also remove generic listeners, attribute change listeners, log4j appenders...
0137:            }
0138:
0139:            public void setModelMBeanInfo(ModelMBeanInfo modelMBeanInfo)
0140:                    throws MBeanException, RuntimeOperationsException {
0141:                if (m_mbeanServer != null)
0142:                    throw new RuntimeOperationsException(
0143:                            new IllegalStateException(
0144:                                    "setModelMBeanInfo cannot be called when ModelMBean is registered"));
0145:                if (modelMBeanInfo == null)
0146:                    throw new RuntimeOperationsException(
0147:                            new IllegalArgumentException(
0148:                                    "ModelMBeanInfo cannot be null"));
0149:                if (!isModelMBeanInfoValid(modelMBeanInfo))
0150:                    throw new RuntimeOperationsException(
0151:                            new IllegalArgumentException(
0152:                                    "ModelMBeanInfo is invalid"));
0153:
0154:                m_modelMBeanInfo = new ModelMBeanInfoSupport(modelMBeanInfo);
0155:
0156:                Logger logger = getLogger();
0157:                if (logger.isEnabledFor(Logger.DEBUG))
0158:                    logger.debug("ModelMBeanInfo successfully set to: "
0159:                            + m_modelMBeanInfo);
0160:            }
0161:
0162:            private boolean isModelMBeanInfoValid(ModelMBeanInfo info) {
0163:                if (info == null || info.getClassName() == null)
0164:                    return false;
0165:                // PENDING: maybe more checks are needed
0166:                return true;
0167:            }
0168:
0169:            public void setManagedResource(Object resource, String resourceType)
0170:                    throws MBeanException, RuntimeOperationsException,
0171:                    InstanceNotFoundException, InvalidTargetObjectTypeException {
0172:                if (!isResourceTypeSupported(resourceType))
0173:                    throw new InvalidTargetObjectTypeException(resourceType);
0174:
0175:                Logger logger = getLogger();
0176:                if (logger.isEnabledFor(Logger.DEBUG))
0177:                    logger.debug("Setting managed resource to be: " + resource);
0178:                m_managedResource = resource;
0179:            }
0180:
0181:            private boolean isResourceTypeSupported(String resourceType) {
0182:                // For now only object reference is supported
0183:                return OBJECT_RESOURCE_TYPE.equalsIgnoreCase(resourceType);
0184:            }
0185:
0186:            private Object getManagedResource() {
0187:                return m_managedResource;
0188:            }
0189:
0190:            public MBeanInfo getMBeanInfo() {
0191:                return m_modelMBeanInfo == null ? null
0192:                        : (MBeanInfo) m_modelMBeanInfo.clone();
0193:            }
0194:
0195:            public void addAttributeChangeNotificationListener(
0196:                    NotificationListener listener, String attributeName,
0197:                    Object handback) throws MBeanException,
0198:                    RuntimeOperationsException, IllegalArgumentException {
0199:                if (listener == null)
0200:                    throw new IllegalArgumentException(
0201:                            "Listener cannot be null");
0202:                AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
0203:                if (attributeName != null) {
0204:                    if (m_modelMBeanInfo.getAttribute(attributeName) == null)
0205:                        throw new RuntimeOperationsException(
0206:                                new IllegalArgumentException(
0207:                                        "No attribute named " + attributeName));
0208:                    filter.enableAttribute(attributeName);
0209:                } else {
0210:                    MBeanAttributeInfo[] ai = m_modelMBeanInfo.getAttributes();
0211:                    for (int i = 0; i < ai.length; i++) {
0212:                        Descriptor d = ((ModelMBeanAttributeInfo) ai[i])
0213:                                .getDescriptor();
0214:                        filter
0215:                                .enableAttribute((String) d
0216:                                        .getFieldValue("name"));
0217:                    }
0218:                }
0219:
0220:                getAttributeChangeBroadcaster().addNotificationListener(
0221:                        listener, filter, handback);
0222:
0223:                Logger logger = getLogger();
0224:                if (logger.isEnabledFor(Logger.DEBUG))
0225:                    logger.debug("Listener " + listener + " for attribute "
0226:                            + attributeName
0227:                            + " added successfully, handback is " + handback);
0228:            }
0229:
0230:            public void addNotificationListener(NotificationListener listener,
0231:                    NotificationFilter filter, Object handback)
0232:                    throws IllegalArgumentException {
0233:                if (listener == null)
0234:                    throw new IllegalArgumentException(
0235:                            "listener cannot be null");
0236:                m_generalBroadcaster.addNotificationListener(listener, filter,
0237:                        handback);
0238:            }
0239:
0240:            public MBeanNotificationInfo[] getNotificationInfo() {
0241:                MBeanNotificationInfo[] notifications = m_modelMBeanInfo
0242:                        .getNotifications();
0243:                boolean hasGeneric = false;
0244:                boolean hasAttribute = false;
0245:                int toAdd = 2;
0246:                for (int i = 0; i < notifications.length; i++) {
0247:                    String name = notifications[i].getName();
0248:                    if ("GENERIC".equals(name)) {
0249:                        hasGeneric = true;
0250:                        toAdd -= 1;
0251:                        if (hasAttribute)
0252:                            break;
0253:                    } else if ("ATTRIBUTE_CHANGE".equals(name)) {
0254:                        hasAttribute = true;
0255:                        toAdd -= 1;
0256:                        if (hasGeneric)
0257:                            break;
0258:                    }
0259:                }
0260:
0261:                // clone the array, adding in missing notifications
0262:                MBeanNotificationInfo[] newNotifications = new MBeanNotificationInfo[notifications.length
0263:                        + toAdd];
0264:                System.arraycopy(notifications, 0, newNotifications, toAdd,
0265:                        notifications.length);
0266:                if (!hasAttribute)
0267:                    newNotifications[--toAdd] = ATTR_CHANGE_INFO;
0268:                if (!hasGeneric)
0269:                    newNotifications[--toAdd] = GENERIC_INFO;
0270:                return newNotifications;
0271:            }
0272:
0273:            public void removeAttributeChangeNotificationListener(
0274:                    NotificationListener listener, String attributeName)
0275:                    throws MBeanException, RuntimeOperationsException,
0276:                    ListenerNotFoundException {
0277:                //todo there may be a problem here if the original handback was not null - should we go directly to removeListener(NotificationListener) ?
0278:                removeAttributeChangeNotificationListener(listener,
0279:                        attributeName, null);
0280:            }
0281:
0282:            // Not in the spec but needed
0283:            private void removeAttributeChangeNotificationListener(
0284:                    NotificationListener listener, String attributeName,
0285:                    Object handback) throws MBeanException,
0286:                    RuntimeOperationsException, ListenerNotFoundException {
0287:                if (listener == null)
0288:                    throw new ListenerNotFoundException("listener is null");
0289:                AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
0290:                if (attributeName != null) {
0291:                    if (m_modelMBeanInfo.getAttribute(attributeName) == null)
0292:                        throw new RuntimeOperationsException(
0293:                                new IllegalArgumentException(
0294:                                        "No attribute named " + attributeName));
0295:                    filter.enableAttribute(attributeName);
0296:                } else {
0297:                    MBeanAttributeInfo[] ai = m_modelMBeanInfo.getAttributes();
0298:                    for (int i = 0; i < ai.length; i++) {
0299:                        Descriptor d = ((ModelMBeanAttributeInfo) ai[i])
0300:                                .getDescriptor();
0301:                        filter
0302:                                .enableAttribute((String) d
0303:                                        .getFieldValue("name"));
0304:                    }
0305:                }
0306:
0307:                getAttributeChangeBroadcaster().removeNotificationListener(
0308:                        listener, filter, handback);
0309:
0310:                Logger logger = getLogger();
0311:                if (logger.isEnabledFor(Logger.DEBUG))
0312:                    logger.debug("Listener " + listener + " for attribute "
0313:                            + attributeName
0314:                            + " removed successfully, handback is " + handback);
0315:            }
0316:
0317:            public void removeNotificationListener(NotificationListener listener)
0318:                    throws RuntimeOperationsException,
0319:                    ListenerNotFoundException {
0320:                m_generalBroadcaster.removeNotificationListener(listener);
0321:            }
0322:
0323:            public void removeNotificationListener(
0324:                    NotificationListener listener, NotificationFilter filter,
0325:                    Object handback) throws RuntimeOperationsException,
0326:                    ListenerNotFoundException {
0327:                m_generalBroadcaster.removeNotificationListener(listener,
0328:                        filter, handback);
0329:            }
0330:
0331:            public void sendAttributeChangeNotification(Attribute oldAttribute,
0332:                    Attribute newAttribute) throws MBeanException,
0333:                    RuntimeOperationsException {
0334:                if (oldAttribute == null || newAttribute == null)
0335:                    throw new RuntimeOperationsException(
0336:                            new IllegalArgumentException(
0337:                                    "Attribute cannot be null"));
0338:                if (!oldAttribute.getName().equals(newAttribute.getName()))
0339:                    throw new RuntimeOperationsException(
0340:                            new IllegalArgumentException(
0341:                                    "Attribute names cannot be different"));
0342:
0343:                // TODO: the source must be the object name of the MBean if the listener was registered through MBeanServer
0344:                Object oldValue = oldAttribute.getValue();
0345:                AttributeChangeNotification n = new AttributeChangeNotification(
0346:                        this ,
0347:                        1,
0348:                        System.currentTimeMillis(),
0349:                        "Attribute value changed",
0350:                        oldAttribute.getName(),
0351:                        oldValue == null ? null : oldValue.getClass().getName(),
0352:                        oldValue, newAttribute.getValue());
0353:                sendAttributeChangeNotification(n);
0354:            }
0355:
0356:            public void sendAttributeChangeNotification(
0357:                    AttributeChangeNotification notification)
0358:                    throws MBeanException, RuntimeOperationsException {
0359:                if (notification == null)
0360:                    throw new RuntimeOperationsException(
0361:                            new IllegalArgumentException(
0362:                                    "Notification cannot be null"));
0363:
0364:                getAttributeChangeBroadcaster().sendNotification(notification);
0365:
0366:                Logger modelMBeanLogger = getModelMBeanLogger(notification
0367:                        .getType());
0368:                if (modelMBeanLogger != null)
0369:                    if (modelMBeanLogger.isEnabledFor(Logger.DEBUG))
0370:                        modelMBeanLogger.debug("ModelMBean log: " + new Date()
0371:                                + " - " + notification);
0372:
0373:                Logger logger = getLogger();
0374:                if (logger.isEnabledFor(Logger.DEBUG))
0375:                    logger.debug("Attribute change notification "
0376:                            + notification + " sent");
0377:            }
0378:
0379:            public void sendNotification(String message) throws MBeanException,
0380:                    RuntimeOperationsException {
0381:                if (message == null)
0382:                    throw new RuntimeOperationsException(
0383:                            new IllegalArgumentException("message is null"));
0384:                Notification notification = new Notification(
0385:                        "jmx.modelmbean.generic", this , 1, message);
0386:                sendNotification(notification);
0387:            }
0388:
0389:            public void sendNotification(Notification notification)
0390:                    throws MBeanException, RuntimeOperationsException {
0391:                if (notification == null)
0392:                    throw new RuntimeOperationsException(
0393:                            new IllegalArgumentException("notification is null"));
0394:                m_generalBroadcaster.sendNotification(notification);
0395:            }
0396:
0397:            public AttributeList getAttributes(String[] attributes) {
0398:                if (attributes == null)
0399:                    throw new RuntimeOperationsException(
0400:                            new IllegalArgumentException(
0401:                                    "Attribute names cannot be null"));
0402:
0403:                Logger logger = getLogger();
0404:
0405:                AttributeList list = new AttributeList();
0406:                for (int i = 0; i < attributes.length; ++i) {
0407:                    String attrName = attributes[i];
0408:                    Attribute attribute = null;
0409:                    try {
0410:                        Object value = getAttribute(attrName);
0411:                        attribute = new Attribute(attrName, value);
0412:                        list.add(attribute);
0413:                    } catch (Exception x) {
0414:                        if (logger.isEnabledFor(Logger.TRACE))
0415:                            logger.trace("getAttribute for attribute "
0416:                                    + attrName + " failed", x);
0417:                        // And go on with the next attribute
0418:                    }
0419:                }
0420:                return list;
0421:            }
0422:
0423:            public Object getAttribute(String attribute)
0424:                    throws AttributeNotFoundException, MBeanException,
0425:                    ReflectionException {
0426:                if (attribute == null)
0427:                    throw new RuntimeOperationsException(
0428:                            new IllegalArgumentException(
0429:                                    "Attribute name cannot be null"));
0430:
0431:                Logger logger = getLogger();
0432:
0433:                // I want the real info, not its clone
0434:                ModelMBeanInfo info = getModelMBeanInfo();
0435:                if (info == null)
0436:                    throw new AttributeNotFoundException(
0437:                            "ModelMBeanInfo is null");
0438:                if (logger.isEnabledFor(Logger.DEBUG))
0439:                    logger.debug("ModelMBeanInfo is: " + info);
0440:
0441:                // This is a clone, we use it read only
0442:                ModelMBeanAttributeInfo attrInfo = info.getAttribute(attribute);
0443:                if (attrInfo == null)
0444:                    throw new AttributeNotFoundException(
0445:                            "Cannot find ModelMBeanAttributeInfo for attribute "
0446:                                    + attribute);
0447:                if (logger.isEnabledFor(Logger.DEBUG))
0448:                    logger.debug("Attribute info is: " + attrInfo);
0449:                if (!attrInfo.isReadable())
0450:                    throw new AttributeNotFoundException("Attribute "
0451:                            + attribute + " is not readable");
0452:
0453:                // This returns a clone of the mbean descriptor, we use it read only
0454:                Descriptor mbeanDescriptor = info.getMBeanDescriptor();
0455:                if (mbeanDescriptor == null)
0456:                    throw new AttributeNotFoundException(
0457:                            "MBean descriptor cannot be null");
0458:                if (logger.isEnabledFor(Logger.DEBUG))
0459:                    logger.debug("MBean descriptor is: " + mbeanDescriptor);
0460:
0461:                // This descriptor is a clone
0462:                Descriptor attributeDescriptor = attrInfo.getDescriptor();
0463:                if (attributeDescriptor == null)
0464:                    throw new AttributeNotFoundException(
0465:                            "Attribute descriptor for attribute " + attribute
0466:                                    + " cannot be null");
0467:                if (logger.isEnabledFor(Logger.DEBUG))
0468:                    logger.debug("Attribute descriptor is: "
0469:                            + attributeDescriptor);
0470:
0471:                Object returnValue = null;
0472:
0473:                String lastUpdateField = "lastUpdatedTimeStamp";
0474:
0475:                int staleness = getStaleness(attributeDescriptor,
0476:                        mbeanDescriptor, lastUpdateField);
0477:
0478:                if (staleness == ALWAYS_STALE || staleness == STALE) {
0479:                    if (logger.isEnabledFor(Logger.TRACE))
0480:                        logger.trace("Value is stale");
0481:
0482:                    String getter = (String) attributeDescriptor
0483:                            .getFieldValue("getMethod");
0484:                    if (logger.isEnabledFor(Logger.DEBUG))
0485:                        logger.debug("getMethod field is: " + getter);
0486:                    if (getter == null) {
0487:                        // No getter, use default value
0488:                        returnValue = attributeDescriptor
0489:                                .getFieldValue("default");
0490:
0491:                        if (returnValue != null) {
0492:                            // Check if the return type is of the same type
0493:                            // As an extension allow covariant return type
0494:                            Class returned = returnValue.getClass();
0495:                            Class declared = loadClassWithContextClassLoader(attrInfo
0496:                                    .getType());
0497:
0498:                            checkAssignability(returned, declared);
0499:                        }
0500:
0501:                        if (logger.isEnabledFor(Logger.DEBUG))
0502:                            logger.debug("getAttribute for attribute "
0503:                                    + attribute + " returns default value: "
0504:                                    + returnValue);
0505:                    } else {
0506:                        if (logger.isEnabledFor(Logger.TRACE))
0507:                            logger.trace("Invoking attribute getter...");
0508:                        // As an extension, allow attributes to be called on target objects also
0509:                        Object target = resolveTargetObject(attributeDescriptor);
0510:                        returnValue = invokeMethod(target, getter,
0511:                                new Class[0], new Object[0]);
0512:                        if (logger.isEnabledFor(Logger.DEBUG))
0513:                            logger.debug("Returned value is: " + returnValue);
0514:
0515:                        if (returnValue != null) {
0516:                            // Check if the return type is of the same type
0517:                            // As an extension allow covariant return type
0518:                            Class returned = returnValue.getClass();
0519:                            Class declared = loadClassWithContextClassLoader(attrInfo
0520:                                    .getType());
0521:
0522:                            checkAssignability(returned, declared);
0523:                        }
0524:
0525:                        // Cache the new value only if caching is needed
0526:                        if (staleness != ALWAYS_STALE) {
0527:                            attributeDescriptor.setField("value", returnValue);
0528:                            attributeDescriptor.setField(lastUpdateField,
0529:                                    new Long(System.currentTimeMillis()));
0530:                            if (logger.isEnabledFor(Logger.TRACE))
0531:                                logger.trace("Returned value has been cached");
0532:
0533:                            // And now replace the descriptor with the updated clone
0534:                            info
0535:                                    .setDescriptor(attributeDescriptor,
0536:                                            "attribute");
0537:                        }
0538:
0539:                        if (logger.isEnabledFor(Logger.DEBUG))
0540:                            logger.debug("getAttribute for attribute "
0541:                                    + attribute + " returns invoked value: "
0542:                                    + returnValue);
0543:                    }
0544:                } else {
0545:                    // Return cached value
0546:                    returnValue = attributeDescriptor.getFieldValue("value");
0547:
0548:                    if (returnValue != null) {
0549:                        // Check if the return type is of the same type
0550:                        // As an extension allow covariant return type
0551:                        Class returned = returnValue.getClass();
0552:                        Class declared = loadClassWithContextClassLoader(attrInfo
0553:                                .getType());
0554:
0555:                        checkAssignability(returned, declared);
0556:                    }
0557:
0558:                    if (logger.isEnabledFor(Logger.DEBUG))
0559:                        logger.debug("getAttribute for attribute " + attribute
0560:                                + " returns cached value: " + returnValue);
0561:                }
0562:
0563:                // Puff, everything went ok
0564:                return returnValue;
0565:            }
0566:
0567:            public AttributeList setAttributes(AttributeList attributes) {
0568:                if (attributes == null)
0569:                    throw new RuntimeOperationsException(
0570:                            new IllegalArgumentException(
0571:                                    "Attribute list cannot be null"));
0572:
0573:                Logger logger = getLogger();
0574:
0575:                AttributeList list = new AttributeList();
0576:                for (Iterator i = attributes.iterator(); i.hasNext();) {
0577:                    Attribute attribute = (Attribute) i.next();
0578:                    String name = attribute.getName();
0579:                    try {
0580:                        setAttribute(attribute);
0581:                        list.add(attribute);
0582:                    } catch (Exception x) {
0583:                        if (logger.isEnabledFor(Logger.TRACE))
0584:                            logger.trace("setAttribute for attribute " + name
0585:                                    + " failed", x);
0586:                        // And go on with the next one
0587:                    }
0588:                }
0589:                return list;
0590:            }
0591:
0592:            public void setAttribute(Attribute attribute)
0593:                    throws AttributeNotFoundException,
0594:                    InvalidAttributeValueException, MBeanException,
0595:                    ReflectionException {
0596:                if (attribute == null)
0597:                    throw new RuntimeOperationsException(
0598:                            new IllegalArgumentException(
0599:                                    "Attribute cannot be null"));
0600:
0601:                Logger logger = getLogger();
0602:
0603:                // No need to synchronize: I work mostly on clones
0604:                // I want the real info, not its clone
0605:                ModelMBeanInfo info = getModelMBeanInfo();
0606:                if (info == null)
0607:                    throw new AttributeNotFoundException(
0608:                            "ModelMBeanInfo is null");
0609:                if (logger.isEnabledFor(Logger.DEBUG))
0610:                    logger.debug("ModelMBeanInfo is: " + info);
0611:
0612:                String attrName = attribute.getName();
0613:                Object attrValue = attribute.getValue();
0614:
0615:                // This is a clone, we use it read only
0616:                ModelMBeanAttributeInfo attrInfo = info.getAttribute(attrName);
0617:                if (attrInfo == null)
0618:                    throw new AttributeNotFoundException(
0619:                            "Cannot find ModelMBeanAttributeInfo for attribute "
0620:                                    + attrName);
0621:                if (logger.isEnabledFor(Logger.DEBUG))
0622:                    logger.debug("Attribute info is: " + attrInfo);
0623:
0624:                if (!attrInfo.isWritable())
0625:                    throw new AttributeNotFoundException("Attribute "
0626:                            + attrName + " is not writable");
0627:
0628:                // This returns a clone of the mbean descriptor, we use it read only
0629:                Descriptor mbeanDescriptor = info.getMBeanDescriptor();
0630:                if (mbeanDescriptor == null)
0631:                    throw new AttributeNotFoundException(
0632:                            "MBean descriptor cannot be null");
0633:                if (logger.isEnabledFor(Logger.DEBUG))
0634:                    logger.debug("MBean descriptor is: " + mbeanDescriptor);
0635:
0636:                // This descriptor is a clone
0637:                Descriptor attributeDescriptor = attrInfo.getDescriptor();
0638:                if (attributeDescriptor == null)
0639:                    throw new AttributeNotFoundException(
0640:                            "Attribute descriptor for attribute " + attrName
0641:                                    + " cannot be null");
0642:                if (logger.isEnabledFor(Logger.DEBUG))
0643:                    logger.debug("Attribute descriptor is: "
0644:                            + attributeDescriptor);
0645:
0646:                String lastUpdateField = "lastUpdatedTimeStamp";
0647:
0648:                Object oldValue = null;
0649:                try {
0650:                    oldValue = getAttribute(attrName);
0651:                    if (logger.isEnabledFor(Logger.DEBUG))
0652:                        logger.debug("Previous value of attribute " + attrName
0653:                                + ": " + oldValue);
0654:                } catch (Exception x) {
0655:                    if (logger.isEnabledFor(Logger.DEBUG))
0656:                        logger.debug("Cannot get previous value of attribute "
0657:                                + attrName, x);
0658:                }
0659:
0660:                // Check if setMethod is present
0661:                String method = (String) attributeDescriptor
0662:                        .getFieldValue("setMethod");
0663:                if (logger.isEnabledFor(Logger.DEBUG))
0664:                    logger.debug("setMethod field is: " + method);
0665:                if (method != null) {
0666:                    Class declared = loadClassWithContextClassLoader(attrInfo
0667:                            .getType());
0668:                    if (attrValue != null) {
0669:                        Class parameter = attrValue.getClass();
0670:                        checkAssignability(parameter, declared);
0671:                    }
0672:
0673:                    // As an extension, allow attributes to be called on target objects also
0674:                    Object target = resolveTargetObject(attributeDescriptor);
0675:                    invokeMethod(target, method, new Class[] { declared },
0676:                            new Object[] { attrValue });
0677:
0678:                    // Cache the value only if currencyTimeLimit is not 0, ie it is not always stale
0679:                    int staleness = getStaleness(attributeDescriptor,
0680:                            mbeanDescriptor, lastUpdateField);
0681:                    if (staleness != ALWAYS_STALE) {
0682:                        attributeDescriptor.setField("value", attrValue);
0683:                        attributeDescriptor.setField(lastUpdateField, new Long(
0684:                                System.currentTimeMillis()));
0685:                        if (logger.isEnabledFor(Logger.TRACE))
0686:                            logger.trace("Attribute's value has been cached");
0687:                    } else {
0688:                        if (logger.isEnabledFor(Logger.TRACE))
0689:                            logger
0690:                                    .trace("Always stale, avoiding to cache attribute's value");
0691:                    }
0692:                } else {
0693:                    if (attrValue != null) {
0694:                        Class parameter = attrValue.getClass();
0695:                        Class declared = loadClassWithContextClassLoader(attrInfo
0696:                                .getType());
0697:
0698:                        checkAssignability(parameter, declared);
0699:                    }
0700:
0701:                    // Always store the value in the descriptor: no setMethod
0702:                    attributeDescriptor.setField("value", attrValue);
0703:                }
0704:
0705:                // And now replace the descriptor with the updated clone
0706:                info.setDescriptor(attributeDescriptor, "attribute");
0707:
0708:                // Send notifications to listeners
0709:                if (logger.isEnabledFor(Logger.TRACE))
0710:                    logger.trace("Sending attribute change notifications");
0711:                sendAttributeChangeNotification(new Attribute(attrName,
0712:                        oldValue), attribute);
0713:
0714:                // Persist this ModelMBean
0715:                boolean persistNow = shouldPersistNow(attributeDescriptor,
0716:                        mbeanDescriptor, lastUpdateField);
0717:                if (persistNow) {
0718:                    if (logger.isEnabledFor(Logger.TRACE))
0719:                        logger.trace("Persisting this ModelMBean...");
0720:                    try {
0721:                        store();
0722:                        if (logger.isEnabledFor(Logger.TRACE))
0723:                            logger.trace("ModelMBean persisted successfully");
0724:                    } catch (Exception x) {
0725:                        logger
0726:                                .error(
0727:                                        "Cannot store ModelMBean after setAttribute",
0728:                                        x);
0729:                        if (x instanceof  MBeanException)
0730:                            throw (MBeanException) x;
0731:                        else
0732:                            throw new MBeanException(x);
0733:                    }
0734:                }
0735:            }
0736:
0737:            public Object invoke(String method, Object[] arguments,
0738:                    String[] params) throws MBeanException, ReflectionException {
0739:                if (method == null)
0740:                    throw new RuntimeOperationsException(
0741:                            new IllegalArgumentException(
0742:                                    "Method name cannot be null"));
0743:                if (arguments == null)
0744:                    arguments = new Object[0];
0745:                if (params == null)
0746:                    params = new String[0];
0747:
0748:                Logger logger = getLogger();
0749:
0750:                // Find operation descriptor
0751:                ModelMBeanInfo info = getModelMBeanInfo();
0752:                if (info == null)
0753:                    throw new MBeanException(new ServiceNotFoundException(
0754:                            "ModelMBeanInfo is null"));
0755:                if (logger.isEnabledFor(Logger.DEBUG))
0756:                    logger.debug("ModelMBeanInfo is: " + info);
0757:
0758:                // This is a clone, we use it read only
0759:                ModelMBeanOperationInfo operInfo = info.getOperation(method);
0760:                if (operInfo == null) {
0761:                    // Bug #940161 Required ModelMBean methods are not invoked
0762:                    try {
0763:                        // Look in RMMB public methods
0764:                        Class[] clzArgs = new Class[params.length];
0765:                        for (int i = 0; i < clzArgs.length; i++) {
0766:                            ClassLoader loader = getClass().getClassLoader();
0767:                            if (loader == null)
0768:                                loader = Thread.currentThread()
0769:                                        .getContextClassLoader();
0770:                            clzArgs[i] = loader.loadClass(params[i]);
0771:                        }
0772:
0773:                        // Class.getMethod only returns public methods
0774:                        Method invocationMethod = getClass().getMethod(method,
0775:                                clzArgs);
0776:                        operInfo = new ModelMBeanOperationInfo("",
0777:                                invocationMethod);
0778:                    } catch (Exception e) {
0779:                        throw new MBeanException(new ServiceNotFoundException(
0780:                                "Cannot find ModelMBeanOperationInfo for operation "
0781:                                        + method));
0782:                    }
0783:                }
0784:                if (logger.isEnabledFor(Logger.DEBUG))
0785:                    logger.debug("Operation info is: " + operInfo);
0786:
0787:                // This descriptor is a clone
0788:                Descriptor operationDescriptor = operInfo.getDescriptor();
0789:                if (operationDescriptor == null)
0790:                    throw new MBeanException(new ServiceNotFoundException(
0791:                            "Operation descriptor for operation " + method
0792:                                    + " cannot be null"));
0793:                String role = (String) operationDescriptor
0794:                        .getFieldValue("role");
0795:                if (role == null || !role.equals("operation"))
0796:                    throw new MBeanException(new ServiceNotFoundException(
0797:                            "Operation descriptor field 'role' must be 'operation', not "
0798:                                    + role));
0799:                if (logger.isEnabledFor(Logger.DEBUG))
0800:                    logger.debug("Operation descriptor is: "
0801:                            + operationDescriptor);
0802:
0803:                // This returns a clone of the mbean descriptor, we use it read only
0804:                Descriptor mbeanDescriptor = info.getMBeanDescriptor();
0805:                if (mbeanDescriptor == null)
0806:                    throw new MBeanException(new ServiceNotFoundException(
0807:                            "MBean descriptor cannot be null"));
0808:                if (logger.isEnabledFor(Logger.DEBUG))
0809:                    logger.debug("MBean descriptor is: " + mbeanDescriptor);
0810:
0811:                Object returnValue = null;
0812:
0813:                String lastUpdateField = "lastReturnedTimeStamp";
0814:
0815:                // Check if the method should be invoked given the cache settings
0816:                int staleness = getStaleness(operationDescriptor,
0817:                        mbeanDescriptor, lastUpdateField);
0818:
0819:                if (staleness == ALWAYS_STALE || staleness == STALE) {
0820:                    if (logger.isEnabledFor(Logger.TRACE))
0821:                        logger.trace("Value is stale");
0822:
0823:                    // Find parameters classes
0824:                    Class[] parameters = null;
0825:                    try {
0826:                        parameters = Utils.loadClasses(Thread.currentThread()
0827:                                .getContextClassLoader(), params);
0828:                    } catch (ClassNotFoundException x) {
0829:                        logger.error(
0830:                                "Cannot find operation's parameter classes", x);
0831:                        throw new ReflectionException(x);
0832:                    }
0833:
0834:                    if (logger.isEnabledFor(Logger.TRACE))
0835:                        logger.trace("Invoking operation...");
0836:
0837:                    // Find target object
0838:                    Object target = resolveTargetObject(operationDescriptor);
0839:                    returnValue = invokeMethod(target, method, parameters,
0840:                            arguments);
0841:
0842:                    if (logger.isEnabledFor(Logger.DEBUG))
0843:                        logger.debug("Returned value is: " + returnValue);
0844:
0845:                    if (returnValue != null) {
0846:                        Class parameter = returnValue.getClass();
0847:                        Class declared = loadClassWithContextClassLoader(operInfo
0848:                                .getReturnType());
0849:
0850:                        checkAssignability(parameter, declared);
0851:                    }
0852:
0853:                    // Cache the new value only if caching is needed
0854:                    if (staleness != ALWAYS_STALE) {
0855:                        operationDescriptor.setField("lastReturnedValue",
0856:                                returnValue);
0857:                        operationDescriptor.setField(lastUpdateField, new Long(
0858:                                System.currentTimeMillis()));
0859:                        if (logger.isEnabledFor(Logger.TRACE)) {
0860:                            logger.trace("Returned value has been cached");
0861:                        }
0862:
0863:                        // And now replace the descriptor with the updated clone
0864:                        info.setDescriptor(operationDescriptor, "operation");
0865:                    }
0866:
0867:                    if (logger.isEnabledFor(Logger.DEBUG))
0868:                        logger.debug("invoke for operation " + method
0869:                                + " returns invoked value: " + returnValue);
0870:                } else {
0871:                    // Return cached value
0872:                    returnValue = operationDescriptor
0873:                            .getFieldValue("lastReturnedValue");
0874:
0875:                    if (returnValue != null) {
0876:                        Class parameter = returnValue.getClass();
0877:                        Class declared = loadClassWithContextClassLoader(operInfo
0878:                                .getReturnType());
0879:
0880:                        checkAssignability(parameter, declared);
0881:                    }
0882:
0883:                    if (logger.isEnabledFor(Logger.DEBUG))
0884:                        logger.debug("invoke for operation " + method
0885:                                + " returns cached value: " + returnValue);
0886:                }
0887:
0888:                // As an extension, persist this model mbean also after operation invocation, but using only
0889:                // settings provided in the operation descriptor, without falling back to defaults set in
0890:                // the MBean descriptor
0891:                boolean persistNow = shouldPersistNow(operationDescriptor,
0892:                        null, lastUpdateField);
0893:                int impact = operInfo.getImpact();
0894:                if (persistNow && impact != ModelMBeanOperationInfo.INFO) {
0895:                    if (logger.isEnabledFor(Logger.TRACE))
0896:                        logger.trace("Persisting this ModelMBean...");
0897:                    try {
0898:                        store();
0899:                        if (logger.isEnabledFor(Logger.TRACE))
0900:                            logger.trace("ModelMBean persisted successfully");
0901:                    } catch (Exception x) {
0902:                        logger
0903:                                .error(
0904:                                        "Cannot store ModelMBean after operation invocation",
0905:                                        x);
0906:                        if (x instanceof  MBeanException)
0907:                            throw (MBeanException) x;
0908:                        else
0909:                            throw new MBeanException(x);
0910:                    }
0911:                }
0912:
0913:                return returnValue;
0914:            }
0915:
0916:            private Object resolveTargetObject(Descriptor descriptor)
0917:                    throws MBeanException {
0918:                Logger logger = getLogger();
0919:                Object target = descriptor.getFieldValue("targetObject");
0920:                if (logger.isEnabledFor(Logger.TRACE))
0921:                    logger.trace("targetObject is: " + target);
0922:                if (target == null) {
0923:                    target = getManagedResource();
0924:                } else {
0925:                    String targetObjectType = (String) descriptor
0926:                            .getFieldValue("targetObjectType");
0927:                    if (logger.isEnabledFor(Logger.TRACE))
0928:                        logger
0929:                                .trace("targetObjectType is: "
0930:                                        + targetObjectType);
0931:                    if (targetObjectType == null) {
0932:                        // Not defined, assume object reference
0933:                        targetObjectType = OBJECT_RESOURCE_TYPE;
0934:                    }
0935:
0936:                    if (!isResourceTypeSupported(targetObjectType))
0937:                        throw new MBeanException(
0938:                                new InvalidTargetObjectTypeException(
0939:                                        targetObjectType));
0940:                }
0941:                return target;
0942:            }
0943:
0944:            public void load() throws MBeanException,
0945:                    RuntimeOperationsException, InstanceNotFoundException {
0946:                PersisterMBean persister = findPersister();
0947:                if (persister != null) {
0948:                    ModelMBeanInfo info = (ModelMBeanInfo) persister.load();
0949:                    setModelMBeanInfo(info);
0950:                }
0951:            }
0952:
0953:            public void store() throws MBeanException,
0954:                    RuntimeOperationsException, InstanceNotFoundException {
0955:                PersisterMBean persister = findPersister();
0956:                if (persister != null) {
0957:                    // Take a clone to avoid synchronization problems
0958:                    ModelMBeanInfo info = (ModelMBeanInfo) getMBeanInfo();
0959:                    persister.store(info);
0960:                }
0961:            }
0962:
0963:            protected ClassLoaderRepository getClassLoaderRepository() {
0964:                if (m_mbeanServer != null)
0965:                    return m_mbeanServer.getClassLoaderRepository();
0966:                else
0967:                    return null;
0968:            }
0969:
0970:            private boolean shouldPersistNow(Descriptor attribute,
0971:                    Descriptor mbean, String lastUpdateField) {
0972:                int persist = getPersistPolicy(attribute, mbean);
0973:                if (persist == PERSIST_NO_MORE_OFTEN_THAN) {
0974:                    Long period = getFieldTimeValue(attribute, mbean,
0975:                            "persistPeriod");
0976:                    long now = System.currentTimeMillis();
0977:                    Long lastUpdate = (Long) attribute
0978:                            .getFieldValue(lastUpdateField);
0979:                    if (now - lastUpdate.longValue() < period.longValue())
0980:                        return false;
0981:                    else
0982:                        return true;
0983:                } else if (persist == PERSIST_NEVER) {
0984:                    return false;
0985:                } else if (persist == PERSIST_ON_TIMER) {
0986:                    return false;
0987:                } else if (persist == PERSIST_ON_UPDATE) {
0988:                    return true;
0989:                } else {
0990:                    throw new ImplementationException("Invalid persist value");
0991:                }
0992:            }
0993:
0994:            private int getPersistPolicy(Descriptor descriptor, Descriptor mbean) {
0995:                Logger logger = getLogger();
0996:
0997:                String persist = (String) descriptor
0998:                        .getFieldValue("persistPolicy");
0999:                if (persist == null && mbean != null)
1000:                    persist = (String) mbean.getFieldValue("persistPolicy");
1001:                if (persist == null) {
1002:                    if (logger.isEnabledFor(Logger.TRACE))
1003:                        logger
1004:                                .trace("No persist policy defined, assuming Never");
1005:                    return PERSIST_NEVER;
1006:                } else {
1007:                    if (persist.equals("Never")) {
1008:                        if (logger.isEnabledFor(Logger.TRACE))
1009:                            logger.trace("Persist never");
1010:                        return PERSIST_NEVER;
1011:                    } else if (persist.equals("OnUpdate")) {
1012:                        if (logger.isEnabledFor(Logger.TRACE))
1013:                            logger.trace("Persist on update");
1014:                        return PERSIST_ON_UPDATE;
1015:                    } else if (persist.equals("OnTimer")) {
1016:                        if (logger.isEnabledFor(Logger.TRACE))
1017:                            logger.trace("Persist on update");
1018:                        return PERSIST_ON_TIMER;
1019:                    } else if (persist.equals("NoMoreOftenThan")) {
1020:                        if (logger.isEnabledFor(Logger.TRACE)) {
1021:                            Long period = getFieldTimeValue(descriptor, mbean,
1022:                                    "persistPeriod");
1023:                            logger
1024:                                    .trace("Persist no more often than "
1025:                                            + period);
1026:                        }
1027:                        return PERSIST_NO_MORE_OFTEN_THAN;
1028:                    } else {
1029:                        // Garbage, assuming Never
1030:                        if (logger.isEnabledFor(Logger.TRACE))
1031:                            logger
1032:                                    .trace("Invalid persist policy, assuming persist never");
1033:                        return PERSIST_NEVER;
1034:                    }
1035:                }
1036:            }
1037:
1038:            private int getStaleness(Descriptor attribute, Descriptor mbean,
1039:                    String lastUpdateField) {
1040:                Logger logger = getLogger();
1041:
1042:                Long currencyTimeLimit = getFieldTimeValue(attribute, mbean,
1043:                        "currencyTimeLimit");
1044:                if (currencyTimeLimit == null) {
1045:                    // No time limit defined
1046:                    if (logger.isEnabledFor(Logger.TRACE))
1047:                        logger
1048:                                .trace("No currencyTimeLimit defined, assuming always stale");
1049:                    return ALWAYS_STALE;
1050:                } else {
1051:                    long ctl = currencyTimeLimit.longValue() * 1000;
1052:                    if (logger.isEnabledFor(Logger.TRACE))
1053:                        logger.trace("currencyTimeLimit is (ms): " + ctl);
1054:
1055:                    if (ctl == 0) {
1056:                        // Never stale
1057:                        if (logger.isEnabledFor(Logger.TRACE))
1058:                            logger.trace("Never stale");
1059:                        return NEVER_STALE;
1060:                    } else if (ctl < 0) // this should be == -1 but the other cases are in the air
1061:                    {
1062:                        // Always stale
1063:                        if (logger.isEnabledFor(Logger.TRACE))
1064:                            logger.trace("Always stale");
1065:                        return ALWAYS_STALE;
1066:                    } else {
1067:                        Long timestamp = (Long) attribute
1068:                                .getFieldValue(lastUpdateField);
1069:                        long luts = 0;
1070:
1071:                        if (timestamp != null)
1072:                            luts = timestamp.longValue();
1073:                        if (logger.isEnabledFor(Logger.DEBUG))
1074:                            logger.debug(lastUpdateField + " is: " + luts);
1075:
1076:                        long now = System.currentTimeMillis();
1077:                        if (now < luts + ctl) {
1078:                            // Seems to be not stale, but has been set at least once ?
1079:                            if (timestamp == null) {
1080:                                // Return stale to call it the first time
1081:                                if (logger.isEnabledFor(Logger.TRACE))
1082:                                    logger.trace("Stale since was never set");
1083:                                return STALE;
1084:                            } else {
1085:                                if (logger.isEnabledFor(Logger.TRACE))
1086:                                    logger.trace("Not stale");
1087:                                return NOT_STALE;
1088:                            }
1089:                        } else {
1090:                            // Stale
1091:                            if (logger.isEnabledFor(Logger.TRACE))
1092:                                logger.trace("Stale");
1093:                            return STALE;
1094:                        }
1095:                    }
1096:                }
1097:            }
1098:
1099:            private Long getFieldTimeValue(Descriptor descriptor,
1100:                    Descriptor mbean, String field) {
1101:                Logger logger = getLogger();
1102:
1103:                Object value = descriptor.getFieldValue(field);
1104:                if (logger.isEnabledFor(Logger.DEBUG))
1105:                    logger.debug("Descriptor's " + field + " field: " + value);
1106:
1107:                if (value == null && mbean != null) {
1108:                    value = mbean.getFieldValue(field);
1109:                    if (logger.isEnabledFor(Logger.DEBUG))
1110:                        logger.debug("MBean's " + field + " field: " + value);
1111:                    if (value == null)
1112:                        return null;
1113:                }
1114:
1115:                if (value instanceof  Number)
1116:                    return new Long(((Number) value).longValue());
1117:
1118:                if (value instanceof  String) {
1119:                    try {
1120:                        long ctl = Long.parseLong((String) value);
1121:                        return new Long(ctl);
1122:                    } catch (NumberFormatException x) {
1123:                        return new Long(0);
1124:                    }
1125:                }
1126:                return new Long(0);
1127:            }
1128:
1129:            private Object invokeMethod(Object target, String methodName,
1130:                    Class[] params, Object[] args) throws MBeanException,
1131:                    ReflectionException {
1132:                // First try on this instance, then on the target
1133:                Object realTarget = null;
1134:                Method method = null;
1135:                try {
1136:                    realTarget = this ;
1137:                    method = realTarget.getClass()
1138:                            .getMethod(methodName, params);
1139:                } catch (NoSuchMethodException x) {
1140:                    realTarget = target;
1141:                }
1142:
1143:                if (realTarget == null)
1144:                    throw new MBeanException(new ServiceNotFoundException(
1145:                            "Could not find target"));
1146:
1147:                if (method == null) {
1148:                    try {
1149:                        method = realTarget.getClass().getMethod(methodName,
1150:                                params);
1151:                    } catch (NoSuchMethodException x) {
1152:                        throw new ReflectionException(x);
1153:                    }
1154:                }
1155:
1156:                try {
1157:                    Object value = method.invoke(realTarget, args);
1158:                    Logger logger = getLogger();
1159:                    if (logger.isEnabledFor(Logger.DEBUG))
1160:                        logger.debug("Method invocation returned value: "
1161:                                + value);
1162:                    return value;
1163:                } catch (IllegalAccessException x) {
1164:                    throw new ReflectionException(x);
1165:                } catch (IllegalArgumentException x) {
1166:                    throw new MBeanException(x);
1167:                } catch (InvocationTargetException x) {
1168:                    Throwable t = x.getTargetException();
1169:                    if (t instanceof  Error)
1170:                        throw new MBeanException(new RuntimeErrorException(
1171:                                (Error) t));
1172:                    else
1173:                        throw new MBeanException((Exception) t);
1174:                }
1175:            }
1176:
1177:            private Logger getModelMBeanLogger(String notificationType)
1178:                    throws MBeanException {
1179:                // Get a copy to avoid synchronization
1180:                ModelMBeanInfo info = getModelMBeanInfo();
1181:
1182:                // First look if there is a suitable notification descriptor, otherwise use MBean descriptor
1183:                Descriptor descriptor = null;
1184:                Logger modelMBeanLogger = null;
1185:                if (notificationType != null) {
1186:                    descriptor = info.getDescriptor(notificationType,
1187:                            "notification");
1188:                    modelMBeanLogger = findLogger(descriptor);
1189:                }
1190:
1191:                if (modelMBeanLogger == null) {
1192:                    descriptor = info.getMBeanDescriptor();
1193:                    modelMBeanLogger = findLogger(descriptor);
1194:                    if (modelMBeanLogger != null)
1195:                        return modelMBeanLogger;
1196:                }
1197:
1198:                return null;
1199:            }
1200:
1201:            private Logger findLogger(Descriptor descriptor) {
1202:                Logger logger = getLogger();
1203:
1204:                if (descriptor == null) {
1205:                    if (logger.isEnabledFor(Logger.TRACE))
1206:                        logger
1207:                                .trace("Can't find MBean logger, descriptor is null");
1208:                    return null;
1209:                }
1210:
1211:                String log = (String) descriptor.getFieldValue("log");
1212:                String location = (String) descriptor.getFieldValue("logFile");
1213:
1214:                if (logger.isEnabledFor(Logger.DEBUG))
1215:                    logger.debug("Log fields: log=" + log + ", file="
1216:                            + location);
1217:
1218:                if (log == null || !Boolean.valueOf(log).booleanValue()) {
1219:                    if (logger.isEnabledFor(Logger.DEBUG))
1220:                        logger
1221:                                .debug("Logging is not supported by this ModelMBean");
1222:                    return null;
1223:                }
1224:                // Logger is supported, where log to ?
1225:                if (location == null) {
1226:                    // As an extension, see if the field logMBean has been defined
1227:                    location = (String) descriptor.getFieldValue("logMBean");
1228:                    if (logger.isEnabledFor(Logger.DEBUG))
1229:                        logger.debug("Log fields: mbean=" + location);
1230:
1231:                    if (location == null) {
1232:                        if (logger.isEnabledFor(Logger.TRACE))
1233:                            logger
1234:                                    .trace("Logging is not supported by this ModelMBean");
1235:                        return null;
1236:                    }
1237:
1238:                    // It seems that the user wants to delegate a registered mbean to log
1239:                    try {
1240:                        ObjectName objectName = new ObjectName(location);
1241:                        MBeanServer server = getMBeanServer();
1242:                        if (server == null)
1243:                            throw new MBeanException(new IllegalStateException(
1244:                                    "RequiredModelMBean is not registered"));
1245:                        if (server.isRegistered(objectName)) {
1246:                            MBeanLogger l = new MBeanLogger(server, objectName);
1247:                            if (logger.isEnabledFor(Logger.DEBUG))
1248:                                logger
1249:                                        .debug("ModelMBean log supported by delegating to this MBean: "
1250:                                                + objectName);
1251:                            return l;
1252:                        }
1253:
1254:                        return null;
1255:                    } catch (MalformedObjectNameException x) {
1256:                        // Ah, was not a correct object name
1257:                        if (logger.isEnabledFor(Logger.DEBUG))
1258:                            logger
1259:                                    .debug("Specified logMBean field does not contain a valid ObjectName: "
1260:                                            + location);
1261:                        return null;
1262:                    } catch (MBeanException x) {
1263:                        if (logger.isEnabledFor(Logger.DEBUG))
1264:                            logger
1265:                                    .debug(
1266:                                            "logMBean field does not specify an MBean that supports logging delegation",
1267:                                            x);
1268:                        return null;
1269:                    }
1270:                } else {
1271:                    // User decided to log to a file
1272:                    if (logger.isEnabledFor(Logger.DEBUG))
1273:                        logger.debug("ModelMBean log supported on file system");
1274:                    return new FileLogger(location);
1275:                }
1276:            }
1277:
1278:            private NotificationBroadcasterSupport getAttributeChangeBroadcaster() {
1279:                return m_generalBroadcaster;
1280:            }
1281:
1282:            private MBeanServer getMBeanServer() {
1283:                return m_mbeanServer;
1284:            }
1285:
1286:            private ModelMBeanInfo getModelMBeanInfo() {
1287:                // No cloning performed
1288:                return m_modelMBeanInfo;
1289:            }
1290:
1291:            private PersisterMBean findPersister() throws MBeanException,
1292:                    InstanceNotFoundException {
1293:                Logger logger = getLogger();
1294:
1295:                ModelMBeanInfo info = getModelMBeanInfo();
1296:                if (info == null) {
1297:                    // Not yet initialized
1298:                    if (logger.isEnabledFor(Logger.TRACE))
1299:                        logger
1300:                                .trace("Can't find persister, ModelMBeanInfo is null");
1301:                    return null;
1302:                }
1303:                Descriptor mbeanDescriptor = info.getMBeanDescriptor();
1304:                if (mbeanDescriptor == null) {
1305:                    // This is normally should not happen if ModelMBeanInfoSupport is used
1306:                    if (logger.isEnabledFor(Logger.TRACE))
1307:                        logger
1308:                                .trace("Can't find persister, MBean descriptor is null");
1309:                    return null;
1310:                }
1311:
1312:                String location = (String) mbeanDescriptor
1313:                        .getFieldValue("persistLocation");
1314:                String name = (String) mbeanDescriptor
1315:                        .getFieldValue("persistName");
1316:                String mbeanName = (String) mbeanDescriptor
1317:                        .getFieldValue("name");
1318:                if (logger.isEnabledFor(Logger.DEBUG))
1319:                    logger.debug("Persistence fields: location=" + location
1320:                            + ", name=" + name);
1321:
1322:                if (mbeanName == null && name == null) {
1323:                    if (logger.isEnabledFor(Logger.DEBUG))
1324:                        logger
1325:                                .debug("Persistence is not supported by this ModelMBean");
1326:                    return null;
1327:                }
1328:
1329:                // Try to see if this mbean should delegate to another mbean
1330:                if (name != null) {
1331:                    try {
1332:                        ObjectName objectName = new ObjectName(name.trim());
1333:                        // OK, a valid object name
1334:                        MBeanServer server = getMBeanServer();
1335:                        if (server == null)
1336:                            throw new MBeanException(new IllegalStateException(
1337:                                    "RequiredModelMBean is not registered"));
1338:
1339:                        if (server.isRegistered(objectName)
1340:                                && server.isInstanceOf(objectName,
1341:                                        PersisterMBean.class.getName())) {
1342:                            // OK, the given mbean is registered with this mbean server
1343:                            PersisterMBean persister = new MBeanPersister(
1344:                                    server, objectName);
1345:                            if (logger.isEnabledFor(Logger.DEBUG))
1346:                                logger
1347:                                        .debug("Persistence is delegated to this MBean: "
1348:                                                + objectName);
1349:                            return persister;
1350:                        } else {
1351:                            throw new InstanceNotFoundException(objectName
1352:                                    .toString());
1353:                        }
1354:                    } catch (MalformedObjectNameException ignored) {
1355:                        // It does not delegates to another mbean, use default
1356:                        if (logger.isEnabledFor(Logger.TRACE))
1357:                            logger
1358:                                    .trace("Persistence is not delegated to another MBean");
1359:                    }
1360:
1361:                    // Default is serialization to file
1362:                    FilePersister persister = new FilePersister(location, name);
1363:                    if (logger.isEnabledFor(Logger.DEBUG))
1364:                        logger
1365:                                .debug("Persistence is realized through file system in "
1366:                                        + persister.getFileName());
1367:                    return persister;
1368:                } else {
1369:                    // Only location given, use MBean name
1370:                    FilePersister persister = new FilePersister(location,
1371:                            mbeanName);
1372:                    if (logger.isEnabledFor(Logger.DEBUG))
1373:                        logger
1374:                                .debug("Persistence is realized through file system in "
1375:                                        + persister.getFileName());
1376:                    return persister;
1377:                }
1378:            }
1379:
1380:            private Class loadClassWithContextClassLoader(String name) {
1381:                try {
1382:                    return Utils.loadClass(Thread.currentThread()
1383:                            .getContextClassLoader(), name);
1384:                } catch (ClassNotFoundException x) {
1385:                    Logger logger = getLogger();
1386:                    if (logger.isEnabledFor(Logger.TRACE))
1387:                        logger
1388:                                .trace(
1389:                                        "Cannot find attribute's declared return class",
1390:                                        x);
1391:                    return null;
1392:                }
1393:            }
1394:
1395:            private void checkAssignability(Class parameter, Class declared)
1396:                    throws MBeanException {
1397:                Logger logger = getLogger();
1398:
1399:                if (logger.isEnabledFor(Logger.DEBUG)) {
1400:                    logger.debug("The class of the parameter is: " + parameter);
1401:                    if (parameter != null)
1402:                        logger
1403:                                .debug("The classloder of the parameter's class is: "
1404:                                        + parameter.getClassLoader());
1405:                    logger
1406:                            .debug("The class declared as type of the attribute is: "
1407:                                    + declared);
1408:                    if (declared != null)
1409:                        logger
1410:                                .debug("The classloader of the declared parameter's class is: "
1411:                                        + declared.getClassLoader());
1412:                }
1413:
1414:                boolean assignable = false;
1415:
1416:                if (declared == null || parameter == null)
1417:                    assignable = false;
1418:                else if (declared == boolean.class
1419:                        && parameter == Boolean.class)
1420:                    assignable = true;
1421:                else if (declared == byte.class && parameter == Byte.class)
1422:                    assignable = true;
1423:                else if (declared == char.class && parameter == Character.class)
1424:                    assignable = true;
1425:                else if (declared == short.class && parameter == Short.class)
1426:                    assignable = true;
1427:                else if (declared == int.class && parameter == Integer.class)
1428:                    assignable = true;
1429:                else if (declared == long.class && parameter == Long.class)
1430:                    assignable = true;
1431:                else if (declared == float.class && parameter == Float.class)
1432:                    assignable = true;
1433:                else if (declared == double.class && parameter == Double.class)
1434:                    assignable = true;
1435:                else
1436:                    assignable = declared.isAssignableFrom(parameter);
1437:
1438:                if (!assignable) {
1439:                    if (logger.isEnabledFor(Logger.TRACE))
1440:                        logger
1441:                                .trace("Parameter value's class and attribute's declared return class are not assignable");
1442:                    throw new MBeanException(
1443:                            new InvalidAttributeValueException(
1444:                                    "Returned type and declared type are not assignable"));
1445:                }
1446:            }
1447:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.