2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.netconf.cli.io;
10 import static org.opendaylight.controller.netconf.cli.io.IOUtil.PATH_SEPARATOR;
11 import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX;
13 import com.google.common.base.Optional;
14 import com.google.common.collect.Lists;
15 import java.awt.event.ActionEvent;
16 import java.awt.event.ActionListener;
17 import java.io.IOException;
18 import java.util.ArrayDeque;
19 import java.util.ArrayList;
20 import java.util.Deque;
21 import java.util.Iterator;
22 import jline.console.ConsoleReader;
23 import jline.console.completer.Completer;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Jline based IO implementation
30 public class ConsoleIOImpl implements ConsoleIO {
32 private static final Logger LOG = LoggerFactory.getLogger(ConsoleIOImpl.class);
34 private final ConsoleReader console;
35 private final Deque<ConsoleContext> contexts = new ArrayDeque<>();
37 public ConsoleIOImpl() throws IOException {
38 console = new ConsoleReader();
39 console.setHandleUserInterrupt(true);
40 console.setPaginationEnabled(true);
41 console.setHistoryEnabled(true);
43 // TODO trifferedActions not supported by jline in current version
44 // https://github.com/jline/jline2/issues/149
45 console.addTriggeredAction('?', new QuestionMarkActionListener());
49 public String read() throws IOException {
50 return console.readLine().trim();
54 public String read(final Character mask) throws IOException {
55 return console.readLine(mask).trim();
59 public void write(final CharSequence data) throws IOException {
65 public void writeLn(final CharSequence data) throws IOException {
66 console.println(data);
71 public void formatLn(final String format, final Object... args) throws IOException {
72 console.println(String.format(format, args));
77 public void enterContext(final ConsoleContext consoleContext) {
78 contexts.push(consoleContext);
79 enterCtx(consoleContext);
84 public void enterRootContext(final ConsoleContext consoleContext) {
85 contexts.addLast(consoleContext);
86 enterCtx(consoleContext);
89 private void enterCtx(final ConsoleContext consoleContext) {
90 setCompleter(consoleContext.getCompleter());
91 console.setPrompt(buildPrompt());
95 public void leaveContext() {
101 public void leaveRootContext() {
106 private void leaveCtx() {
107 console.setPrompt(buildPrompt());
108 if (contexts.peek() != null) {
109 setCompleter(contexts.peek().getCompleter());
113 protected String buildPrompt() {
114 final StringBuilder newPrompt = new StringBuilder();
116 final Iterator<ConsoleContext> descendingIterator = contexts.descendingIterator();
117 while (descendingIterator.hasNext()) {
118 final ConsoleContext consoleContext = descendingIterator.next();
119 final Optional<String> promptPart = consoleContext.getPrompt();
120 if (promptPart.isPresent()) {
121 newPrompt.append(PATH_SEPARATOR);
122 newPrompt.append(promptPart.get());
125 if (newPrompt.length() ==0) {
126 newPrompt.append(PATH_SEPARATOR);
129 newPrompt.append(PROMPT_SUFIX);
131 return newPrompt.toString();
134 private void setCompleter(final Completer newCompleter) {
135 for (final Completer concreteCompleter : console.getCompleters()) {
136 console.removeCompleter(concreteCompleter);
138 console.addCompleter(newCompleter);
141 private class QuestionMarkActionListener implements ActionListener {
143 public void actionPerformed(final ActionEvent e) {
144 ConsoleIOImpl.this.complete();
148 public void complete() {
149 final ArrayList<CharSequence> candidates = Lists.newArrayList();
150 contexts.peek().getCompleter().complete("", 0, candidates);
152 console.getCompletionHandler().complete(console, candidates, 0);
153 } catch (final IOException ex) {
154 throw new IllegalStateException("Unable to write to output", ex);