1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.geronimo.gshell.commands.ssh;
21
22 import com.google.code.sshd.server.ShellFactory;
23 import jline.Completor;
24 import jline.History;
25 import org.apache.geronimo.gshell.command.Variables;
26 import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
27 import org.apache.geronimo.gshell.console.Console;
28 import org.apache.geronimo.gshell.console.JLineConsole;
29 import org.apache.geronimo.gshell.console.completer.AggregateCompleter;
30 import org.apache.geronimo.gshell.io.Closer;
31 import org.apache.geronimo.gshell.io.IO;
32 import org.apache.geronimo.gshell.notification.ExitNotification;
33 import org.apache.geronimo.gshell.shell.ShellContext;
34 import org.apache.geronimo.gshell.shell.ShellContextHolder;
35 import org.apache.geronimo.gshell.registry.CommandResolver;
36 import org.apache.geronimo.gshell.application.Application;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.io.OutputStream;
43 import java.util.List;
44 import java.util.Map;
45
46
47
48
49
50
51 public class ShellFactoryImpl
52 implements ShellFactory
53 {
54 private final Logger log = LoggerFactory.getLogger(getClass());
55
56 private Application application;
57
58 private Console.Prompter prompter;
59
60 private CommandLineExecutor executor;
61
62 private History history;
63
64 private List<Completor> completers;
65
66 private Console.ErrorHandler errorHandler;
67
68 public Console.Prompter getPrompter() {
69 return prompter;
70 }
71
72 public void setPrompter(final Console.Prompter prompter) {
73 this.prompter = prompter;
74 }
75
76 public CommandLineExecutor getExecutor() {
77 return executor;
78 }
79
80 public void setExecutor(final CommandLineExecutor executor) {
81 this.executor = executor;
82 }
83
84 public History getHistory() {
85 return history;
86 }
87
88 public void setHistory(final History history) {
89 this.history = history;
90 }
91
92 public List<Completor> getCompleters() {
93 return completers;
94 }
95
96 public void setCompleters(final List<Completor> completers) {
97 this.completers = completers;
98 }
99
100 public Console.ErrorHandler getErrorHandler() {
101 return errorHandler;
102 }
103
104 public void setErrorHandler(final Console.ErrorHandler errorHandler) {
105 this.errorHandler = errorHandler;
106 }
107
108 public Application getApplication() {
109 return application;
110 }
111
112 public void setApplication(Application application) {
113 this.application = application;
114 }
115
116 public Shell createShell() {
117 return new ShellImpl();
118 }
119
120 public class ShellImpl
121 implements ShellFactory.DirectShell, org.apache.geronimo.gshell.shell.Shell, ShellContext, Runnable
122 {
123 private InputStream in;
124
125 private OutputStream out;
126
127 private OutputStream err;
128
129 private ExitCallback callback;
130
131 private IO io;
132
133 private Variables variables;
134
135 private boolean closed;
136
137 public void setInputStream(final InputStream in) {
138 this.in = in;
139 }
140
141 public void setOutputStream(final OutputStream out) {
142 this.out = out;
143 }
144
145 public void setErrorStream(final OutputStream err) {
146 this.err = err;
147 }
148
149 public void setExitCallback(ExitCallback callback) {
150 this.callback = callback;
151 }
152
153 public void start(final Map<String,String> env) throws IOException {
154 this.io = new IO(in, out, err, false);
155
156
157 this.variables = new Variables(application.getVariables());
158
159 if (env != null) {
160 for (Map.Entry<String,String> entry : env.entrySet()) {
161 this.variables.set(entry.getKey(), entry.getValue());
162 }
163 }
164 this.variables.set("gshell.prompt", application.getModel().getBranding().getPrompt());
165 this.variables.set(CommandResolver.GROUP, "/");
166 this.variables.set("gshell.username", env.get("USER"));
167 this.variables.set("gshell.hostname", application.getLocalHost());
168
169 this.variables.set("gshell.internal.history", getHistory(), true);
170 new Thread(this).start();
171 }
172
173 public void destroy() {
174 close();
175 }
176
177 public ShellContext getContext() {
178 return this;
179 }
180
181 public Object execute(final String line) throws Exception {
182
183 return executor.execute(getContext(), line);
184 }
185
186 public Object execute(final String command, final Object[] args) throws Exception {
187 return executor.execute(getContext(), args);
188 }
189
190 public Object execute(final Object... args) throws Exception {
191 return executor.execute(getContext(), args);
192 }
193
194 public boolean isOpened() {
195 return !closed;
196 }
197
198 public void close() {
199 closed = true;
200 Closer.close(in, out, err);
201 callback.onExit(0);
202 }
203
204 public boolean isInteractive() {
205 return false;
206 }
207
208 public void run(final Object... args) throws Exception {
209 Console.Executor executor = new Console.Executor()
210 {
211 public Result execute(final String line) throws Exception {
212 assert line != null;
213 try {
214 ShellImpl.this.execute(line);
215 }
216 catch (ExitNotification n) {
217 return Result.STOP;
218 }
219 return Result.CONTINUE;
220 }
221 };
222
223 IO io = getContext().getIo();
224
225
226 JLineConsole console = new JLineConsole(executor, io);
227 console.setPrompter(getPrompter());
228 console.setErrorHandler(getErrorHandler());
229 console.setHistory(getHistory());
230
231 if (completers != null) {
232
233 console.addCompleter(new AggregateCompleter(completers));
234 }
235
236 console.run();
237 }
238
239 public org.apache.geronimo.gshell.shell.Shell getShell() {
240 return this;
241 }
242
243 public IO getIo() {
244 return io;
245 }
246
247 public Variables getVariables() {
248 return variables;
249 }
250
251 public void run() {
252 ShellContext ctx = ShellContextHolder.get(true);
253
254 try {
255 ShellContextHolder.set(getContext());
256 run(new Object[0]);
257 }
258 catch (Exception e) {
259 log.error("Unhandled failure: " + e, e);
260 }
261 finally {
262 ShellContextHolder.set(ctx);
263 close();
264 }
265 }
266 }
267 }