avoid hard-coding a default value twice
[saartuer.git] / AndTuer / src / de / hacksaar / andtuer / AsyncTyshell.java
1 package de.hacksaar.andtuer;
2
3 import android.os.AsyncTask;
4 import android.util.Log;
5 import de.hacksaar.javatuer.InteractiveLogin;
6 import de.hacksaar.javatuer.TyshellClient;
7
8 import java.io.BufferedReader;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.InputStreamReader;
12 import java.util.LinkedList;
13 import java.util.Queue;
14
15 class AsyncTyshell extends AsyncTask<Void, Void, Void> {
16
17         private static final String TAG = "AsyncTyshell";
18         private final String hostname;
19         private final int port;
20         private final String username;
21         private final String keyFile;
22         private final Prompter prompter;
23         private final Queue<String> messages = new LinkedList<>();
24         private final Object promptWait = new Object();
25         private String promptResultString;
26         private boolean promptResultBoolean;
27         private boolean disconnect = true;
28
29         AsyncTyshell(String hostname, int port, String username, String keyFile, Prompter prompter) {
30                 this.hostname = hostname;
31                 this.port = port;
32                 this.username = username;
33                 this.keyFile = keyFile;
34                 this.prompter = prompter;
35         }
36
37         private void awaitPrompt() {
38                 synchronized (promptWait) {
39                         try {
40                                 promptWait.wait();
41                         } catch (InterruptedException e) {
42                                 Log.w(TAG, e);
43                         }
44                 }
45         }
46
47         public void disconnect() {
48                 disconnect = false;
49                 synchronized (promptWait) {
50                         promptWait.notify();
51                 }
52                 synchronized (messages) {
53                         messages.notify();
54                 }
55         }
56
57         private void readUnlimited(InputStreamReader inputStreamReader) {
58                 final BufferedReader reader = new BufferedReader(inputStreamReader);
59                 new Thread(new Runnable() {
60                         @Override
61                         public void run() {
62                                 String line;
63                                 try {
64                                         while((line = reader.readLine()) != null) {
65                                                 prompter.sendMessage(line);
66                                         }
67                                 } catch (Exception e) {
68                                         Log.w("end read unlimited!", e);
69                                 }
70                         }
71                 }).start();
72         }
73
74         @Override
75         protected Void doInBackground(Void... voids) {
76                 TyshellClient client = new TyshellClient(hostname, port, new AndroidLogging());
77                 client.connect(username, keyFile, new AsyncInteractiveLogin());
78                 readUnlimited(client.getInputStream());
79                 while (disconnect) {
80                         String msg = null;
81                         synchronized (messages) {
82                                 while (disconnect && (msg = messages.poll()) == null) {
83                                         try {
84                                                 messages.wait();
85                                         } catch (InterruptedException e) {
86                                                 return null;
87                                         }
88                                 }
89                         }
90                         if (msg == null) {
91                                 break;
92                         }
93                         client.sendCommand(msg);
94                 }
95                 client.disconnect();
96                 return null;
97         }
98
99         public void promptResult(boolean result) {
100                 promptResultBoolean = result;
101                 synchronized (promptWait) {
102                         promptWait.notify();
103                 }
104         }
105
106         public void promptResult(String result) {
107                 promptResultString = result;
108                 synchronized (promptWait) {
109                         promptWait.notify();
110                 }
111         }
112
113         public void sendCommand(String string) {
114                 synchronized (messages) {
115                         messages.add(string);
116                         messages.notify();
117                 }
118         }
119
120         public interface Prompter {
121                 void promptBoolean(String message);
122
123                 void promptString(String message);
124
125                 void sendMessage(String message);
126         }
127
128         private class AsyncInteractiveLogin extends InteractiveLogin {
129
130                 AsyncInteractiveLogin() {
131                 }
132
133                 @Override
134                 public String promptKeyPassphrase(String question) {
135                         prompter.promptString(question);
136                         awaitPrompt();
137                         return promptResultString;
138                 }
139
140                 @Override
141                 public String promptUserPassword(String question) {
142                         prompter.promptString(question);
143                         awaitPrompt();
144                         return promptResultString;
145                 }
146
147                 @Override
148                 public boolean promptYesNo(String question) {
149                         prompter.promptBoolean(question);
150                         awaitPrompt();
151                         return promptResultBoolean;
152                 }
153
154                 @Override
155                 public void showMessage(String s) {
156                         prompter.sendMessage(s);
157                 }
158         }
159 }