All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.as.cli.handlers.CommandCommandHandler Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.cli.handlers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jboss.as.cli.CommandContext;
import org.jboss.as.cli.CommandFormatException;
import org.jboss.as.cli.CommandHandler;
import org.jboss.as.cli.CommandLineCompleter;
import org.jboss.as.cli.CommandRegistry;
import org.jboss.as.cli.Util;
import org.jboss.as.cli.impl.ArgumentWithValue;
import org.jboss.as.cli.impl.DefaultCompleter;
import org.jboss.as.cli.impl.DefaultCompleter.CandidatesProvider;
import org.jboss.as.cli.operation.OperationRequestAddress;
import org.jboss.as.cli.operation.OperationRequestCompleter;
import org.jboss.as.cli.operation.ParsedCommandLine;
import org.jboss.as.cli.operation.impl.DefaultCallbackHandler;
import org.jboss.as.cli.parsing.ParserUtil;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
/**
*
* @author Alexey Loubyansky
*/
public class CommandCommandHandler extends CommandHandlerWithHelp {
private final ArgumentWithValue action = new ArgumentWithValue(this, new SimpleTabCompleter(new String[]{"add", "list", "remove"}), 0, "--action");
private final ArgumentWithValue nodePath;
private final ArgumentWithValue idProperty;
private final ArgumentWithValue commandName;
private final CommandRegistry cmdRegistry;
private DefaultCallbackHandler callback;
public CommandCommandHandler(CommandRegistry cmdRegistry) {
super("command", true);
this.cmdRegistry = cmdRegistry;
action.addCantAppearAfter(helpArg);
nodePath = new ArgumentWithValue(this, new CommandLineCompleter(){
@Override
public int complete(CommandContext ctx, String buffer, int cursor, List candidates) {
int offset = 0;
int result = OperationRequestCompleter.ARG_VALUE_COMPLETER.complete(ctx, buffer, cursor + offset, candidates) - offset;
if(result < 0) {
return result;
}
return result;
}}, "--node-type") {
@Override
public boolean canAppearNext(CommandContext ctx) throws CommandFormatException {
return "add".equals(action.getValue(ctx.getParsedCommandLine())) && super.canAppearNext(ctx);
}
};
idProperty = new ArgumentWithValue(this, new DefaultCompleter(new CandidatesProvider(){
@Override
public List getAllCandidates(CommandContext ctx) {
List props;
try {
props = getNodeProperties(ctx);
} catch (CommandFormatException e) {
return Collections.emptyList();
}
final List candidates = new ArrayList();
for(Property prop : props) {
final ModelNode value = prop.getValue();
if(value.has("access-type") && "read-only".equals(value.get("access-type").asString())) {
candidates.add(prop.getName());
}
}
return candidates;
}}), "--property-id");
idProperty.addRequiredPreceding(nodePath);
commandName = new ArgumentWithValue(this, new DefaultCompleter(new CandidatesProvider(){
private final DefaultCallbackHandler callback = new DefaultCallbackHandler();
@Override
public List getAllCandidates(CommandContext ctx) {
final String actionName = action.getValue(ctx.getParsedCommandLine());
if(actionName == null) {
return Collections.emptyList();
}
if (actionName.equals("add")) {
final String thePath = nodePath.getValue(ctx.getParsedCommandLine());
if (thePath == null) {
return Collections.emptyList();
}
callback.reset();
try {
ParserUtil.parseOperationRequest(thePath, callback);
} catch (CommandFormatException e) {
return Collections.emptyList();
}
OperationRequestAddress typeAddress = callback.getAddress();
if (!typeAddress.endsOnType()) {
return Collections.emptyList();
}
return Collections.singletonList(typeAddress.getNodeType());
}
if (actionName.equals("remove")) {
return getExistingCommands();
}
return Collections.emptyList();
}}), "--command-name") {
@Override
public boolean canAppearNext(CommandContext ctx) throws CommandFormatException {
ParsedCommandLine args = ctx.getParsedCommandLine();
if(isPresent(args)) {
return false;
}
final String actionStr = action.getValue(args);
if(actionStr == null) {
return false;
}
if("add".equals(actionStr)) {
return nodePath.isValueComplete(args);
}
if("remove".equals(actionStr)) {
return true;
}
return false;
}
};
}
/* (non-Javadoc)
* @see org.jboss.as.cli.handlers.CommandHandlerWithHelp#doHandle(org.jboss.as.cli.CommandContext)
*/
@Override
protected void doHandle(CommandContext ctx) throws CommandFormatException {
final ParsedCommandLine args = ctx.getParsedCommandLine();
final String action = this.action.getValue(args);
if(action == null) {
throw new CommandFormatException("Command is missing.");
}
if(action.equals("list")) {
ctx.printColumns(getExistingCommands());
return;
}
if(action.equals("add")) {
final String nodePath = this.nodePath.getValue(args, true);
final String propName = this.idProperty.getValue(args, false);
final String cmdName = this.commandName.getValue(args, true);
validateInput(ctx, nodePath, propName);
if(cmdRegistry.getCommandHandler(cmdName) != null) {
throw new CommandFormatException("Command '" + cmdName + "' already registered.");
}
cmdRegistry.registerHandler(new GenericTypeOperationHandler(ctx, nodePath, propName), cmdName);
return;
}
if(action.equals("remove")) {
final String cmdName = this.commandName.getValue(args, true);
CommandHandler handler = cmdRegistry.getCommandHandler(cmdName);
if(!(handler instanceof GenericTypeOperationHandler)) {
throw new CommandFormatException("Command '" + cmdName + "' is not a generic type command.");
}
cmdRegistry.remove(cmdName);
return;
}
throw new CommandFormatException("Unexpected action: " + action);
}
protected List getExistingCommands() {
final List commands = new ArrayList();
for(String cmd : cmdRegistry.getTabCompletionCommands()) {
if(cmdRegistry.getCommandHandler(cmd) instanceof GenericTypeOperationHandler) {
commands.add(cmd);
}
}
return commands;
}
protected List getNodeProperties(CommandContext ctx) throws CommandFormatException {
final ModelNode request = initRequest(ctx);
request.get(Util.OPERATION).set(Util.READ_RESOURCE_DESCRIPTION);
ModelNode result;
try {
result = ctx.getModelControllerClient().execute(request);
} catch (IOException e) {
return Collections.emptyList();
}
if(!result.hasDefined(Util.RESULT)) {
return Collections.emptyList();
}
result = result.get(Util.RESULT);
if(!result.hasDefined(Util.ATTRIBUTES)) {
return Collections.emptyList();
}
return result.get(Util.ATTRIBUTES).asPropertyList();
}
protected ModelNode initRequest(CommandContext ctx) throws CommandFormatException {
ModelNode request = new ModelNode();
ModelNode address = request.get(Util.ADDRESS);
final String type = nodePath.getValue(ctx.getParsedCommandLine());
if(callback == null) {
callback = new DefaultCallbackHandler();
} else {
callback.reset();
}
ParserUtil.parseOperationRequest(type, callback);
OperationRequestAddress typeAddress = callback.getAddress();
if(!typeAddress.endsOnType()) {
return null;
}
final String typeName = typeAddress.toParentNode().getType();
for(OperationRequestAddress.Node node : typeAddress) {
address.add(node.getType(), node.getName());
}
address.add(typeName, "?");
return request;
}
protected void validateInput(CommandContext ctx, String typePath, String propertyName) throws CommandFormatException {
ModelNode request = new ModelNode();
ModelNode address = request.get(Util.ADDRESS);
if(callback == null) {
callback = new DefaultCallbackHandler();
} else {
callback.reset();
}
try {
ParserUtil.parseOperationRequest(typePath, callback);
} catch (CommandFormatException e) {
throw new CommandFormatException("Failed to validate input: " + e.getLocalizedMessage());
}
OperationRequestAddress typeAddress = callback.getAddress();
if(!typeAddress.endsOnType()) {
throw new CommandFormatException("Node path '" + typePath + "' doesn't appear to end on a type.");
}
final String typeName = typeAddress.toParentNode().getType();
for(OperationRequestAddress.Node node : typeAddress) {
address.add(node.getType(), node.getName());
}
request.get(Util.OPERATION).set(Util.READ_CHILDREN_TYPES);
ModelNode result;
try {
result = ctx.getModelControllerClient().execute(request);
} catch (IOException e) {
throw new CommandFormatException("Failed to validate input: " + e.getLocalizedMessage());
}
if(!result.hasDefined(Util.RESULT)) {
throw new CommandFormatException("Failed to validate input: operation response doesn't contain result info.");
}
boolean pathValid = false;
for(ModelNode typeNode : result.get(Util.RESULT).asList()) {
if(typeNode.asString().equals(typeName)) {
pathValid = true;
break;
}
}
if(!pathValid) {
throw new CommandFormatException("Type '" + typeName + "' not found among child types of '" + ctx.getNodePathFormatter().format(typeAddress) + "'");
}
address.add(typeName, "?");
request.get(Util.OPERATION).set(Util.READ_RESOURCE_DESCRIPTION);
try {
result = ctx.getModelControllerClient().execute(request);
} catch (IOException e) {
throw new CommandFormatException(e.getLocalizedMessage());
}
if(!result.hasDefined(Util.RESULT)) {
throw new CommandFormatException("Failed to validate input: operation response doesn't contain result info.");
}
result = result.get(Util.RESULT);
if(!result.hasDefined("attributes")) {
throw new CommandFormatException("Failed to validate input: description of attributes is missing for " + typePath);
}
if(propertyName != null) {
for(Property prop : result.get(Util.ATTRIBUTES).asPropertyList()) {
if(prop.getName().equals(propertyName)) {
ModelNode value = prop.getValue();
if(value.has(Util.ACCESS_TYPE) && Util.READ_ONLY.equals(value.get(Util.ACCESS_TYPE).asString())) {
return;
}
throw new CommandFormatException("Property " + propertyName + " is not read-only.");
}
}
} else {
return;
}
throw new CommandFormatException("Property '" + propertyName + "' wasn't found among the properties of " + typePath);
}
}