Merge "Fixed for bug 1168 : Issue while update subnet"
[controller.git] / opendaylight / netconf / netconf-cli / src / main / java / org / opendaylight / controller / netconf / cli / io / ConsoleIOImpl.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.netconf.cli.io;
9
10 import static org.opendaylight.controller.netconf.cli.io.IOUtil.PATH_SEPARATOR;
11 import static org.opendaylight.controller.netconf.cli.io.IOUtil.PROMPT_SUFIX;
12
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;
26
27 /**
28  * Jline based IO implementation
29  */
30 public class ConsoleIOImpl implements ConsoleIO {
31
32     private static final Logger LOG = LoggerFactory.getLogger(ConsoleIOImpl.class);
33
34     private final ConsoleReader console;
35     private final Deque<ConsoleContext> contexts = new ArrayDeque<>();
36
37     public ConsoleIOImpl() throws IOException {
38         console = new ConsoleReader();
39         console.setHandleUserInterrupt(true);
40         console.setPaginationEnabled(true);
41         console.setHistoryEnabled(true);
42
43         // TODO trifferedActions not supported by jline in current version
44         // https://github.com/jline/jline2/issues/149
45         console.addTriggeredAction('?', new QuestionMarkActionListener());
46     }
47
48     @Override
49     public String read() throws IOException {
50         return console.readLine().trim();
51     }
52
53     @Override
54     public String read(final Character mask) throws IOException {
55         return console.readLine(mask).trim();
56     }
57
58     @Override
59     public void write(final CharSequence data) throws IOException {
60         console.print(data);
61         console.flush();
62     }
63
64     @Override
65     public void writeLn(final CharSequence data) throws IOException {
66         console.println(data);
67         console.flush();
68     }
69
70     @Override
71     public void formatLn(final String format, final Object... args) throws IOException {
72         console.println(String.format(format, args));
73         console.flush();
74     }
75
76     @Override
77     public void enterContext(final ConsoleContext consoleContext) {
78         contexts.push(consoleContext);
79         enterCtx(consoleContext);
80     }
81
82
83     @Override
84     public void enterRootContext(final ConsoleContext consoleContext) {
85         contexts.addLast(consoleContext);
86         enterCtx(consoleContext);
87     }
88
89     private void enterCtx(final ConsoleContext consoleContext) {
90         setCompleter(consoleContext.getCompleter());
91         console.setPrompt(buildPrompt());
92     }
93
94     @Override
95     public void leaveContext() {
96         contexts.pollFirst();
97         leaveCtx();
98     }
99
100     @Override
101     public void leaveRootContext() {
102         contexts.pollLast();
103         leaveCtx();
104     }
105
106     private void leaveCtx() {
107         console.setPrompt(buildPrompt());
108         if (contexts.peek() != null) {
109             setCompleter(contexts.peek().getCompleter());
110         }
111     }
112
113     protected String buildPrompt() {
114         final StringBuilder newPrompt = new StringBuilder();
115
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());
123             }
124         }
125         if (newPrompt.length() ==0) {
126             newPrompt.append(PATH_SEPARATOR);
127         }
128
129         newPrompt.append(PROMPT_SUFIX);
130
131         return newPrompt.toString();
132     }
133
134     private void setCompleter(final Completer newCompleter) {
135         for (final Completer concreteCompleter : console.getCompleters()) {
136             console.removeCompleter(concreteCompleter);
137         }
138         console.addCompleter(newCompleter);
139     }
140
141     private class QuestionMarkActionListener implements ActionListener {
142         @Override
143         public void actionPerformed(final ActionEvent e) {
144             ConsoleIOImpl.this.complete();
145         }
146     }
147
148     public void complete() {
149         final ArrayList<CharSequence> candidates = Lists.newArrayList();
150         contexts.peek().getCompleter().complete("", 0, candidates);
151         try {
152             console.getCompletionHandler().complete(console, candidates, 0);
153         } catch (final IOException ex) {
154             throw new IllegalStateException("Unable to write to output", ex);
155         }
156     }
157 }