001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package javax.management;
023:
024: import java.lang.reflect.Method;
025: import java.io.Serializable;
026: import java.util.Arrays;
027:
028: import org.jboss.mx.util.MetaDataUtil;
029:
030: /**
031: * Describes an operation exposed by an MBean
032: *
033: * This implementation protects its immutability by taking shallow clones of all arrays
034: * supplied in constructors and by returning shallow array clones in getXXX() methods.
035: *
036: * @author <a href="mailto:juha@jboss.org">Juha Lindfors</a>.
037: * @author <a href="mailto:trevor@protocool.com">Trevor Squires</a>.
038: * @author <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>
039: * @author <a href="mailto:thomas.diesler@jboss.com">Thomas Diesler</a>.
040: *
041: * @version $Revision: 57200 $
042: */
043: public class MBeanOperationInfo extends MBeanFeatureInfo implements
044: Serializable, Cloneable {
045:
046: // Constants -----------------------------------------------------
047:
048: private static final long serialVersionUID = -6178860474881375330L;
049:
050: /**
051: * Management operation impact: INFO. The operation should not alter the
052: * state of the MBean component (read operation).
053: */
054: public static final int INFO = 0;
055:
056: /**
057: * Management operation impact: ACTION. The operation changes the state
058: * of the MBean component (write operation).
059: */
060: public static final int ACTION = 1;
061:
062: /**
063: * Management operation impact: ACTION_INFO. Operation behaves like a
064: * read/write operation.
065: */
066: public static final int ACTION_INFO = 2;
067:
068: /**
069: * Management operation impact: UNKNOWN. Reserved for Standard MBeans.
070: */
071: public static final int UNKNOWN = 3;
072:
073: // Attributes ----------------------------------------------------
074:
075: /**
076: * Impact of this operation.
077: */
078: private int impact = UNKNOWN;
079:
080: /**
081: * Signature of this operation.
082: */
083: private MBeanParameterInfo[] signature = null;
084:
085: /**
086: * Return type of this operation as a fully qualified class name.
087: */
088: private String type = null;
089:
090: /**
091: * The cached string
092: */
093: private transient String cacheString;
094:
095: /**
096: * The cached hashCode
097: */
098: private transient int cacheHashCode;
099:
100: // Constructors --------------------------------------------------
101:
102: /**
103: * Constructs management operation metadata from a given <tt>Method</tt>
104: * object and description.
105: *
106: * @param description human readable description of this operation
107: * @param method used for build the metadata for the management operation
108: */
109: public MBeanOperationInfo(String description, Method method)
110: throws IllegalArgumentException {
111: super (method.getName(), description);
112: this .type = method.getReturnType().getName();
113:
114: Class[] sign = method.getParameterTypes();
115: signature = new MBeanParameterInfo[sign.length];
116:
117: for (int i = 0; i < sign.length; ++i) {
118: String name = sign[i].getName();
119: signature[i] = new MBeanParameterInfo(name, name,
120: "MBean Operation Parameter.");
121: }
122: }
123:
124: /**
125: * Constructs a management operation metadata.
126: *
127: * @param name name of the management operation
128: * @param description human readable description string of the operation
129: * @param inSignature inSignature of the operation
130: * @param returnType return type of the operation as a fully qualified class name
131: * @param impact impact of this operation: {@link #ACTION ACTION}, {@link #INFO INFO}, {@link #ACTION_INFO ACTION_INFO} or {@link #UNKNOWN UNKNOWN}
132: * @exception IllegalArgumentException if the name or return type is not a valid java identifier or it is a reserved word
133: * or the impact is invalid
134: */
135: public MBeanOperationInfo(String name, String description,
136: MBeanParameterInfo[] inSignature, String returnType,
137: int impact) throws IllegalArgumentException {
138: super (name, description);
139: if (MetaDataUtil.isValidJavaType(returnType) == false)
140: throw new IllegalArgumentException(
141: "Return type is not a valid java identifier (or is reserved): "
142: + returnType);
143: if (impact != INFO && impact != ACTION && impact != ACTION_INFO
144: && impact != UNKNOWN)
145: throw new IllegalArgumentException("Impact is invalid: "
146: + impact);
147:
148: this .signature = (null == inSignature) ? new MBeanParameterInfo[0]
149: : (MBeanParameterInfo[]) inSignature.clone();
150: this .type = returnType;
151: this .impact = impact;
152: }
153:
154: // Public --------------------------------------------------------
155:
156: /**
157: * Returns a fully qualified class name of the return type of this operation.
158: *
159: * @return fully qualified class name
160: */
161: public String getReturnType() {
162: return type;
163: }
164:
165: /**
166: * Returns the signature of this operation. <b>Note:</b> an operation with a void
167: * signature returns a zero-length array, not a <tt>null</tt> reference.
168: *
169: * @return operation's signature
170: */
171: public MBeanParameterInfo[] getSignature() {
172: return (MBeanParameterInfo[]) signature.clone();
173: }
174:
175: /**
176: * Returns the impact of this operation. The impact is one of the following values:
177: * {@link #ACTION ACTION}, {@link #INFO INFO}, {@link #ACTION_INFO ACTION_INFO} or {@link #UNKNOWN UNKNOWN} (reserved for Standard MBeans).
178: *
179: * @return operation's impact
180: */
181: public int getImpact() {
182: return impact;
183: }
184:
185: public boolean equals(Object object) {
186: if (this == object)
187: return true;
188: if (object == null
189: || (object instanceof MBeanOperationInfo) == false)
190: return false;
191:
192: MBeanOperationInfo other = (MBeanOperationInfo) object;
193:
194: if (super .equals(other) == false)
195: return false;
196: if (this .getReturnType().equals(other.getReturnType()) == false)
197: return false;
198: if (this .getImpact() != other.getImpact())
199: return false;
200:
201: MBeanParameterInfo[] this Params = this .getSignature();
202: MBeanParameterInfo[] otherParams = other.getSignature();
203: if (this Params.length != otherParams.length)
204: return false;
205: for (int i = 0; i < this Params.length; ++i)
206: if (this Params[i].equals(otherParams[i]) == false)
207: return false;
208:
209: return true;
210: }
211:
212: public int hashCode() {
213: if (cacheHashCode == 0) {
214: cacheHashCode = super .hashCode();
215: cacheHashCode += getReturnType().hashCode();
216: cacheHashCode += impact;
217: }
218: return cacheHashCode;
219: }
220:
221: /**
222: * @return a human readable string
223: */
224: public String toString() {
225: if (cacheString == null) {
226: StringBuffer buffer = new StringBuffer(100);
227: buffer.append(getClass().getName()).append(":");
228: buffer.append(" name=").append(getName());
229: buffer.append(" description=").append(getDescription());
230: buffer.append(" signature=").append(
231: Arrays.asList(signature));
232: buffer.append(" returnType=").append(getReturnType());
233: buffer.append(" impact=");
234: switch (impact) {
235: case ACTION:
236: buffer.append("ACTION");
237: break;
238: case ACTION_INFO:
239: buffer.append("ACTION_INFO");
240: break;
241: case INFO:
242: buffer.append("INFO");
243: break;
244: default:
245: buffer.append("UNKNOWN");
246: }
247: cacheString = buffer.toString();
248: }
249: return cacheString;
250: }
251:
252: // Cloneable implementation --------------------------------------
253: /**
254: * Creates a copy of this object. This is a deep copy; the <tt>MBeanParameterInfo</tt> objects
255: * forming the operation's signature are also cloned.
256: *
257: * @return a clone of this object
258: */
259: public synchronized Object clone() {
260: MBeanOperationInfo clone = null;
261: try {
262: clone = (MBeanOperationInfo) super .clone();
263: clone.signature = (MBeanParameterInfo[]) this .signature
264: .clone();
265: clone.type = this .type;
266: clone.impact = this .impact;
267: } catch (CloneNotSupportedException e) {
268: }
269:
270: return clone;
271: }
272: }
|