Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for WFCORE-1968. Fix write-attribute completion. #1927

Merged
merged 1 commit into from
Nov 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public SimpleTabCompleter(String[] candidates) {
throw new IllegalArgumentException("Candidates can't be null");
}
all = Arrays.asList(candidates);
Collections.sort(all);
}

/* (non-Javadoc)
Expand Down Expand Up @@ -99,7 +100,6 @@ public int complete(CommandContext ctx, String buffer, int cursor, List<String>
candidates.add(name);
}
}
Collections.sort(candidates);
}
return result;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -333,52 +333,57 @@ private CommandLineCompleter getCompleter(final Map<String, CommandLineCompleter
propCompleter = factory.createCompleter(ctx, address);
}
if (propCompleter == null) {
ModelNode attrDescr = prop.getValue();
final ModelNode typeNode = attrDescr.get(Util.TYPE);
if (typeNode.isDefined() && ModelType.BOOLEAN.equals(typeNode.asType())) {
return SimpleTabCompleter.BOOLEAN;
propCompleter = getCompleter(prop, ctx, address);
}
return propCompleter;
}

static CommandLineCompleter getCompleter(final Property prop, CommandContext ctx, OperationRequestAddress address) {
ModelNode attrDescr = prop.getValue();
final ModelNode typeNode = attrDescr.get(Util.TYPE);
if (typeNode.isDefined() && ModelType.BOOLEAN.equals(typeNode.asType())) {
return SimpleTabCompleter.BOOLEAN;
}
if (attrDescr.has(Util.VALUE_TYPE)) {
final ModelNode valueTypeNode = attrDescr.get(Util.VALUE_TYPE);
if (typeNode.isDefined() && ModelType.LIST.equals(typeNode.asType())) {
return new ValueTypeCompleter(attrDescr, address);
}
if (attrDescr.has(Util.VALUE_TYPE)) {
final ModelNode valueTypeNode = attrDescr.get(Util.VALUE_TYPE);
if (typeNode.isDefined() && ModelType.LIST.equals(typeNode.asType())) {
return new ValueTypeCompleter(attrDescr, address);
try {
// the logic is: if value-type is set to a specific type
// (i.e. doesn't describe a custom structure)
// then if allowed is specified, use it.
// it might be broken but so far this is not looking clear to me
valueTypeNode.asType();
if (attrDescr.has(Util.ALLOWED)) {
return getAllowedCompleter(prop);
}
try {
// the logic is: if value-type is set to a specific type
// (i.e. doesn't describe a custom structure)
// then if allowed is specified, use it.
// it might be broken but so far this is not looking clear to me
valueTypeNode.asType();
if (attrDescr.has(Util.ALLOWED)) {
return getAllowedCompleter(prop);
}
// Possibly a Map.
if (typeNode.isDefined() && ModelType.OBJECT.equals(typeNode.asType())) {
return new ValueTypeCompleter(attrDescr, address);
}
} catch (IllegalArgumentException e) {
// TODO this means value-type describes a custom structure
// Possibly a Map.
if (typeNode.isDefined() && ModelType.OBJECT.equals(typeNode.asType())) {
return new ValueTypeCompleter(attrDescr, address);
}
}
if (attrDescr.has(Util.FILESYSTEM_PATH) && attrDescr.get(Util.FILESYSTEM_PATH).asBoolean()) {
return Util.isWindows() ? new WindowsFilenameTabCompleter(ctx) : new DefaultFilenameTabCompleter(ctx);
}
if (attrDescr.has(Util.RELATIVE_TO) && attrDescr.get(Util.RELATIVE_TO).asBoolean()) {
return new DeploymentItemCompleter(address);
}
if (attrDescr.has(Util.ALLOWED)) {
return getAllowedCompleter(prop);
}
if (attrDescr.has(Util.CAPABILITY_REFERENCE)) {
return new CapabilityReferenceCompleter(address,
attrDescr.get(Util.CAPABILITY_REFERENCE).asString());
} catch (IllegalArgumentException e) {
// TODO this means value-type describes a custom structure
return new ValueTypeCompleter(attrDescr, address);
}
}
return propCompleter;
if (attrDescr.has(Util.FILESYSTEM_PATH) && attrDescr.get(Util.FILESYSTEM_PATH).asBoolean()) {
return Util.isWindows() ? new WindowsFilenameTabCompleter(ctx) : new DefaultFilenameTabCompleter(ctx);
}
if (attrDescr.has(Util.RELATIVE_TO) && attrDescr.get(Util.RELATIVE_TO).asBoolean()) {
return new DeploymentItemCompleter(address);
}
if (attrDescr.has(Util.ALLOWED)) {
return getAllowedCompleter(prop);
}
if (attrDescr.has(Util.CAPABILITY_REFERENCE)) {
return new CapabilityReferenceCompleter(address,
attrDescr.get(Util.CAPABILITY_REFERENCE).asString());
}
return null;
}

private CommandLineCompleter getAllowedCompleter(final Property prop) {
private static CommandLineCompleter getAllowedCompleter(final Property prop) {
final ModelNode allowedNode = prop.getValue().get(Util.ALLOWED);
if(allowedNode.isDefined()) {
final List<ModelNode> nodeList = allowedNode.asList();
Expand Down Expand Up @@ -456,11 +461,8 @@ public CommandLineCompleter createCompleter(CommandContext ctx, OperationRequest
return NO_CANDIDATES_COMPLETER;
}

if (attrDescr.has(Util.FILESYSTEM_PATH) && attrDescr.get(Util.FILESYSTEM_PATH).asBoolean()) {
return Util.isWindows() ? new WindowsFilenameTabCompleter(ctx) : new DefaultFilenameTabCompleter(ctx);
}

return new AttributeTypeDescrValueCompleter(attrDescr, address);
Property prop = new Property(propName, attrDescr);
return getCompleter(prop, ctx, address);
}});
addGlobalOpPropCompleter(Util.READ_OPERATION_DESCRIPTION, Util.NAME, new CommandLineCompleterFactory(){
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2016, 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.operation.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.jboss.as.cli.CommandContext;
import org.jboss.as.cli.CommandContextFactory;
import org.jboss.as.cli.CommandLineCompleter;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import static org.junit.Assert.assertEquals;
import org.junit.Test;

/**
*
* @author jdenise@redhat.com
*/
public class DefaultOperationCandidatesProviderTestCase {

private static final String list_content = "{\n"
+ " \"type\" => LIST,\n"
+ " \"value-type\" => STRING\n"
+ " }";

private static final String obj_content = "{\n"
+ " \"type\" => OBJECT,\n"
+ " \"value-type\" => { \"prop1\" => { \"type\" => STRING},\n"
+ " \"prop2\" => { \"type\" => STRING}\n"
+ " } }";

private static final String map_content = "{\n"
+ " \"type\" => OBJECT,\n"
+ " \"value-type\" => STRING }";

private static final String boolean_content = "{\n"
+ " \"type\" => BOOLEAN,\n"
+ " }";

private static final String string_content = "{\n"
+ " \"type\" => STRING,\n"
+ " }";

private static final String allowed_content = "{\n"
+ " \"type\" => STRING,\n"
+ " \"allowed\" => [\n"
+ " \"ALL\",\n"
+ " \"FINEST\",\n"
+ " \"FINER\",\n"
+ " ]"
+ " }";

@Test
public void testAttributeValueCompleter() throws Exception {
CommandContext ctx = CommandContextFactory.getInstance().newCommandContext();
DefaultOperationRequestAddress address = new DefaultOperationRequestAddress();
{
Property prop = new Property("arg", ModelNode.fromString(list_content));
CommandLineCompleter completer = DefaultOperationCandidatesProvider.getCompleter(prop, ctx, address);
List<String> candidates = new ArrayList<>();
completer.complete(ctx, "", 0, candidates);
assertEquals(Arrays.asList("["), candidates);
}

{
Property prop = new Property("arg", ModelNode.fromString(map_content));
CommandLineCompleter completer = DefaultOperationCandidatesProvider.getCompleter(prop, ctx, address);
List<String> candidates = new ArrayList<>();
completer.complete(ctx, "", 0, candidates);
assertEquals(Arrays.asList("{"), candidates);
}

{
Property prop = new Property("arg", ModelNode.fromString(obj_content));
CommandLineCompleter completer = DefaultOperationCandidatesProvider.getCompleter(prop, ctx, address);
List<String> candidates = new ArrayList<>();
completer.complete(ctx, "{", 0, candidates);
assertEquals(Arrays.asList("prop1", "prop2"), candidates);
}

{
Property prop = new Property("arg", ModelNode.fromString(boolean_content));
CommandLineCompleter completer = DefaultOperationCandidatesProvider.getCompleter(prop, ctx, address);
List<String> candidates = new ArrayList<>();
completer.complete(ctx, "", 0, candidates);
assertEquals(Arrays.asList("false", "true"), candidates);
}

{
Property prop = new Property("arg", ModelNode.fromString(allowed_content));
CommandLineCompleter completer = DefaultOperationCandidatesProvider.getCompleter(prop, ctx, address);
List<String> candidates = new ArrayList<>();
completer.complete(ctx, "", 0, candidates);
assertEquals(Arrays.asList("ALL", "FINER", "FINEST"), candidates);
}

{
Property prop = new Property("arg", ModelNode.fromString(string_content));
CommandLineCompleter completer = DefaultOperationCandidatesProvider.getCompleter(prop, ctx, address);
assertEquals(null, completer);
}
}
}