Main Page   Class Hierarchy   Compound List   File List   Compound Members  

ConnectionServer.java

00001 /*  Package Web Test Tools 
00002  *  Copyright (C) 2001 "Artur Hefczyc" <kobit@users.sourceforge.net>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU Lesser General Public License as published
00006  *  by the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00012  *  GNU Lesser General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Lesser General Public License
00015  *  along with this program; if not, write to the Free Software Foundation,
00016  *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  *
00018  * $Id: ConnectionServer.java,v 1.1 2002/11/29 15:18:30 kobit Exp $
00019  * $Author: kobit $
00020  * $Date: 2002/11/29 15:18:30 $
00021  */
00022 
00023 package wttools.remotecons;
00024 
00025 import java.net.Socket;
00026 import java.net.SocketException;
00027 import java.io.PrintWriter;
00028 import java.io.BufferedReader;
00029 import java.io.IOException;
00030 import java.io.InputStreamReader;
00031 import java.io.File;
00032 import java.io.FileReader;
00033 import java.io.ByteArrayOutputStream;
00034 import java.util.List;
00035 import java.util.ArrayList;
00036 import java.util.Collections;
00037 import java.util.StringTokenizer;
00038 import java.util.Date;
00039 import java.text.DateFormat;
00040 import wttools.remotecons.ifc.CommandHandlerIfc;
00041 import wttools.remotecons.ifc.LogIfc;
00042 
00066 public class ConnectionServer extends Thread {
00067 
00075   protected static List active_connections =
00076     Collections.synchronizedList(new ArrayList());
00084   protected Socket          my_socket = null;
00090   protected BufferedReader  inst = null;
00096   protected PrintWriter     out = null;
00106   protected List            comm_handl = null;
00113   protected LogIfc          log_impl = null;
00124   protected boolean         prompt = true;
00142   protected boolean         echo = true;
00143 
00153   public ConnectionServer(Socket socket, List command_handlers)
00154     throws IOException
00155   {
00156     comm_handl = command_handlers;
00157     if (comm_handl == null) {
00158       comm_handl = new ArrayList();
00159     } // end of if (comm_handl == null)
00160     comm_handl.add(0, new CommandHandlerImpl());
00161     comm_handl.add(0, new InternalCommands());
00162     
00163     my_socket = socket;
00164     inst =
00165       new BufferedReader(new InputStreamReader(my_socket.getInputStream()));
00166     out = new PrintWriter(my_socket.getOutputStream(), true);
00167     setDaemon(true);
00168     start();
00169     active_connections.add(this);
00170   }
00171 
00177   public void run() {
00178     log("Connection server started for client: "+my_socket.getInetAddress().getHostAddress());
00179     while (inst != null) {
00180       try {
00181         if (prompt) {
00182           out.print(my_socket.getLocalAddress().getHostAddress()+" << "); out.flush();
00183         } // end of if (prompt)
00184         String line = "";
00185         if (echo) {
00186           char chr = (char)inst.read();
00187           while (chr != '\n') {
00188             if (chr != '\r') {
00189               line += chr;
00190             } // end of if (chr != '\r')
00191             out.print(chr); out.flush();
00192             chr = (char)inst.read();
00193           } // end of while (chr != '\n')
00194           out.print(chr); out.flush();
00195         } // end of if (echo)
00196         else {
00197           line = inst.readLine();
00198         } // end of if (echo)else
00199         
00200         log("Received command: "+line);
00201         if (!processCommand(line) && out != null && !line.equals("")) {
00202           out.println(getClass().getName()+" >> Command '"+line+"' not understood.");
00203         } // end of if (!processInternalCommand(line) && !comm_found)
00204       }
00205       catch (SocketException e) {
00206         // Probably someone closed this connection
00207         out = null;
00208         inst = null;
00209         my_socket = null;
00210       } // end of catch
00211       catch (IOException e) {
00212         e.printStackTrace();
00213         out = null;
00214         inst = null;
00215         my_socket = null;
00216       } // end of try-catch
00217     } // end of while (inst != null)
00218     active_connections.remove(this);
00219   }
00220 
00235   protected void asyncMessage(String msg) {
00236     out.print(msg); out.flush();
00237   }
00238 
00247   protected boolean processCommand(String line) {
00248     boolean comm_found = false;
00249     for (int i = 0; i < comm_handl.size(); i++) {
00250       String res = ((CommandHandlerIfc)comm_handl.get(i)).handleCommand(line);
00251       if (res != null && !res.equals("")) {
00252         if (out != null) {
00253           out.print(res); out.flush();
00254         } // end of if (out != null)
00255         prompt = res.endsWith("\r\n");
00256         comm_found = true;
00257       } // end of if (res != null && !res.equals(""))
00258     } // end of for (int i = 0; i < comm_handl.size(); i++)
00259     return comm_found;
00260   }
00261 
00267   protected void log(String msg) {
00268     if (log_impl != null) {
00269       log_impl.log(msg);
00270     } // end of if (log != null)
00271   }
00272 
00280   class InternalCommands implements CommandHandlerIfc {
00281 
00282     protected String last_command = null;
00283 
00284     public String handleCommand(String comm) {
00285       String ret_res = null;
00286       if (comm.trim().startsWith("echo")) {
00287         echo = !echo;
00288         ret_res = "Echo your command is now in '"+echo+"' mode\r\n";
00289       } // end of if (comm.trim().startsWith("echo"))
00290       if (comm.equals("quit")) {
00291         ret_res = "OK";
00292         log("'quit' received, closing connection...");
00293         out.println("Bye");
00294         out.close();
00295         out = null;
00296         try {
00297           inst.close();
00298           inst = null;
00299           my_socket.close();
00300           my_socket = null;
00301         } catch (Exception e) {
00302           e.printStackTrace();
00303           out = null;
00304           inst = null;
00305           my_socket = null;
00306         } // end of try-catch
00307       } // end of if (line.equals("quit"))
00308       if (comm.startsWith("help")) {
00309         ret_res = "";
00310         if (comm.trim().equals("help")) {
00311           for (int i = 0; i < comm_handl.size(); i++) {
00312             String res = ((CommandHandlerIfc)comm_handl.get(i)).help();
00313             ret_res += comm_handl.get(i).getClass().getName()+" >> "+res;
00314           } // end of for (int i = 0; i < comm_handl.size(); i++)
00315         } // end of if (comm.trim().equals("help"))
00316         else {
00317           for (int i = 0; i < comm_handl.size(); i++) {
00318             String res = ((CommandHandlerIfc)comm_handl.get(i)).help(comm.substring(5));
00319             ret_res += comm_handl.get(i).getClass().getName()+" >> "+res;
00320           } // end of for (int i = 0; i < comm_handl.size(); i++)
00321         } // end of if (comm.trim().equals("help"))else
00322       } // end of if (comm.startsWith("help"))
00323       if (comm.trim().equals("who")) {
00324         ret_res = "\r\n";
00325         for (int i = 0; i < active_connections.size(); i++) {
00326           ConnectionServer cs = (ConnectionServer)active_connections.get(i);
00327           if (cs.my_socket == my_socket) {
00328             ret_res += "this:  ";
00329           } // end of if (active_connections.get(i) == this)
00330           else {
00331             ret_res += "other: ";
00332           } // end of if (active_connections.get(i) == this)else
00333           ret_res += ""+i+". "+cs.my_socket+"\r\n";
00334         } // end of for (int i = 0; i < active_connections.size(); i++)
00335       } // end of if (comm.trim().equals("who"))
00336       if (comm.trim().startsWith("ls")) {
00337         StringTokenizer stt = null;
00338         if (comm.trim().length() > 2) {
00339           stt = new StringTokenizer(comm.substring(2));
00340         } // end of if (comm.trim().length() > 2)
00341         else {
00342           stt = new StringTokenizer(".");
00343         } // end of if (comm.trim().length() > 2)else
00344         while (stt.hasMoreTokens()) {
00345           File dir = new File(stt.nextToken());
00346           File[] files = dir.listFiles();
00347           if (files != null && files.length > 0) {
00348             for (int i = 0; i < files.length; i++) {
00349               out.println(buildFileString(files[i]));
00350             } // end of for (int i = 0; i < files.length; i++)
00351             out.println("\r\ntotal "+files.length);
00352           } // end of if (files != null && files.length > 0)
00353           else {
00354             out.println(dir.toString()+" is not a directory or");
00355             out.println("this directory does not contains any antries.");
00356           } // end of else
00357         } // end of while (stt.hasMoreTokens())
00358         ret_res = "\r\n";
00359       } // end of if (comm.trim().startsWith("ls"))
00360       if (comm.trim().startsWith("show")) {
00361         if (comm.trim().length() < 5) {
00362           ret_res = "Wrong number of arguments. I need file name here.\r\n";
00363         } // end of if (comm.trim().length() == 5)
00364         else {
00365           StringTokenizer stt = new StringTokenizer(comm.substring(5));
00366           while (stt.hasMoreTokens()) {
00367             File ff = new File(stt.nextToken());
00368             if (ff.exists()) {
00369               try {
00370                 BufferedReader brin = new BufferedReader(new FileReader(ff));
00371                 String line = brin.readLine();
00372                 while (line != null) {
00373                   out.println(line);
00374                   line = brin.readLine();
00375                 } // end of while (line != null)
00376                 brin.close();
00377                 ret_res = "  -----  End of file "+ff.toString()+" -----\r\n";
00378               } catch (Exception e) {
00379                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
00380                 PrintWriter pw = new PrintWriter(baos, false);
00381                 e.printStackTrace(pw);
00382                 pw.flush();
00383                 ret_res = baos.toString();
00384                 pw.close();
00385               } // end of try-catch
00386             } // end of if (ff.exists())
00387             else {
00388               ret_res = "File "+ff.toString()+" does not exists!\r\n";
00389             } // end of if (ff.exists())else
00390           } // end of while (stt.hasMoreTokens())
00391         } // end of if (comm.trim().length() == 5)else
00392       } // end of if (comm.trim().startsWith("show"))
00393       if (comm.trim().startsWith("close")) {
00394         int no = -1;
00395         try {
00396           no = Integer.parseInt(comm.substring(6).trim());
00397           if (no >= 0 && no < active_connections.size()) {
00398             ConnectionServer cs = (ConnectionServer)active_connections.get(no);
00399             out.print("closing "+cs.my_socket+" ... "); out.flush();
00400             cs.processCommand("quit");
00401             active_connections.remove(cs);
00402             ret_res = "OK\r\n";
00403           } // end of if (no >= 0 && no < active_connections.size())
00404           else {
00405             ret_res = "Argument out of range. Check valid ranges with 'who' command.";
00406           } // end of if (no >= 0 && no < active_connections.size())else
00407         }
00408         catch (StringIndexOutOfBoundsException e) {
00409           ret_res = "Wrong number of arguments. I need integer number here.";
00410         } // end of catch
00411         catch (NumberFormatException e) {
00412           ret_res = "Bad argument to 'close' command. I need integer number here.";
00413         } // end of try-catch
00414       } // end of if (comm.trim().startsWith("close"))
00415       return ret_res;
00416     }
00417 
00418     protected String buildFileString(File ff) {
00419       StringBuffer res = new StringBuffer(80);
00420       res.append(setForTrueOrFalse(ff.isDirectory(), "d", "-"));
00421       res.append(setForTrueOrFalse(ff.canRead(), "r", "-"));
00422       res.append(setForTrueOrFalse(ff.canWrite(), "w", "-"));
00423       res.append(setForTrueOrFalse(ff.isHidden(), "h", "-"));
00424       res.append("   "+ff.length());
00425       while (res.length() < 17) {
00426         res.append(' ');
00427       } // end of while (res.length() < 17)
00428       DateFormat dt = DateFormat.getDateInstance();
00429       res.append("   "+dt.format(new Date(ff.lastModified())));
00430       res.append("   "+ff.getName());
00431       res.append(setForTrueOrFalse(ff.isDirectory(), "/", ""));
00432       return res.toString();
00433     }
00434 
00435     protected String setForTrueOrFalse(boolean cond, String for_true, String for_false) {
00436       if (cond) {
00437         return for_true;
00438       } // end of if (cond)
00439       else {
00440         return for_false;
00441       } // end of if (cond)else
00442     }
00443 
00444     public String help() {
00445       String help_text =
00446         "\r\n"+
00447         "  echo           - switch 'echo' mode (for windows telnet is really needed)\r\n"+
00448         "  quit           - close connection to server\r\n"+
00449         "  who            - list all active connections\r\n"+
00450         "  close n        - close active connection number 'n'\r\n"+
00451         "  help [command] - display this message info\r\n"+
00452         "  ls [dir]*      - list content of given directory\r\n"+
00453         "  show filename  - display content of given file\r\n";
00454       return help_text;
00455     }
00456 
00457     public String help(String command) {
00458       return "";
00459     }
00460 
00461     public CommandHandlerIfc getInstance() {
00462       return new InternalCommands();
00463     }
00464     
00465   }
00466   
00467   
00468 }// ConnectionServer
00469 /*
00470  * Changes in file:
00471  *
00472  * $Log: ConnectionServer.java,v $
00473  * Revision 1.1  2002/11/29 15:18:30  kobit
00474  * Refactoring packages, thanks to RefactorIT
00475  *
00476  * Revision 1.1  2002/03/21 09:57:27  kobit
00477  * 1. Small but important redesign:
00478  *    - package 'remotecons.wttools' was removed and all classes
00479  *      were moved to 'remotecons' package
00480  * 2. Added 'asyncMessage' to provide sending messages to remote clients
00481  *    in asynchronous mode
00482  *
00483  * Revision 1.14  2002/01/23 15:49:24  kobit
00484  * Java doc for all classes finishedant clean dist
00485  *
00486  * Revision 1.13  2002/01/21 16:30:19  kobit
00487  * Commenting out code in progress
00488  *
00489  * Revision 1.12  2002/01/18 14:18:46  kobit
00490  * Next part of javadoc documentation
00491  *
00492  * Revision 1.11  2002/01/17 22:37:44  kobit
00493  * Javadoc comments for classes in progress...
00494  *
00495  * Revision 1.10  2002/01/14 17:02:02  kobit
00496  * Changed interface to CommandHandlersIfc
00497  *
00498  * Revision 1.9  2002/01/13 18:09:29  kobit
00499  * Added methods for closing remote console
00500  *
00501  * Revision 1.8  2002/01/13 17:27:13  kobit
00502  * Corrected interface for external command handlers
00503  *
00504  * Revision 1.7  2002/01/13 17:14:45  kobit
00505  * Added commands: ls, show file, echo and support for windows telnet
00506  *
00507  * Revision 1.6  2002/01/12 16:19:21  kobit
00508  * Started code for command 'show filename'
00509  *
00510  * Revision 1.5  2002/01/12 12:54:22  kobit
00511  * Bug in closing connection command fixed
00512  *
00513  * Revision 1.4  2002/01/12 12:25:34  kobit
00514  * Almost finished basic code
00515  *
00516  *
00517  */

Generated on Thu Dec 19 21:00:47 2002 for WTTools - Remote Console by doxygen1.3-rc2