001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package javax.management.modelmbean;
010:
011: import java.lang.reflect.Method;
012: import javax.management.Descriptor;
013: import javax.management.DescriptorAccess;
014: import javax.management.MBeanOperationInfo;
015: import javax.management.MBeanParameterInfo;
016: import javax.management.RuntimeOperationsException;
017:
018: /**
019: * @version $Revision: 1.11 $
020: */
021: public class ModelMBeanOperationInfo extends MBeanOperationInfo
022: implements DescriptorAccess {
023: private static final long serialVersionUID = 6532732096650090465L;
024:
025: private Descriptor operationDescriptor;
026:
027: public ModelMBeanOperationInfo(String description, Method method) {
028: this (description, method, null);
029: }
030:
031: public ModelMBeanOperationInfo(String description, Method method,
032: Descriptor descriptor) {
033: super (description, method);
034: checkAndSetDescriptor(descriptor);
035: }
036:
037: public ModelMBeanOperationInfo(String name, String description,
038: MBeanParameterInfo[] params, String type, int impact) {
039: this (name, description, params, type, impact, null);
040: }
041:
042: public ModelMBeanOperationInfo(String name, String description,
043: MBeanParameterInfo[] params, String type, int impact,
044: Descriptor descriptor) {
045: super (name, description, params, type, impact);
046: checkAndSetDescriptor(descriptor);
047: }
048:
049: public ModelMBeanOperationInfo(ModelMBeanOperationInfo copy) {
050: super (copy.getName(), copy.getDescription(), copy
051: .getSignature(), copy.getReturnType(), copy.getImpact());
052: checkAndSetDescriptor(copy.getDescriptor());
053: }
054:
055: public Object clone() {
056: return new ModelMBeanOperationInfo(this );
057: }
058:
059: public Descriptor getDescriptor() {
060: return (Descriptor) operationDescriptor.clone();
061: }
062:
063: public void setDescriptor(Descriptor descriptor) {
064: if (descriptor == null) {
065: operationDescriptor = createDefaultDescriptor();
066: } else {
067: if (isDescriptorValid(descriptor)) {
068: operationDescriptor = (Descriptor) descriptor.clone();
069: } else {
070: // Not sure what to do here: javadoc says IllegalArgument, but for example ModelMBeanInfo throws RuntimeOperations
071: // which is consistent with the fact that all exception thrown by the JMX implementation should be JMX exceptions
072: // throw new IllegalArgumentException("Invalid descriptor");
073: throw new RuntimeOperationsException(
074: new IllegalArgumentException(
075: "Invalid descriptor"));
076: }
077: }
078: }
079:
080: private void checkAndSetDescriptor(Descriptor descriptor) {
081: if (descriptor == null) {
082: operationDescriptor = createDefaultDescriptor();
083: } else if (isDescriptorValid(descriptor)) {
084: operationDescriptor = (Descriptor) descriptor.clone();
085: if (operationDescriptor.getFieldValue("displayName") == null) {
086: operationDescriptor.setField("displayName", getName());
087: }
088: } else {
089: throw new RuntimeOperationsException(
090: new IllegalArgumentException("Invalid Descriptor"));
091: }
092: }
093:
094: private boolean isDescriptorValid(Descriptor descriptor) {
095: if (!descriptor.isValid()) {
096: return false;
097: }
098:
099: // Spec compliance checks
100:
101: // Mandatory fields are: name, descriptorType, role, lastReturnedTimeStamp(?)
102: String[] names = descriptor.getFieldNames();
103:
104: if (!ModelMBeanInfoSupport.containsIgnoreCase(names, "name")
105: || !ModelMBeanInfoSupport.containsIgnoreCase(names,
106: "descriptortype")
107: || !ModelMBeanInfoSupport.containsIgnoreCase(names,
108: "role")) {
109: return false;
110: }
111: // Case sensitive name
112: String name = getName();
113: if (name == null) {
114: return false;
115: }
116: if (!name.equals(descriptor.getFieldValue("name"))) {
117: return false;
118: }
119: // Descriptor type must be 'operation'
120: String desctype = (String) descriptor
121: .getFieldValue("descriptortype");
122: if (desctype.compareToIgnoreCase("operation") != 0)
123: return false;
124: // Role must be 'getter' or 'setter' or 'operation'
125: if (!"getter".equals(descriptor.getFieldValue("role"))
126: && !"setter".equals(descriptor.getFieldValue("role"))
127: && !"operation"
128: .equals(descriptor.getFieldValue("role"))) {
129: return false;
130: }
131:
132: return true;
133: }
134:
135: private Descriptor createDefaultDescriptor() {
136: String[] names = new String[] { "name", "descriptorType",
137: "role", "displayName"/*, "lastReturnedTimeStamp"*/};
138: Object[] values = new Object[] { getName(), "operation",
139: "operation", getName() /*, "0"*/};
140: return new DescriptorSupport(names, values);
141: }
142: }
|