View Javadoc

1   /*
2    * Trip Tracker, a real-time position tracking system for the Internet.
3    * Copyright (C) 2006  Team Trip Tracker
4    *
5    * This program is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License as published by the
7    * Free Software Foundation; either version 2 of the License, or (at your
8    * option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful, but
11   * WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13   * General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License along
16   * with this program; if not, write to the Free Software Foundation, Inc.,
17   * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18   */
19  
20  package triptracker.server;
21  
22  import static triptracker.core.Protocol.*;
23  
24  import java.io.BufferedReader;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.io.PrintStream;
28  import java.net.Socket;
29  
30  import triptracker.core.User;
31  import triptracker.server.persistence.MySqlDB;
32  import triptracker.server.persistence.Persistence;
33  
34  /***
35   * This is for verifying the user with username and password before a special
36   * thread is started for the spesific kind of task wich he has come to this
37   * server to get fullfilled.
38   */
39  // TODO (jani) Generalize to extend ClientHandler, be single threaded.
40  public class CheckThread implements Runnable {
41  	private final Server server;
42  	private Persistence db = new MySqlDB();
43  	// TODO Add dynamic loading of persistency driver from the file
44  	// "Persistence.properties" in the triptracker/server/persistence/ folder.
45  
46  	private final Socket socket;
47  	private BufferedReader input;
48  	private PrintStream output;
49  
50  	private String username = "xx";
51  	private String password;
52  	private int userId = -1;
53  	private User user;
54  
55  	/***
56  	 * Default class constructor.
57  	 * 
58  	 * @param server parent server instance
59  	 * @param socket open socket for client communication
60  	 */
61  	public CheckThread(Server server, Socket socket) {
62  		this.server = server;
63  		this.socket = socket;
64  	}
65  
66  	/***
67  	 * Main thread entry point.
68  	 * 
69  	 * @see java.lang.Runnable#run()
70  	 */
71  	public void run() {
72  		boolean shutdown = true;
73  		try {
74  			input = new BufferedReader(new InputStreamReader(
75  					socket.getInputStream()));
76  			output = new PrintStream(socket.getOutputStream(), true);
77  			shutdown = messageHandler();
78  		} catch (IOException e) {
79  			// TODO Generalize this class to replace "null" with "this".
80  			// Integrate it with ClientHandler.
81  			server.socketErrorEvent(null, e); 
82  			log("Client terminated with IOException: " + e); // TODO MVC this.
83  		} catch (RuntimeException e) {
84  			log("Client terminated with RuntimeException: " + e); // TODO MVC this.
85  			e.printStackTrace();
86  		} finally {
87  			if (!shutdown) {
88  				return;
89  			}
90  				
91  			// Gracefully exit.
92  			try {
93  				socket.close();
94  			} catch (IOException e) {
95  				// Broadcast error to clients.
96  //				server.socketErrorEvent(this, e);  // TODO Fix MVC, generalize.
97  				log("Error closing client socket: " + e);
98  				e.printStackTrace();
99  			}
100 			log("Client disconnected");
101 		}
102 	}
103 
104 	/***
105 	 * Handles messages.
106 	 * 
107 	 * @throws IOException message handler dies on IOException
108 	 */
109 	private boolean messageHandler() throws IOException {
110 		int type;
111 		String message = input.readLine();
112 		String[] msg ;
113 		msg = message.split(DELIMITER);
114 		
115 		// Check for client type.
116 		type = Integer.parseInt(msg[0]);
117 		
118 		try {
119 			username = msg[1];
120 			password = msg[2];
121 		} catch (ArrayIndexOutOfBoundsException e) {
122 			log("Incorrectly typed login info.");
123 			throw e;  // Propagate the exception.
124 		}
125 
126 		userId = db.authUser(username, password);
127 		if (userId < 0) {
128 			send(output, AUTH_FAIL);
129 			log("Did not get verified!");
130 			return true;
131 		}
132 		
133 		send(output, AUTH_OK);
134 		log("Verified! User: " + username + ", Pass: " + password
135 				+ " Type: " + type);
136 		
137 		user = new User(userId, username, password);
138 		
139 		switch (type) {
140 		case SENDCLIENT:
141 			sendClientHandler();
142 			break;
143 		case MAPCLIENT:
144 			mapClientHandler();
145 			break;
146 		default:
147 			// TODO Generalize this class to replace "null" with "this".
148 			server.invalidMessage(null, message); 
149 			break;
150 		}
151 		
152 		return false;
153 	}
154 	
155 	/***
156 	 * Creates a new GPS client handler and starts the GPS handler thread.
157 	 * 
158 	 * @throws IOException on socket connection error
159 	 */
160 	private void sendClientHandler() throws IOException {
161 		GPSHandler handler = new GPSHandler(server, socket, user);
162 
163 		server.addGPSHandler(handler);
164 		
165 		handler.startHandler();
166 	}
167 	
168 	/***
169 	 * Creates a new map client handler and starts the map handler thread.
170 	 * 
171 	 * @throws IOException on socket connection error
172 	 */
173 	private void mapClientHandler() throws IOException {
174 		MapHandler handler = new MapHandler(server, socket, user);
175 		
176 		server.addMapHandler(handler);
177 		
178 		handler.startHandler();
179 	}
180 	
181 	/***
182 	 * For broadcasting messages to logfile.
183 	 * 
184 	 * @param message
185 	 */
186 	protected void log(String message) {
187 		server.log(username, message);
188 	}
189 }