1 /*
   2  * Copyright (c)  2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <jni.h>
  27 #include "management.h"
  28 #include "sun_management_DiagnosticCommandImpl.h"
  29 
  30 JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
  31 (JNIEnv *env, jobject dummy, jboolean enabled) {
  32     if(jmm_version > JMM_VERSION_1_2_2) {
  33         jmm_interface->SetDiagnosticFrameworkNotificationEnabled(env, enabled);
  34     } else {
  35         JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
  36                         "JMX interface to diagnostic framework notifications is not supported by this VM");
  37     }
  38 }
  39 
  40 JNIEXPORT jobjectArray JNICALL
  41 Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands
  42   (JNIEnv *env, jobject dummy)
  43 {
  44   return jmm_interface->GetDiagnosticCommands(env);
  45 }
  46 
  47 jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
  48                                               int num_arg) {
  49   int i;
  50   jobject obj;
  51   jobjectArray result;
  52   dcmdArgInfo* dcmd_arg_info_array;
  53   jclass dcmdArgInfoCls;
  54   jclass arraysCls;
  55   jmethodID mid;
  56   jobject resultList;
  57 
  58   dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
  59   if (dcmd_arg_info_array == NULL) {
  60     return NULL;
  61   }
  62   jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
  63                                                    dcmd_arg_info_array);
  64   dcmdArgInfoCls = (*env)->FindClass(env,
  65                                      "sun/management/DiagnosticCommandArgumentInfo");
  66   result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
  67   if (result == NULL) {
  68     free(dcmd_arg_info_array);
  69     return NULL;
  70   }
  71   for (i=0; i<num_arg; i++) {
  72     obj = JNU_NewObjectByName(env,
  73                               "sun/management/DiagnosticCommandArgumentInfo",
  74                               "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V",
  75                               (*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
  76                               (*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
  77                               (*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
  78                               dcmd_arg_info_array[i].default_string == NULL ? NULL:
  79                               (*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
  80                               dcmd_arg_info_array[i].mandatory,
  81                               dcmd_arg_info_array[i].option,
  82                               dcmd_arg_info_array[i].multiple,
  83                               dcmd_arg_info_array[i].position);
  84     if (obj == NULL) {
  85       free(dcmd_arg_info_array);
  86       return NULL;
  87     }
  88     (*env)->SetObjectArrayElement(env, result, i, obj);
  89   }
  90   free(dcmd_arg_info_array);
  91   arraysCls = (*env)->FindClass(env, "java/util/Arrays");
  92   mid = (*env)->GetStaticMethodID(env, arraysCls,
  93                                   "asList", "([Ljava/lang/Object;)Ljava/util/List;");
  94   resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
  95   return resultList;
  96 }
  97 
  98 /* Throws IllegalArgumentException if at least one of the diagnostic command
  99  * passed in argument is not supported by the JVM
 100  */
 101 JNIEXPORT jobjectArray JNICALL
 102 Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo
 103 (JNIEnv *env, jobject dummy, jobjectArray commands)
 104 {
 105   int i;
 106   jclass dcmdInfoCls;
 107   jobject result;
 108   jobjectArray args;
 109   jobject obj;
 110   jmmOptionalSupport mos;
 111   jint ret = jmm_interface->GetOptionalSupport(env, &mos);
 112   jsize num_commands;
 113   dcmdInfo* dcmd_info_array;
 114 
 115   if (commands == NULL) {
 116       JNU_ThrowNullPointerException(env, "Invalid String Array");
 117       return NULL;
 118   }
 119   num_commands = (*env)->GetArrayLength(env, commands);
 120   dcmd_info_array = (dcmdInfo*) malloc(num_commands *
 121                                        sizeof(dcmdInfo));
 122   if (dcmd_info_array == NULL) {
 123       JNU_ThrowOutOfMemoryError(env, NULL);
 124   }
 125   jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
 126   dcmdInfoCls = (*env)->FindClass(env,
 127                                   "sun/management/DiagnosticCommandInfo");
 128   result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
 129   if (result == NULL) {
 130       free(dcmd_info_array);
 131       JNU_ThrowOutOfMemoryError(env, 0);
 132   }
 133   for (i=0; i<num_commands; i++) {
 134       args = getDiagnosticCommandArgumentInfoArray(env,
 135                                                    (*env)->GetObjectArrayElement(env,commands,i),
 136                                                    dcmd_info_array[i].num_arguments);
 137       if (args == NULL) {
 138           free(dcmd_info_array);
 139           JNU_ThrowOutOfMemoryError(env, 0);
 140       }
 141       obj = JNU_NewObjectByName(env,
 142                                 "sun/management/DiagnosticCommandInfo",
 143                                 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
 144                                 (*env)->NewStringUTF(env,dcmd_info_array[i].name),
 145                                 (*env)->NewStringUTF(env,dcmd_info_array[i].description),
 146                                 (*env)->NewStringUTF(env,dcmd_info_array[i].impact),
 147                                 dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
 148                                 dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
 149                                 dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
 150                                 dcmd_info_array[i].enabled,
 151                                 args);
 152       if (obj == NULL) {
 153           free(dcmd_info_array);
 154           JNU_ThrowOutOfMemoryError(env, 0);
 155       }
 156       (*env)->SetObjectArrayElement(env, result, i, obj);
 157   }
 158   free(dcmd_info_array);
 159   return result;
 160 }
 161 
 162 /* Throws IllegalArgumentException if the diagnostic command
 163  * passed in argument is not supported by the JVM
 164  */
 165 JNIEXPORT jstring JNICALL
 166 Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand
 167 (JNIEnv *env, jobject dummy, jstring command) {
 168   return jmm_interface->ExecuteDiagnosticCommand(env, command);
 169 }