1 /*
   2  * Copyright (c) 2005, 2011, 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 package sun.management;
  27 
  28 import java.io.IOException;
  29 import java.util.ArrayList;
  30 import java.util.Arrays;
  31 import java.util.Collections;
  32 import java.util.List;
  33 import javax.management.ObjectName;
  34 
  35 import com.sun.management.DiagnosticCommandInfo;
  36 import com.sun.management.DiagnosticCommandArgumentInfo;
  37 import com.sun.management.HotSpotDiagnosticMXBean;
  38 import com.sun.management.VMOption;
  39 
  40 /**
  41  * Implementation of the diagnostic MBean for Hotspot VM.
  42  */
  43 public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
  44     public HotSpotDiagnostic() {
  45     }
  46 
  47     public native void dumpHeap(String outputFile, boolean live) throws IOException;
  48 
  49     public List<VMOption> getDiagnosticOptions() {
  50         List<Flag> allFlags = Flag.getAllFlags();
  51         List<VMOption> result = new ArrayList<VMOption>();
  52         for (Flag flag : allFlags) {
  53             if (flag.isWriteable() && flag.isExternal()) {
  54                 result.add(flag.getVMOption());
  55             }
  56         }
  57         return result;
  58     }
  59 
  60     public VMOption getVMOption(String name) {
  61         if (name == null) {
  62             throw new NullPointerException("name cannot be null");
  63         }
  64 
  65         Flag f = Flag.getFlag(name);
  66         if (f == null) {
  67             throw new IllegalArgumentException("VM option \"" +
  68                 name + "\" does not exist");
  69         }
  70         return f.getVMOption();
  71     }
  72 
  73     public void setVMOption(String name, String value) {
  74         if (name == null) {
  75             throw new NullPointerException("name cannot be null");
  76         }
  77         if (value == null) {
  78             throw new NullPointerException("value cannot be null");
  79         }
  80 
  81         Util.checkControlAccess();
  82         Flag flag = Flag.getFlag(name);
  83         if (flag == null) {
  84             throw new IllegalArgumentException("VM option \"" +
  85                 name + "\" does not exist");
  86         }
  87         if (!flag.isWriteable()){
  88             throw new IllegalArgumentException("VM Option \"" +
  89                 name + "\" is not writeable");
  90         }
  91 
  92         // Check the type of the value
  93         Object v = flag.getValue();
  94         if (v instanceof Long) {
  95             try {
  96                 long l = Long.parseLong(value);
  97                 Flag.setLongValue(name, l);
  98             } catch (NumberFormatException e) {
  99                 IllegalArgumentException iae =
 100                     new IllegalArgumentException("Invalid value:" +
 101                         " VM Option \"" + name + "\"" +
 102                         " expects numeric value");
 103                 iae.initCause(e);
 104                 throw iae;
 105             }
 106         } else if (v instanceof Boolean) {
 107             if (!value.equalsIgnoreCase("true") &&
 108                 !value.equalsIgnoreCase("false")) {
 109                 throw new IllegalArgumentException("Invalid value:" +
 110                     " VM Option \"" + name + "\"" +
 111                     " expects \"true\" or \"false\".");
 112             }
 113             Flag.setBooleanValue(name, Boolean.parseBoolean(value));
 114         } else if (v instanceof String) {
 115             Flag.setStringValue(name, value);
 116         } else {
 117             throw new IllegalArgumentException("VM Option \"" +
 118                 name + "\" is of an unsupported type: " +
 119                 v.getClass().getName());
 120         }
 121     }
 122 
 123     public List<String> getDiagnosticCommands() {
 124         String[] commands = getDiagnosticCommands0();
 125         return commands == null ? Collections.<String>emptyList() :
 126             Arrays.asList(commands);
 127     }
 128 
 129     public DiagnosticCommandInfo getDiagnosticCommandInfo(String command) {
 130         String[] array = new String[] { command };
 131         return getDiagnosticCommandInfo0(array)[0];
 132     }
 133 
 134     public List<DiagnosticCommandInfo> getDiagnosticCommandInfo() {
 135         String[] commands = getDiagnosticCommands0();
 136         return Arrays.asList(getDiagnosticCommandInfo0(commands));
 137     }
 138 
 139     public List<DiagnosticCommandInfo> getDiagnosticCommandInfo(
 140         List<String> commands) {
 141         if (commands == null) {
 142             throw new NullPointerException();
 143         }
 144         return Arrays.asList(getDiagnosticCommandInfo0(
 145             commands.toArray(new String[commands.size()])));
 146     }
 147 
 148     public String execute(String command) {
 149         Util.checkControlAccess();
 150         return executeDiagnosticCommand0(command);
 151     }
 152 
 153     public String execute(String cmd, String... arguments) {
 154         if(cmd == null) {
 155             throw new NullPointerException("Missing command name");
 156         }
 157         StringBuilder sb = new StringBuilder();
 158         sb.append(cmd);
 159         sb.append(" ");
 160         for(String arg : arguments) {
 161             sb.append(arg);
 162             sb.append(" ");
 163         }
 164         return execute(sb.toString());
 165     }
 166 
 167     public ObjectName getObjectName() {
 168         return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
 169     }
 170 
 171     private native String[] getDiagnosticCommands0();
 172     private native DiagnosticCommandInfo[] getDiagnosticCommandInfo0(
 173         String[] commands) throws IllegalArgumentException;
 174     private native String executeDiagnosticCommand0(String command)
 175         throws IllegalArgumentException;
 176 }