diff --git a/cli/src/main/java/org/jboss/as/cli/handlers/ResourceCompositeOperationHandler.java b/cli/src/main/java/org/jboss/as/cli/handlers/ResourceCompositeOperationHandler.java index 33aea8cbc00..62d573a6dbd 100644 --- a/cli/src/main/java/org/jboss/as/cli/handlers/ResourceCompositeOperationHandler.java +++ b/cli/src/main/java/org/jboss/as/cli/handlers/ResourceCompositeOperationHandler.java @@ -311,8 +311,6 @@ protected Map getOperationArguments(CommandContext ct args = new HashMap(); final List propList = descr.get(Util.REQUEST_PROPERTIES).asPropertyList(); for (Property prop : propList) { - final ModelNode propDescr = prop.getValue(); - ModelType type = null; CommandLineCompleter valueCompleter = null; ArgumentValueConverter valueConverter = null; if(propConverters != null) { @@ -323,16 +321,18 @@ protected Map getOperationArguments(CommandContext ct } if(valueConverter == null) { valueConverter = ArgumentValueConverter.DEFAULT; - if(propDescr.has(Util.TYPE)) { - type = propDescr.get(Util.TYPE).asType(); - if(ModelType.BOOLEAN == type) { + final ModelType propType = getType(prop.getValue()); + if(propType != null) { + if(ModelType.BOOLEAN == propType) { if(valueCompleter == null) { valueCompleter = SimpleTabCompleter.BOOLEAN; } + } else if(ModelType.STRING == propType) { + valueConverter = ArgumentValueConverter.NON_OBJECT; } else if(prop.getName().endsWith("properties")) { // TODO this is bad but can't rely on proper descriptions valueConverter = ArgumentValueConverter.PROPERTIES; - } else if(ModelType.LIST == type) { - if(propDescr.hasDefined(Util.VALUE_TYPE) && propDescr.get(Util.VALUE_TYPE).asType() == ModelType.PROPERTY) { + } else if(ModelType.LIST == propType) { + if(asType(descr.get(Util.VALUE_TYPE)) == ModelType.PROPERTY) { valueConverter = ArgumentValueConverter.PROPERTIES; } else { valueConverter = ArgumentValueConverter.LIST; @@ -382,4 +382,28 @@ protected ModelNode initRequest(CommandContext ctx) throws CommandLineException address.add(getRequiredType(), "?"); return request; } + + protected ModelType getType(ModelNode descr) { + if(!descr.has(Util.TYPE)) { + return null; + } + try { + return descr.get(Util.TYPE).asType(); + } catch(IllegalArgumentException e) { + // the value type is a structure + return null; + } + } + + protected ModelType asType(ModelNode type) { + if(type == null) { + return null; + } + try { + return type.asType(); + } catch(IllegalArgumentException e) { + // the value type is a structure + return null; + } + } } diff --git a/cli/src/main/java/org/jboss/as/cli/handlers/jca/DataSourceAddCompositeHandler.java b/cli/src/main/java/org/jboss/as/cli/handlers/jca/DataSourceAddCompositeHandler.java new file mode 100644 index 00000000000..ac0d9d2d928 --- /dev/null +++ b/cli/src/main/java/org/jboss/as/cli/handlers/jca/DataSourceAddCompositeHandler.java @@ -0,0 +1,119 @@ +/* + * JBoss, Home of Professional Open Source. + * Copyright 2015, 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.jca; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.jboss.as.cli.ArgumentValueConverter; +import org.jboss.as.cli.CommandArgument; +import org.jboss.as.cli.CommandContext; +import org.jboss.as.cli.CommandFormatException; +import org.jboss.as.cli.CommandLineException; +import org.jboss.as.cli.Util; +import org.jboss.as.cli.handlers.OperationCommandWithDescription; +import org.jboss.as.cli.handlers.ResourceCompositeOperationHandler; +import org.jboss.as.cli.impl.ArgumentWithValue; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; +import org.jboss.dmr.Property; + +/** + * Command handler that allows to add connection properties while adding the data-source in one composite operation. + * + * @author Alexey Loubyansky + */ +public class DataSourceAddCompositeHandler extends ResourceCompositeOperationHandler implements OperationCommandWithDescription { + + private static final String CONNECTION_PROPERTIES = "connection-properties"; + + private ArgumentWithValue conProps; + + public DataSourceAddCompositeHandler(CommandContext ctx, String nodeType) { + super(ctx, "data-source-add", nodeType, null, Util.ADD); + conProps = new ArgumentWithValue(this, null, ArgumentValueConverter.PROPERTIES, "--" + CONNECTION_PROPERTIES); + } + + @Override + protected Map loadArguments(CommandContext ctx) { + final Map args = super.loadArguments(ctx); + args.put(conProps.getFullName(), conProps); + return args; + } + + protected ModelNode buildRequestWithoutHeaders(CommandContext ctx) throws CommandFormatException { + final ModelNode req = super.buildRequestWithoutHeaders(ctx); + final ModelNode steps = req.get(Util.STEPS); + + final ModelNode conPropsNode = conProps.toModelNode(ctx); + if(conPropsNode != null) { + final List propsList = conPropsNode.asPropertyList(); + for(Property prop : propsList) { + final ModelNode address = this.buildOperationAddress(ctx); + address.add(CONNECTION_PROPERTIES, prop.getName()); + final ModelNode addProp = new ModelNode(); + addProp.get(Util.ADDRESS).set(address); + addProp.get(Util.OPERATION).set(Util.ADD); + addProp.get(Util.VALUE).set(prop.getValue()); + steps.add(addProp); + } + } + return req; + } + + @Override + public ModelNode getOperationDescription(CommandContext ctx) throws CommandLineException { + ModelNode request = initRequest(ctx); + if(request == null) { + return null; + } + request.get(Util.OPERATION).set(Util.READ_OPERATION_DESCRIPTION); + request.get(Util.NAME).set(Util.ADD); + final ModelNode response; + try { + response = ctx.getModelControllerClient().execute(request); + } catch (IOException e) { + throw new CommandFormatException("Failed to execute read-operation-description.", e); + } + if (!response.hasDefined(Util.RESULT)) { + return null; + } + final ModelNode result = response.get(Util.RESULT); + + final ModelNode opDescr = result.get(Util.DESCRIPTION); + final StringBuilder buf = new StringBuilder(); + buf.append(opDescr.asString()); + buf.append(" (unlike the add operation, this command accepts xa-datasource-properties)."); + opDescr.set(buf.toString()); + + final ModelNode allProps = result.get(Util.REQUEST_PROPERTIES); + final ModelNode conProps = allProps.get(CONNECTION_PROPERTIES); + + conProps.get(Util.DESCRIPTION).set("A comma-separated list of datasource connection properties in key=value pair format."); + conProps.get(Util.TYPE).set(ModelType.LIST); + conProps.get(Util.REQUIRED).set(false); + conProps.get(Util.NILLABLE).set(false); + + return result; + } +} diff --git a/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java b/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java index fadaaf5861b..59c07f5a101 100644 --- a/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java +++ b/cli/src/main/java/org/jboss/as/cli/impl/CommandContextImpl.java @@ -141,6 +141,7 @@ import org.jboss.as.cli.handlers.ifelse.ElseHandler; import org.jboss.as.cli.handlers.ifelse.EndIfHandler; import org.jboss.as.cli.handlers.ifelse.IfHandler; +import org.jboss.as.cli.handlers.jca.DataSourceAddCompositeHandler; import org.jboss.as.cli.handlers.jca.JDBCDriverInfoHandler; import org.jboss.as.cli.handlers.jca.JDBCDriverNameProvider; import org.jboss.as.cli.handlers.jca.XADataSourceAddCompositeHandler; @@ -410,7 +411,7 @@ public int execute(ConsoleOperation output) throws InterruptedException { terminateSession(); else { handleSafe(output.getBuffer().trim()); - if (INTERACT && terminate == 0) { + if (INTERACT && terminate == RUNNING) { console.setPrompt(getPrompt()); } } @@ -556,16 +557,20 @@ private void initCommands() throws CommandLineException { cmdRegistry.registerHandler(new EndIfHandler(), "end-if"); // data-source - GenericTypeOperationHandler dsHandler = new GenericTypeOperationHandler(this, "/subsystem=datasources/data-source", null); final DefaultCompleter driverNameCompleter = new DefaultCompleter(JDBCDriverNameProvider.INSTANCE); + final GenericTypeOperationHandler dsHandler = new GenericTypeOperationHandler(this, "/subsystem=datasources/data-source", null); dsHandler.addValueCompleter(Util.DRIVER_NAME, driverNameCompleter); + // override the add operation with the handler that accepts connection props + final DataSourceAddCompositeHandler dsAddHandler = new DataSourceAddCompositeHandler(this, "/subsystem=datasources/data-source"); + dsAddHandler.addValueCompleter(Util.DRIVER_NAME, driverNameCompleter); + dsHandler.addHandler(Util.ADD, dsAddHandler); cmdRegistry.registerHandler(dsHandler, "data-source"); - GenericTypeOperationHandler xaDsHandler = new GenericTypeOperationHandler(this, "/subsystem=datasources/xa-data-source", null); + final GenericTypeOperationHandler xaDsHandler = new GenericTypeOperationHandler(this, "/subsystem=datasources/xa-data-source", null); xaDsHandler.addValueCompleter(Util.DRIVER_NAME, driverNameCompleter); - // override the add operation with the handler that accepts xa props + // override the xa add operation with the handler that accepts xa props final XADataSourceAddCompositeHandler xaDsAddHandler = new XADataSourceAddCompositeHandler(this, "/subsystem=datasources/xa-data-source"); xaDsAddHandler.addValueCompleter(Util.DRIVER_NAME, driverNameCompleter); - xaDsHandler.addHandler("add", xaDsAddHandler); + xaDsHandler.addHandler(Util.ADD, xaDsAddHandler); cmdRegistry.registerHandler(xaDsHandler, "xa-data-source"); cmdRegistry.registerHandler(new JDBCDriverInfoHandler(this), "jdbc-driver-info"); @@ -821,7 +826,7 @@ public String getArgumentsString() { @Override public void terminateSession() { - if(terminate == 0) { + if(terminate == RUNNING) { terminate = TERMINATING; disconnectController(); restoreStdIO(); @@ -1235,7 +1240,7 @@ public void disconnectController() { extLoader.resetHandlers(); } promptConnectPart = null; - if(console != null && terminate == 0) { + if(console != null && terminate == RUNNING) { console.setPrompt(getPrompt()); } }