/* * Copyright 2011 ClamShell-Cli. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.clamshellcli.jmx; import org.clamshellcli.api.Command; import org.clamshellcli.api.Context; import org.clamshellcli.core.AnInputController; import org.clamshellcli.core.ShellException; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.management.ObjectInstance; /** * This is an implementation of the InputController for the JMX CLI. * This implementation parses command-line input from Context(KEY_INPUT_LINE) * value. It parses the input using JSon notation. The command-line input is * expected to be of the form: * * <code>cmd param0:value para1:value1 ... paramN:valueN</code> * * The controller parses the input line and dispatches the parsed command and * params to a Command instance on the classpath. * * @author vladimir.vivien */ public class JmxController extends AnInputController { private static final String JMX_NAMESPACE = "jmx"; private Map<String, Command> commands; private Gson gson; @Override public boolean handle(Context ctx) { String cmdLine = (String)ctx.getValue(Context.KEY_COMMAND_LINE_INPUT); boolean handled = false; if(cmdLine != null && !cmdLine.trim().isEmpty()){ String[] tokens = cmdLine.split("\\s+"); String cmdName = tokens[0]; Map<String,Object> argsMap = null; // if there are arguments if(tokens.length > 1 ){ String argsString = convertParamsToString(Arrays.copyOfRange(tokens, 1, tokens.length)); String argsJson = "{" + argsString + "}"; try{ Type mapType = new TypeToken<Map<String,Object>>(){}.getType(); argsMap = gson.fromJson(argsJson, mapType); }catch(Exception ex){ ctx.getIoConsole().writeOutput( String.format("%nUnable to parse command parameters [%s]: " + " %s.%n%n", argsJson, ex.getMessage())); return true; } } // launch command Command cmd = null; if(commands != null && (cmd = commands.get(cmdName)) != null){ ctx.putValue(Context.KEY_COMMAND_LINE_ARGS, argsMap); try{ cmd.execute(ctx); }catch(ShellException se){ printException (se, ctx); } handled = true; }else{ handled = false; } } return handled; } @Override public void plug(Context plug) { super.plug(plug); gson = new Gson(); List<Command> jmxCommands = plug.getCommandsByNamespace(JMX_NAMESPACE); if(jmxCommands.size() > 0){ commands = plug.mapCommands(jmxCommands); Set<String> cmdHints = new TreeSet<String>(); // plug each Command instance and collect input hints for(Command cmd : jmxCommands){ cmd.plug(plug); cmdHints.addAll(collectInputHints(cmd)); } // setup a map for cached jmx objects plug.putValue(Management.KEY_MBEANS_MAP, new HashMap<String,ObjectInstance>()); // save expected command input hints setExpectedInputs(cmdHints.toArray(new String[0])); }else{ plug.getIoConsole().writeOutput( String.format("%nNo commands were found for input controller" + " [%s].%n%n", this.getClass().getName())); } } private void printException(ShellException ex, Context ctx){ ctx.getIoConsole().writeOutput( String.format("%n%s%n%n", ex.getMessage()) ); } private String convertParamsToString(String[] params){ StringBuffer buff = new StringBuffer(); for(int i = 0; i < params.length; i++){ buff.append(params[i].trim()); if(i < (params.length-1)){ buff.append(","); } } return buff.toString(); } }