1 /*
2 * Replica is published under the terms
3 * of the Apache Software License.
4 */
5 package replica.textui;
6
7 import java.io.BufferedReader;
8 import java.io.BufferedWriter;
9 import java.io.FileNotFoundException;
10 import java.io.FileReader;
11 import java.io.IOException;
12 import java.io.InputStreamReader;
13 import java.io.OutputStreamWriter;
14 import java.net.InetAddress;
15 import java.net.Socket;
16 import java.util.Hashtable;
17 import java.util.StringTokenizer;
18
19 import replica.utils.BeanUtils;
20
21 /***
22 * @author Pedro Costa
23 * @author Helder Silva
24 * @since 24/Jan/2004
25 */
26 public class SimpleInterface implements Runnable{
27
28 final static String CONNECT = "connect";
29 final static String DISCONNECT = "disconnect";
30 final static String QUIT = "quit";
31 final static String RUN = "run";
32
33 int port = 7654;
34 String address = "localhost";
35
36 Socket socket;
37 BufferedReader reader;
38 BufferedWriter writer;
39
40 static Hashtable initialOptions;
41 static{
42 initialOptions = new Hashtable();
43 initialOptions.put("-p", "port");
44 initialOptions.put("-a", "address");
45 }
46
47 public static void main(String[] args) {
48
49 SimpleInterface si = new SimpleInterface();
50
51 if( args != null ){
52 for (int i = 0; i < args.length; i=i+2) {
53 if( i < args.length - 1 )
54 BeanUtils.writeProperty(si, args[i], args[i+1]);
55 else{
56 System.out.println("Invalid program option. Usage" + usage());
57 System.exit(-1);
58 }
59 }
60 }
61
62 new Thread(si).start();
63 }
64
65 static String usage(){
66 return "java replica.textui.SimpleTextInterface <options>\n"+
67 "\n"+
68 " Where <options> can be any of the following:\n"+
69 " -p <portNumber> - changes the default port number to use.\n"+
70 " -a <host> - changes the default host address.";
71
72 }
73
74
75 public SimpleInterface (){
76 super();
77 }
78
79 public void run(){
80
81 BufferedReader userReader = null;
82
83 try{
84 userReader = new BufferedReader( new InputStreamReader( System.in ) );
85
86 System.out.print(helloMessage());
87
88 System.out.print(" > ");
89
90 String line = null;
91 StringBuffer command = new StringBuffer();
92 int lineNumber = 1;
93 while ( ( line = userReader.readLine() ) != null ){
94 command.append(line + "\n");
95 if( isApplicationCommand(line) ||
96 line.indexOf(';') >= 0 ||
97 line.trim().length() == 0){
98 String result = processLine(command.toString());
99 command = new StringBuffer();
100 lineNumber = 1;
101 if( result != null && result.length() > 0 )
102 System.out.print(result);
103 System.out.print("\n > ");
104 }
105 else{
106 System.out.print(" " + (++lineNumber) + " ");
107 }
108 }
109 }
110 catch(IOException e){
111 System.out.println("Problem connecting to ["+getAddress()+":"+
112 getPort()+"].");
113 e.printStackTrace();
114 }
115 finally{
116 close();
117 }
118 }
119
120 /***
121 * Return true if the given line starts with
122 * an application command.
123 *
124 * @param line the line to check
125 * @return true or false
126 */
127 boolean isApplicationCommand(String line){
128 line = line.trim();
129
130 return line.startsWith(CONNECT) ||
131 line.startsWith(DISCONNECT) ||
132 line.startsWith(QUIT);
133 }
134
135 String processLine(String line){
136 if(line == null)
137 return null;
138
139 line = line.trim();
140
141 if( line.length() == 0 )
142 return null;
143
144 StringTokenizer tokenizer = new StringTokenizer( line);
145
146 if( tokenizer.countTokens() == 0)
147 return null;
148
149 String command = tokenizer.nextToken();
150
151 if( tokenizer.countTokens() == 0)
152 return processCommand(command, null);
153
154 String args = line.substring(command.length());
155
156 return processCommand( command, args);
157 }
158
159 String helloMessage(){
160 return "\n" +
161 " +----------------------------------------------+\n"+
162 " | T H E R E P L I C A P R O J E C T |\n"+
163 " | |\n"+
164 " | S i m p l e I n t e r f a c e. |\n"+
165 " +----------------------------------------------+\n"+
166 "\n"+
167 " by: Replica Inc.:)\n"+
168 "\n"+
169 "\n";
170 }
171
172 String processCommand(String command, String args){
173
174 if( command.equalsIgnoreCase(CONNECT) )
175 return connect(args);
176
177 if( command.equalsIgnoreCase(DISCONNECT) )
178 return disconnect();
179
180 if( command.equalsIgnoreCase(QUIT) ){
181 quit();
182 return "YOU WILL NEVER SEE THIS.";
183 }
184
185 if( command.equalsIgnoreCase(RUN) )
186 return run(args);
187
188 if( !isConnected() )
189 return "Not connected. You must connect first.";
190
191 return sendToServer( command +
192 (args==null?"":(" " + args)) );
193 }
194
195 String run(String args){
196
197 if( args == null || args.trim().length() == 0 )
198 return "Usage: run <filename>;";
199
200 args = args.trim();
201 if(args.endsWith(";"))
202 args = args.substring(0, args.length()-1);
203
204 BufferedReader reader = null;
205 int i = 0;
206 try{
207 reader = new BufferedReader( new FileReader(args));
208
209 String line = null;
210 while( (line = reader.readLine() ) != null ){
211 processLine(line);i++;
212 }
213 }
214 catch(FileNotFoundException e){
215 return "File no found: [" + args + "].";
216 }
217 catch(IOException e){
218 e.printStackTrace();
219 return e.getMessage();
220 }
221 finally{
222 try{ reader.close(); }catch(Throwable t){}
223 }
224
225 return "Processed " + i + " lines from file [" + args + "].";
226 }
227
228 String connect(String args){
229
230 Object[] conArgs = null;
231 try{
232 conArgs = getConnectArgs(args);
233 }
234 catch(IllegalArgumentException e){
235 return e.getMessage();
236 }
237
238 try{
239 connect( conArgs[0].toString(), ((Integer)conArgs[1]).intValue(), conArgs[2].toString() );
240 }
241 catch(IOException e){
242 e.printStackTrace();
243 return "Unable to connect to [" + conArgs[0] + ":" + conArgs[1]
244 + "] as [" + conArgs[2] + "].";
245 }
246
247 return null;
248 }
249
250 /***
251 * Parse a connect command string.
252 *
253 * If the string to parse does not contain the host address and/or
254 * the port number, a default value is used.
255 *
256 * @param args the connect string to parse.
257 * @return a array where:
258 * 1: is a String with a address;
259 * 2: is a Integer with the port number;
260 * 3: is the user string.
261 * @throws IllegalArgumentException if the string cannot be parsed.
262 */
263 Object[] getConnectArgs(String args) throws IllegalArgumentException{
264
265 if( args == null )
266 throw new IllegalArgumentException(
267 "Error in connect command. Usage: " + connectUsage() );
268
269 StringTokenizer tokenizer = new StringTokenizer(args, " ");
270
271 if( tokenizer.countTokens() < 1 )
272 throw new IllegalArgumentException(
273 "Error in connect command. Usage: " + connectUsage() );
274
275 String host = null;
276 int port = -1;
277 if( tokenizer.countTokens() > 1){
278 String fullAddress = tokenizer.nextToken();
279 StringTokenizer tok2 = new StringTokenizer(fullAddress,":");
280 host = tok2.nextToken();
281 if( tok2.countTokens() > 0 ){
282 String portStr = tok2.nextToken();
283 try{
284 port = Integer.parseInt(portStr);
285 }
286 catch(NumberFormatException e){
287 throw new IllegalArgumentException(
288 "Invalid port number [" + portStr + "]." );
289 }
290 }
291 }
292
293 String user = tokenizer.nextToken();
294
295 if( host == null || host.length() == 0 )
296 host = getAddress();
297
298 if( port < 0 )
299 port = getPort();
300
301 return new Object[]{ host, new Integer(port), user};
302 }
303
304 void connect(String address, int port, String serverArgs) throws IOException{
305
306 if( address == null || address.length() == 0)
307 address = getAddress();
308
309 if( port < 0 )
310 port = getPort();
311
312 socket = new Socket(InetAddress.getByName(address), port);
313
314 new Thread(new ReturnListener(new BufferedReader(
315 new InputStreamReader( socket.getInputStream() ) ) ) ).start();
316
317 writer = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) );
318
319 writer.write( "connect " + serverArgs +
320 (serverArgs.trim().endsWith(";")?"\n":";\n") );
321 writer.flush();
322 }
323
324 String sendToServer(String msg){
325 try{
326 writer.write(msg + "\n");
327 writer.flush();
328 return "Sent [" + msg + "].";
329 }
330 catch(IOException e){
331 e.printStackTrace();
332 return "Problem sending message to server.";
333 }
334 }
335
336 String connectUsage(){
337 return "connect <host>:<port> <user>[/<password>][@<databasename>]";
338 }
339
340 String disconnect(){
341 close();
342 return "Disconnected from remote.";
343 }
344
345 void quit(){
346 close();
347 System.exit(0);
348 }
349
350 public boolean isConnected(){
351 return socket != null && socket.isConnected();
352 }
353
354 void close(){
355 if(reader != null){
356 try{ reader.close(); }catch(Throwable t){}
357 }
358 if(writer != null){
359 try{ writer.close(); }catch(Throwable t){}
360 }
361 if(socket != null){
362 try{ socket.close(); }catch(Throwable t){}
363 }
364 }
365
366 /***
367 * @return
368 */
369 public String getAddress() {
370 return address;
371 }
372
373 /***
374 * @return
375 */
376 public int getPort() {
377 return port;
378 }
379
380 /***
381 * @param string
382 */
383 public void setAddress(String string) {
384 address = string;
385 }
386
387 /***
388 * @param i
389 */
390 public void setPort(int i) {
391 port = i;
392 }
393
394 class ReturnListener implements Runnable{
395
396 BufferedReader reader;
397
398 ReturnListener( BufferedReader reader ){
399 super();
400
401 this.reader = reader;
402 }
403
404 /* (non-Javadoc)
405 * @see java.lang.Runnable#run()
406 */
407 public void run(){
408
409 // System.out.println("Started return listener.");
410
411 String line = null;
412 try{
413 boolean firstLine = true;
414 while( (line = reader.readLine() ) != null ){
415 if( firstLine ){
416 System.out.println();
417 firstLine = false;
418 }
419 System.out.println( " < " + line );
420 if( !reader.ready() ){
421 System.out.println();
422 System.out.print( " > " );
423 firstLine = true;
424 }
425 }
426 }
427 catch(IOException e){
428 throw new RuntimeException( e );
429 }
430
431 // System.out.println("Stopped return listener.");
432 }
433
434 }
435 }
This page was automatically generated by Maven