X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-cli%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fcli%2Fio%2FConsoleIOImpl.java;fp=opendaylight%2Fnetconf%2Fnetconf-cli%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fcli%2Fio%2FConsoleIOImpl.java;h=5b7374a698ce329e46dab3a742ed7995d0e434af;hp=0000000000000000000000000000000000000000;hb=b3d2a00776a1a5e3a139d73ced859aa557c931af;hpb=d04e0863b86415749a8437241c57df0d32a3b133 diff --git a/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java new file mode 100644 index 0000000000..5b7374a698 --- /dev/null +++ b/opendaylight/netconf/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/io/ConsoleIOImpl.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.netconf.cli.io; + +import static org.opendaylight.controller.netconf.cli.io.IOUtil.PATH_SEPARATOR; +import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX; + +import com.google.common.base.Optional; +import com.google.common.collect.Lists; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.Iterator; +import jline.console.ConsoleReader; +import jline.console.completer.Completer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Jline based IO implementation + */ +public class ConsoleIOImpl implements ConsoleIO { + + private static final Logger LOG = LoggerFactory.getLogger(ConsoleIOImpl.class); + + private final ConsoleReader console; + private final Deque contexts = new ArrayDeque<>(); + + public ConsoleIOImpl() throws IOException { + console = new ConsoleReader(); + console.setHandleUserInterrupt(true); + console.setPaginationEnabled(true); + console.setHistoryEnabled(true); + + // TODO trifferedActions not supported by jline in current version + // https://github.com/jline/jline2/issues/149 + console.addTriggeredAction('?', new QuestionMarkActionListener()); + } + + @Override + public String read() throws IOException { + return console.readLine().trim(); + } + + @Override + public String read(final Character mask) throws IOException { + return console.readLine(mask).trim(); + } + + @Override + public void write(final CharSequence data) throws IOException { + console.print(data); + console.flush(); + } + + @Override + public void writeLn(final CharSequence data) throws IOException { + console.println(data); + console.flush(); + } + + @Override + public void formatLn(final String format, final Object... args) throws IOException { + console.println(String.format(format, args)); + console.flush(); + } + + @Override + public void enterContext(final ConsoleContext consoleContext) { + contexts.push(consoleContext); + enterCtx(consoleContext); + } + + + @Override + public void enterRootContext(final ConsoleContext consoleContext) { + contexts.addLast(consoleContext); + enterCtx(consoleContext); + } + + private void enterCtx(final ConsoleContext consoleContext) { + setCompleter(consoleContext.getCompleter()); + console.setPrompt(buildPrompt()); + } + + @Override + public void leaveContext() { + contexts.pollFirst(); + leaveCtx(); + } + + @Override + public void leaveRootContext() { + contexts.pollLast(); + leaveCtx(); + } + + private void leaveCtx() { + console.setPrompt(buildPrompt()); + if (contexts.peek() != null) { + setCompleter(contexts.peek().getCompleter()); + } + } + + protected String buildPrompt() { + final StringBuilder newPrompt = new StringBuilder(); + + final Iterator descendingIterator = contexts.descendingIterator(); + while (descendingIterator.hasNext()) { + final ConsoleContext consoleContext = descendingIterator.next(); + final Optional promptPart = consoleContext.getPrompt(); + if (promptPart.isPresent()) { + newPrompt.append(PATH_SEPARATOR); + newPrompt.append(promptPart.get()); + } + } + if (newPrompt.length() ==0) { + newPrompt.append(PATH_SEPARATOR); + } + + newPrompt.append(PROMPT_SUFIX); + + return newPrompt.toString(); + } + + private void setCompleter(final Completer newCompleter) { + for (final Completer concreteCompleter : console.getCompleters()) { + console.removeCompleter(concreteCompleter); + } + console.addCompleter(newCompleter); + } + + private class QuestionMarkActionListener implements ActionListener { + @Override + public void actionPerformed(final ActionEvent e) { + ConsoleIOImpl.this.complete(); + } + } + + public void complete() { + final ArrayList candidates = Lists.newArrayList(); + contexts.peek().getCompleter().complete("", 0, candidates); + try { + console.getCompletionHandler().complete(console, candidates, 0); + } catch (final IOException ex) { + throw new IllegalStateException("Unable to write to output", ex); + } + } +}