1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package com.gridsystems.config.tools.console;
25
26 import java.io.BufferedReader;
27 import java.io.File;
28 import java.io.FileDescriptor;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.InputStreamReader;
32 import java.io.PrintStream;
33 import java.util.HashMap;
34 import java.util.Map;
35
36
37
38
39
40
41
42 public final class ConsoleTools {
43
44
45
46 private static final int NWCORNER = 0;
47
48
49
50
51 private static final int NECORNER = 1;
52
53
54
55
56 private static final int SWCORNER = 2;
57
58
59
60
61 private static final int SECORNER = 3;
62
63
64
65
66 private static final int WCORNER = 4;
67
68
69
70
71 private static final int ECORNER = 5;
72
73
74
75
76 private static final int HLINE = 6;
77
78
79
80
81 private static final int VLINE = 7;
82
83
84
85
86 private static char[] acsmap = { '+', '+', '+', '+', '+', '+', '-', '|' };
87
88
89
90
91 private static FileOutputStream console = new FileOutputStream(FileDescriptor.out);
92
93
94
95
96 private static boolean ansiEnabled = false;
97
98
99
100
101 private static boolean acsEnabled = false;
102
103
104
105
106 private static BufferedReader reader = null;
107
108
109
110
111 private static String encodingName;
112
113
114
115
116 private static boolean switchEncoding = false;
117
118
119
120
121 private static Map<String, char[]> maps = null;
122
123 static {
124 maps = new HashMap<String, char[]>();
125 maps.put("noacs", new char[] { '+', '+', '+', '+', '+', '+', '-', '|' });
126 maps.put("ansi", new char[] { 'l', 'k', 'm', 'j', 't', 'u', 'q', 'x' });
127 maps.put("Cp1252", new char[] { 0xDA, 0xBF, 0xC0, 0xD9, 0xC3, 0xB4, 0xC4, 0xB3 });
128 };
129
130
131
132
133 private ConsoleTools() { }
134
135
136
137
138
139
140
141
142 public static void setup(boolean ansi, boolean acs) {
143 String encoding = System.getProperty("file.encoding");
144 encodingName = encoding;
145
146 ConsoleTools.ansiEnabled = ansi;
147 ConsoleTools.acsEnabled = acs;
148
149 if (acs) {
150 if (ansi) {
151 encoding = "ansi";
152 System.out.print("\u001b(B\u001b)0\u000F");
153 System.out.flush();
154 }
155 } else {
156 encoding = "noacs";
157 }
158
159 acsmap = (char[])maps.get(encoding);
160 if (acsmap == null) {
161 System.out.println("ACS Map for encoding '" + encoding + "' not found");
162 if (File.separatorChar == '\\') {
163
164 acsmap = (char[])maps.get("Cp1252");
165 switchEncoding = true;
166 acsEnabled = true;
167 } else {
168 acsmap = (char[])maps.get("noacs");
169 acsEnabled = false;
170 }
171 }
172 }
173
174
175
176
177 public static void clear() {
178 if (ansiEnabled) {
179 System.out.print("\u001b[2J\u001b[0;0H");
180 System.out.flush();
181 } else {
182 for (int i = 0; i < 40; i++) {
183 System.out.println();
184 }
185 }
186 }
187
188
189
190
191
192
193
194
195 public static String readLine(String prompt) throws IOException {
196 if (reader == null) {
197 reader = new BufferedReader(new InputStreamReader(System.in));
198 }
199 System.out.print(prompt);
200 return reader.readLine();
201 }
202
203
204
205
206
207
208
209
210
211
212 public static String readPassword(String prompt, char replaceChar) throws IOException {
213 PasswordMasker pm = new PasswordMasker();
214 pm.start();
215 String line = readLine(prompt);
216 pm.setStopped();
217 return line;
218 }
219
220
221
222
223
224
225
226
227 public static void fill(StringBuffer sb, char c, int count) {
228 for (int i = 0; i < count; i++) {
229 sb.append(c);
230 }
231 }
232
233
234
235
236
237
238
239
240 public static String center(String s, int width) {
241 int len = s.length();
242 if (len < width) {
243 len = (width - len) / 2;
244 StringBuffer sb = new StringBuffer();
245 fill(sb, ' ', len);
246 sb.append(s);
247 return sb.toString();
248 } else {
249 return s;
250 }
251 }
252
253
254
255
256
257
258
259
260 private static void paintBoxLine(StringBuffer sb, String s, int width) {
261 if (s.equals("-")) {
262 g1(sb);
263 sb.append(acsmap[WCORNER]);
264 fill(sb, acsmap[HLINE], width);
265 sb.append(acsmap[ECORNER]);
266 g0(sb);
267 } else {
268 acs(sb, VLINE, 1);
269 sb.append(s);
270 fill(sb, ' ', width - s.length());
271 acs(sb, VLINE, 1);
272 }
273 }
274
275
276
277
278
279
280
281
282
283 public static void paintBox(String title, Object[] contents, int width) {
284 StringBuffer sb = new StringBuffer();
285
286
287 g1(sb);
288 sb.append(acsmap[NWCORNER]).append(acsmap[HLINE]);
289 g0(sb);
290
291 sb.append(title);
292
293 g1(sb);
294 fill(sb, acsmap[HLINE], width - (title.length() + 1));
295 sb.append(acsmap[NECORNER]);
296 g0(sb);
297 System.out.println(sb);
298
299
300 for (int i = 0; i < contents.length; i++) {
301 if (contents[i] instanceof Field) {
302
303 String[] lines = ((Field)contents[i]).getContents();
304 for (int j = 0; j < lines.length; j++) {
305 sb.setLength(0);
306 paintBoxLine(sb, lines[j], width);
307 System.out.println(sb);
308 }
309 } else if (contents[i] != null) {
310 sb.setLength(0);
311 String s = contents[i].toString();
312 paintBoxLine(sb, s, width);
313 System.out.println(sb);
314 }
315 }
316
317
318 sb.setLength(0);
319 g1(sb);
320 sb.append(acsmap[SWCORNER]);
321 fill(sb, acsmap[HLINE], width);
322 sb.append(acsmap[SECORNER]);
323 g0(sb);
324 System.out.println(sb);
325 }
326
327
328
329
330
331
332
333
334
335
336
337
338
339 private static void acs(StringBuffer sb, int code, int num) {
340 g1(sb);
341 char c = acsmap[code];
342 for (int i = 0; i < num; i++) {
343 sb.append(c);
344 }
345 g0(sb);
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 private static void g0(StringBuffer sb) {
362 if (acsEnabled && ansiEnabled) {
363 sb.append('\u000F');
364 } else if (switchEncoding) {
365 try {
366 System.out.print(sb);
367 System.out.flush();
368 sb.setLength(0);
369 System.setOut(new PrintStream(console, true, encodingName));
370 } catch (Exception e) {
371 }
372 }
373 }
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388 private static void g1(StringBuffer sb) {
389 if (acsEnabled && ansiEnabled) {
390 sb.append('\u000E');
391 } else if (switchEncoding) {
392 try {
393 System.out.print(sb);
394 System.out.flush();
395 sb.setLength(0);
396 System.setOut(new PrintStream(console, true, "Cp1252"));
397 } catch (Exception e) { }
398 }
399 }
400
401
402
403
404
405
406
407
408 private static class PasswordMasker extends Thread {
409
410
411
412 private volatile boolean stopped = false;
413
414
415
416
417 public PasswordMasker() {
418 super();
419 setPriority(Thread.MAX_PRIORITY);
420 }
421
422
423
424
425 public void setStopped() {
426 this.stopped = true;
427 }
428
429
430
431
432
433
434 public void run() {
435 try {
436 String s = "\b*";
437 while (!stopped) {
438 sleep(1);
439 System.out.print(s);
440 System.out.flush();
441 }
442 } catch (InterruptedException e) { }
443 }
444 }
445 }