io.vertx.ext.shell.system.impl.InternalCommandManager Maven / Gradle / Ivy
/*
* Copyright 2015 Red Hat, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*
*
* Copyright (c) 2015 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*
*/
package io.vertx.ext.shell.system.impl;
import io.vertx.core.Vertx;
import io.vertx.core.VertxException;
import io.vertx.ext.shell.cli.CliToken;
import io.vertx.ext.shell.cli.Completion;
import io.vertx.ext.shell.command.Command;
import io.vertx.ext.shell.command.CommandResolver;
import io.vertx.ext.shell.session.Session;
import io.vertx.ext.shell.system.Process;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;
/**
* @author Julien Viet
*/
public class InternalCommandManager {
private final List resolvers;
public InternalCommandManager(CommandResolver... resolvers) {
this.resolvers = Arrays.asList(resolvers);
}
public InternalCommandManager(List resolvers) {
this.resolvers = resolvers;
}
public List getResolvers() {
return resolvers;
}
/**
* Parses a command line and try to create a process.
*
* @param line the command line to parse
* @return the created process
*/
public Process createProcess(String line) {
return createProcess(CliToken.tokenize(line));
}
/**
* Try to create a process from the command line tokens.
*
* @param line the command line tokens
* @return the created process
*/
public Process createProcess(List line) {
try {
return makeRequest(line);
} catch (Exception e) {
throw new VertxException(e);
}
}
private Process makeRequest(List s) {
ListIterator tokens = s.listIterator();
while (tokens.hasNext()) {
CliToken token = tokens.next();
if (token.isText()) {
for (CommandResolver resolver : resolvers) {
Command command = resolver.getCommand(token.value());
if (command != null) {
List remaining = new ArrayList<>();
while (tokens.hasNext()) {
remaining.add(tokens.next());
}
return command.createProcess(remaining);
}
}
throw new IllegalArgumentException(token.value() + ": command not found");
}
}
throw new IllegalArgumentException();
}
/**
* Perform completion, the completion argument will be notified of the completion progress.
*
* @param completion the completion object
*/
public void complete(Completion completion) {
LinkedList tokens = new LinkedList<>(completion.lineTokens());
// Remove any leading white space
while (tokens.size() > 0 && tokens.getFirst().isBlank()) {
tokens.removeFirst();
}
// > 1 means it's a text token followed by something else
if (tokens.size() > 1) {
ListIterator it = tokens.listIterator();
while (it.hasNext()) {
CliToken ct = it.next();
it.remove();
if (ct.isText()) {
List newTokens = new ArrayList<>();
while (it.hasNext()) {
newTokens.add(it.next());
}
StringBuilder tmp = new StringBuilder();
newTokens.stream().forEach(token -> tmp.append(token.raw()));
String line = tmp.toString();
for (CommandResolver resolver : resolvers) {
Command command = resolver.getCommand(ct.value());
if (command != null) {
command.complete(new Completion() {
@Override
public Vertx vertx() {
return completion.vertx();
}
@Override
public Session session() {
return completion.session();
}
@Override
public String rawLine() {
return line;
}
@Override
public List lineTokens() {
return newTokens;
}
@Override
public void complete(List candidates) {
completion.complete(candidates);
}
@Override
public void complete(String value, boolean terminal) {
completion.complete(value, terminal);
}
});
return;
}
}
completion.complete(Collections.emptyList());
}
}
} else {
String prefix = tokens.size() > 0 ? tokens.getFirst().value() : "";
List names = resolvers.stream().
flatMap(res -> res.commands().stream()).
map(Command::name).
filter(name -> name.startsWith(prefix)).
distinct().
collect(Collectors.toList());
if (names.size() == 1) {
completion.complete(names.get(0).substring(prefix.length()), true);
} else {
String commonPrefix = Completion.findLongestCommonPrefix(names);
if (commonPrefix.length() > prefix.length()) {
completion.complete(commonPrefix.substring(prefix.length()), false);
} else {
completion.complete(names);
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy