001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005: package com.sun.portal.admin.cli.commands.monitoring;
006:
007: import com.sun.enterprise.cli.framework.CommandValidationException;
008: import com.sun.enterprise.cli.framework.CommandException;
009: import com.sun.enterprise.cli.framework.CLILogger;
010:
011: import javax.management.*;
012: import javax.management.openmbean.*;
013: import java.util.*;
014: import java.lang.reflect.Array;
015: import java.io.IOException;
016:
017: public class InvokeMonitoringOperation extends MonitoringBaseCommand {
018: private class CLIInput {
019: public boolean interactive = false;
020: public String nameProperties = null;
021: public String objectName = null;
022: public String type = null;
023: public boolean verbose = false;
024:
025: public String operandValues[];
026:
027: CLIInput() {
028: interactive = getBooleanOption(CLI_OPTION_INTERACTIVE);
029: nameProperties = getOption(CLI_OPTION_NAME_PROPERTIES);
030: objectName = getOption(CLI_OPTION_OBJECT_NAME);
031: type = getOption(CLI_OPTION_TYPE);
032: verbose = getBooleanOption(CLI_OPTION_VERBOSE);
033:
034: operandValues = getOperandValues();
035: }
036: }
037:
038: private Object getArgument(String argType, String argValue) {
039: Object result = null;
040: if (argType.startsWith("[")) {
041: ; // not supported. better write your own program to invoke what you want to invoke.
042: } else if (argType
043: .equals("javax.management.openmbean.CompositeData")) {
044: ; // not supported. better write your own program to invoke what you want to invoke.
045: } else if (argType
046: .equals("javax.management.openmbean.TabularData")) {
047: ; // not supported. better write your own program to invoke what you want to invoke.
048: } else {
049: if (argType.equals(boolean.class.getName())
050: || (argType.equals(Boolean.class.getName()))) {
051: result = Boolean.getBoolean(argValue) ? Boolean.TRUE
052: : Boolean.FALSE;
053: } else if (argType.equals(byte.class.getName())
054: || argType.equals(Byte.class.getName())) {
055: result = new Byte(Byte.parseByte(argValue));
056: } else if (argType.equals(char.class.getName())
057: || argType.equals(Character.class.getName())) {
058: result = new Character(argValue.charAt(0));
059: } else if (argType.equals(double.class.getName())
060: || argType.equals(Double.class.getName())) {
061: result = new Double(Double.parseDouble(argValue));
062: } else if (argType.equals(float.class.getName())
063: || argType.equals(Float.class.getName())) {
064: result = new Float(Float.parseFloat(argValue));
065: } else if (argType.equals(int.class.getName())
066: || argType.equals(Integer.class.getName())) {
067: result = new Integer(Integer.parseInt(argValue));
068: } else if (argType.equals(long.class.getName())
069: || argType.equals(Long.class.getName())) {
070: result = new Long(Long.parseLong(argValue));
071: } else if (argType.equals(short.class.getName())
072: || argType.equals(Short.class.getName())) {
073: result = new Short(Short.parseShort(argValue));
074: } else {
075: result = argValue; // assuming String
076: }
077: }
078:
079: return result;
080: }
081:
082: private Map getAttributeNameValues(String attributeNamePrefix,
083: Object array) {
084: Map result = new TreeMap();
085:
086: int arrayLength = 0;
087: try {
088: arrayLength = Array.getLength(array);
089: } catch (IllegalArgumentException t) {
090: result.put(attributeNamePrefix, array);
091: return result;
092: }
093:
094: for (int j = 0; j < arrayLength; j++) {
095: result.putAll(getAttributeNameValues(attributeNamePrefix
096: + "." + j, Array.get(array, j)));
097: }
098:
099: return result;
100: }
101:
102: private Map getAttributeNameValues(String attributeName,
103: int dimension, Object array, Class arrayElementType) {
104: Map result = new TreeMap();
105:
106: int[] dimensions = new int[dimension];
107: Object[] arrayObjects = new Object[dimension];
108:
109: try {
110: dimensions[0] = Array.getLength(array);
111: arrayObjects[0] = Array.get(array, 0);
112: for (int i = 1; i < dimension; i++) {
113: dimensions[i] = Array.getLength(arrayObjects[i - 1]);
114: arrayObjects[i] = Array.get(arrayObjects[i - 1], 0);
115: }
116:
117: Object arrayInner = Array.newInstance(arrayElementType,
118: dimensions);
119: arrayInner = array;
120:
121: for (int i = 0; i < dimensions[0]; i++) {
122: result.putAll(getAttributeNameValues(attributeName
123: + "." + i, Array.get(arrayInner, i)));
124: }
125:
126: return result;
127: } catch (ArrayIndexOutOfBoundsException aiobe) {
128: }
129:
130: return result;
131: }
132:
133: private Map getAttributeNameValues(String attributeName,
134: CompositeData compositeData) {
135: Map result = new TreeMap();
136:
137: CompositeType compositeType = compositeData.getCompositeType();
138: Set itemNames = compositeType.keySet();
139: for (Iterator iterator = itemNames.iterator(); iterator
140: .hasNext();) {
141: String itemName = (String) iterator.next();
142: OpenType itemType = compositeType.getType(itemName);
143: Object itemValue = compositeData.get(itemName);
144:
145: String attributeName2 = (attributeName.length() == 0) ? ""
146: : attributeName + "." + itemName;
147: if (itemType instanceof ArrayType) {
148: ArrayType arrayType = (ArrayType) itemType;
149:
150: int dimension = arrayType.getDimension();
151: String className = arrayType.getClassName();
152: String elementType = className.substring(dimension,
153: dimension + 1);
154: if (elementType.equals("B")) {
155: } else if (elementType.equals("C")) {
156: } else if (elementType.equals("D")) {
157: } else if (elementType.equals("F")) {
158: } else if (elementType.equals("I")) {
159: } else if (elementType.equals("J")) {
160: } else if (elementType.equals("L")) {
161: try {
162: Class arrayElementClass = Class
163: .forName(className);
164: result.putAll(getAttributeNameValues(
165: attributeName2, dimension, itemValue,
166: arrayElementClass));
167: } catch (ClassNotFoundException cnfe) {
168: result.putAll(getAttributeNameValues(
169: attributeName2, dimension, itemValue,
170: Object.class));
171: }
172: } else if (elementType.equals("S")) {
173: } else if (elementType.equals("Z")) {
174: } else {
175: }
176: } else if (itemType instanceof CompositeType) {
177: result.putAll(getAttributeNameValues(attributeName2,
178: (CompositeData) itemValue));
179: } else if (itemType instanceof SimpleType) {
180: result.put(itemName, itemValue);
181: } else if (itemType instanceof TabularType) {
182: result.putAll(getAttributeNameValues(itemName,
183: (TabularData) itemValue));
184: }
185: }
186:
187: return result;
188: }
189:
190: private String getKeyValuesPrefix(OpenType openType, Object value) {
191: if (openType instanceof ArrayType) {
192: return "ArrayTypeKey"; // not supported, doesn't make sense
193: } else if (openType instanceof CompositeType) {
194: return "CompositeTypeKey"; // not supported, doesn't make sense
195: } else if (openType instanceof SimpleType) {
196: return value.toString();
197: } else if (openType instanceof TabularType) {
198: return "TabularTypeKey"; // not supported, doesn't make sense
199: }
200:
201: return "UnknownOpenType"; // should not reach here
202: }
203:
204: private String getKeyValuesPrefix(List indexNames,
205: CompositeData compositeData) {
206: StringBuffer result = new StringBuffer();
207: for (Iterator iterator = indexNames.iterator(); iterator
208: .hasNext();) {
209: String itemName = (String) iterator.next();
210:
211: Object itemValue = compositeData.get(itemName);
212: OpenType itemType = compositeData.getCompositeType()
213: .getType(itemName);
214:
215: result.append(".").append(
216: getKeyValuesPrefix(itemType, itemValue));
217: }
218:
219: return result.toString();
220: }
221:
222: private Map getAttributeNameValues(String attributeName,
223: TabularData tabularData) {
224: Map result = new TreeMap();
225:
226: TabularType tabularType = tabularData.getTabularType();
227: List indexNames = tabularType.getIndexNames();
228: Collection rows = tabularData.values();
229: for (Iterator iterator = rows.iterator(); iterator.hasNext();) {
230: CompositeData row = (CompositeData) iterator.next();
231: result.putAll(getAttributeNameValues(attributeName
232: + getKeyValuesPrefix(indexNames, row), row));
233: }
234:
235: return result;
236: }
237:
238: private Map mapResult(String resultType, Object resultValue) {
239: Map result = new TreeMap();
240: if (resultType.startsWith("[")) {
241: int dimension = resultType.lastIndexOf("[") + 1;
242:
243: String elementType = resultType.substring(dimension,
244: dimension + 1);
245: if (elementType.equals("B")) {
246: } else if (elementType.equals("C")) {
247: } else if (elementType.equals("D")) {
248: } else if (elementType.equals("F")) {
249: } else if (elementType.equals("I")) {
250: } else if (elementType.equals("J")) {
251: } else if (elementType.equals("L")) {
252: String arrayElementType = resultType.substring(
253: dimension + 1, resultType.length()
254: - ";".length());
255: try {
256: Class arrayElementClass = Class
257: .forName(arrayElementType);
258: result.putAll(getAttributeNameValues("", dimension,
259: resultValue, arrayElementClass));
260: } catch (ClassNotFoundException cnfe) {
261: result.putAll(getAttributeNameValues("", dimension,
262: resultValue, Object.class));
263: }
264: } else if (elementType.equals("S")) {
265: } else if (elementType.equals("Z")) {
266: } else {
267: }
268: } else if (resultType
269: .equals("javax.management.openmbean.CompositeData")) {
270: result.putAll(getAttributeNameValues("",
271: (CompositeData) resultValue));
272: } else if (resultType
273: .equals("javax.management.openmbean.TabularData")) {
274: result.putAll(getAttributeNameValues("",
275: (TabularData) resultValue));
276: } else {
277: result.put("", resultValue);
278: }
279:
280: return result;
281: }
282:
283: private Object invokeMBeanOperation(ObjectName on,
284: String operationName, String[] operandValues)
285: throws NoSuchMethodException, CommandException {
286: Object result = null;
287:
288: MBeanInfo mBeanInfo = null;
289: try {
290: mBeanInfo = getCommandClient().getMBeanInfo(on);
291: } catch (ReflectionException e) {
292: throwError(e);
293: } catch (IOException e) {
294: throwError(e);
295: } catch (InstanceNotFoundException e) {
296: throwError(e);
297: } catch (MBeanException e) {
298: throwError(e);
299: }
300: MBeanOperationInfo[] mBeanOperationInfos = mBeanInfo
301: .getOperations();
302:
303: if (mBeanOperationInfos == null) {
304: throw new NoSuchMethodException();
305: }
306:
307: if (mBeanOperationInfos.length == 0) {
308: throw new NoSuchMethodException();
309: }
310:
311: Boolean invoked = Boolean.FALSE;
312: for (int i = 0; i < mBeanOperationInfos.length; i++) {
313: MBeanOperationInfo mBeanOperationInfo = mBeanOperationInfos[i];
314: if (mBeanOperationInfo.getName().equals(operationName)) {
315: MBeanParameterInfo[] mBeanParameterInfos = mBeanOperationInfo
316: .getSignature();
317: if (mBeanParameterInfos == null) {
318: try {
319: result = getCommandClient().invoke(on,
320: operationName, null, null);
321: } catch (ReflectionException e) {
322: throwError(e);
323: } catch (IOException e) {
324: throwError(e);
325: } catch (InstanceNotFoundException e) {
326: throwError(e);
327: } catch (MBeanException e) {
328: throwError(e);
329: }
330: invoked = Boolean.TRUE;
331: } else if (mBeanParameterInfos.length == 0) {
332: try {
333: result = getCommandClient().invoke(on,
334: operationName, null, null);
335: } catch (ReflectionException e) {
336: throwError(e);
337: } catch (IOException e) {
338: throwError(e);
339: } catch (InstanceNotFoundException e) {
340: throwError(e);
341: } catch (MBeanException e) {
342: throwError(e);
343: }
344: invoked = Boolean.TRUE;
345: } else {
346: if (mBeanParameterInfos.length != (operandValues.length - 1)) {
347: continue;
348: }
349:
350: String[] argTypes = new String[mBeanParameterInfos.length];
351: Object[] argValues = new Object[mBeanParameterInfos.length];
352: Boolean canInvoke = Boolean.TRUE;
353: for (int j = 0; j < mBeanParameterInfos.length; j++) {
354: MBeanParameterInfo mBeanParameterInfo = mBeanParameterInfos[j];
355: argTypes[j] = mBeanParameterInfo.getType();
356: argValues[j] = getArgument(argTypes[j],
357: operandValues[j + 1]);
358:
359: if (argValues[j] == null) {
360: canInvoke = Boolean.FALSE;
361: break;
362: }
363: }
364:
365: if (canInvoke.booleanValue()) {
366: try {
367: result = getCommandClient().invoke(on,
368: operationName, argValues, argTypes);
369: } catch (ReflectionException e) {
370: throwError(e);
371: } catch (IOException e) {
372: throwError(e);
373: } catch (InstanceNotFoundException e) {
374: throwError(e);
375: } catch (MBeanException e) {
376: throwError(e);
377: }
378:
379: Map nameValues = mapResult(mBeanOperationInfo
380: .getReturnType(), result);
381: Set names = nameValues.keySet();
382:
383: StringBuffer sb = new StringBuffer();
384: for (Iterator iterator2 = names.iterator(); iterator2
385: .hasNext();) {
386: String name = (String) iterator2.next();
387: sb.append(
388: name + EQUAL_TO
389: + nameValues.get(name))
390: .append(LINE_SEPARATOR);
391: }
392: result = sb;
393:
394: invoked = Boolean.TRUE;
395: break;
396: }
397: }
398: }
399: }
400:
401: if (!invoked.booleanValue()) {
402: throw new NoSuchMethodException();
403: }
404:
405: return result;
406: }
407:
408: private String invokeMBeanOperation(CLIInput cliInput)
409: throws CommandException {
410: StringBuffer sb = new StringBuffer();
411:
412: ObjectName onPattern = getObjectNamePattern(
413: cliInput.objectName, cliInput.type,
414: cliInput.nameProperties);
415: if (cliInput.verbose) {
416: CLILogger.getInstance().printMessage(
417: getMessage(
418: QUERYING_MBEAN_OBJECT_NAMES_WITH_PATTERN,
419: new Object[] { onPattern }));
420: }
421:
422: Set objectNames = null;
423: try {
424: objectNames = getCommandClient()
425: .queryNames(onPattern, null);
426: } catch (ReflectionException e) {
427: throwError(e);
428: } catch (IOException e) {
429: throwError(e);
430: } catch (InstanceNotFoundException e) {
431: throwError(e);
432: } catch (MBeanException e) {
433: throwError(e);
434: }
435:
436: if (objectNames.isEmpty()) {
437: sb.append(getMessage(NO_MBEANS_FOUND, null));
438: } else {
439: Iterator iterator = objectNames.iterator();
440: ObjectName on = null;
441: while (iterator.hasNext()) {
442: on = (ObjectName) iterator.next();
443: if (cliInput.interactive) {
444: if (!voteForContinue(on).booleanValue()) {
445: continue;
446: }
447: }
448:
449: if (sb.length() != 0) {
450: sb.append(LINE_SEPARATOR);
451: }
452: sb.append(on);
453:
454: try {
455: Object result = invokeMBeanOperation(on,
456: cliInput.operandValues[0],
457: cliInput.operandValues);
458: sb
459: .append(LINE_SEPARATOR)
460: .append(TAB)
461: .append(
462: getMessage(
463: INVOKE_MBEAN_OPERATION_RETURN_VALUE,
464: new Object[] { result }));
465: } catch (NoSuchMethodException e) {
466: sb
467: .append(LINE_SEPARATOR)
468: .append(TAB)
469: .append(
470: getMessage(
471: INVOKE_MBEAN_OPERATION_NOT_SUPPORTED,
472: null));
473: }
474: }
475: }
476:
477: return sb.toString();
478: }
479:
480: private void printCLIInput(CLIInput cliInput) {
481: if (cliInput.verbose) {
482: CLILogger.getInstance().printMessage(
483: getMessage(MBEAN_OBJECT_NAME_PATTERN,
484: new Object[] { cliInput.objectName }));
485: CLILogger.getInstance().printMessage(
486: getMessage(MBEAN_TYPE,
487: new Object[] { cliInput.type }));
488: CLILogger.getInstance().printMessage(
489: getMessage(MBEAN_NAME_PROPERTIES,
490: new Object[] { cliInput.nameProperties }));
491: }
492: }
493:
494: public void runCommand() throws CommandValidationException,
495: CommandException {
496: CLIInput cliInput = null;
497: Boolean connected = Boolean.FALSE;
498:
499: try {
500: gearUp();
501:
502: cliInput = new CLIInput();
503: printCLIInput(cliInput);
504:
505: connect(cliInput.verbose);
506: connected = Boolean.TRUE;
507:
508: String output = invokeMBeanOperation(cliInput);
509: CLILogger.getInstance().printMessage(output);
510: } finally {
511: if (connected.booleanValue()) {
512: disconnect(cliInput.verbose);
513: }
514: }
515: }
516: }
|