001: /*
002: * This file is part of the QuickServer library
003: * Copyright (C) 2003-2005 QuickServer.org
004: *
005: * Use, modification, copying and distribution of this software is subject to
006: * the terms and conditions of the GNU Lesser General Public License.
007: * You should have received a copy of the GNU LGP License along with this
008: * library; if not, you can download a copy from <http://www.quickserver.org/>.
009: *
010: * For questions, suggestions, bug-reports, enhancement-requests etc.
011: * visit http://www.quickserver.org
012: *
013: */
014:
015: package org.quickserver.net.server;
016:
017: import java.io.BufferedInputStream;
018: import java.io.BufferedOutputStream;
019: import java.io.BufferedReader;
020: import java.io.BufferedWriter;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.ObjectInputStream;
024: import java.io.ObjectOutputStream;
025: import java.io.OutputStream;
026: import java.io.OutputStreamWriter;
027: import java.net.InetAddress;
028: import java.net.Socket;
029: import java.net.SocketException;
030: import java.nio.channels.ClosedChannelException;
031: import java.nio.channels.SelectionKey;
032: import java.nio.channels.SocketChannel;
033: import java.security.KeyManagementException;
034: import java.security.NoSuchAlgorithmException;
035: import java.sql.Connection;
036: import java.util.Date;
037: import java.util.logging.Level;
038: import java.util.logging.Logger;
039: import javax.net.ssl.SSLSocket;
040: import org.quickserver.util.MyString;
041:
042: /**
043: * Interface that represents client handle in QuickServer.
044: * <p> This class is used by {@link QuickServer} to handle each new client
045: * connected. This class is responsible to handle client sockets. It can operate
046: * in both blocking mode and non-blocking mode (java nio) based on its
047: * implementation.</p>
048: * @author Akshathkumar Shetty
049: */
050: public interface ClientHandler extends Runnable {
051:
052: /**
053: * Adds the ClientEvent.
054: * @since 1.4.5
055: */
056: void addEvent(ClientEvent event);
057:
058: /**
059: * Removes the ClientEvent.
060: * @since 1.4.5
061: */
062: void removeEvent(ClientEvent event);
063:
064: void clean();
065:
066: /** Closes client socket associated. */
067: void closeConnection();
068:
069: /**
070: * Force the closing of the client by closing the associated socket.
071: * @since 1.3.3
072: */
073: void forceClose() throws IOException;
074:
075: /**
076: * Returns client SelectionKey associated, if any.
077: * @since 1.4.5
078: */
079: Logger getAppLogger();
080:
081: /**
082: *Returns the {@link java.io.BufferedInputStream} associated with
083: * the Client being handled. Can be null if not available at the time of method call.
084: * @see #getBufferedOutputStream
085: * @since 1.4.6
086: */
087: BufferedInputStream getBufferedInputStream();
088:
089: /**
090: * Returns the {@link java.io.BufferedOutputStream} associated with
091: * the Client being handled. Can be null if not available at the time of method call.
092: * @see #getBufferedInputStream
093: * @since 1.4.6
094: */
095: BufferedOutputStream getBufferedOutputStream();
096:
097: /**
098: * Returns the {@link java.io.BufferedReader} associated with
099: * the Client being handled. Note that this is only available under blocking mode.
100: * @see #getBufferedWriter
101: */
102: BufferedReader getBufferedReader();
103:
104: /**
105: * Returns Charset to be used for String decoding and encoding..
106: * @see #setCharset
107: * @since 1.4.5
108: */
109: String getCharset();
110:
111: /**
112: * Returns the date/time when the client socket was assigned to this
113: * ClientHanlder. If no client is currently connected it will return
114: * <code>null</code>
115: * @since 1.3.1
116: */
117: Date getClientConnectedTime();
118:
119: /**
120: * Returns the ClientData object associated with this ClientHandler,
121: * if not set will return <code>null</code>
122: * @see ClientData
123: */
124: ClientData getClientData();
125:
126: /**
127: * Returns the communication logging flag.
128: * @see #setCommunicationLogging
129: * @since 1.3.2
130: */
131: boolean getCommunicationLogging();
132:
133: /**
134: * Returns the {@link DataMode} of the ClientHandler for the
135: * DataType.
136: * @since 1.2
137: */
138: DataMode getDataMode(DataType dataType);
139:
140: /**
141: * Returns cached socket host ip address.
142: * @since 1.4.5
143: */
144: String getHostAddress();
145:
146: /**
147: * Returns the {@link java.io.InputStream} associated with
148: * the Client being handled.
149: */
150: InputStream getInputStream();
151:
152: /**
153: * Returns the date/time when the client socket last sent a data to this
154: * ClientHanlder. If no client is currently connected it will return
155: * <code>null</code>
156: * @since 1.3.3
157: */
158: Date getLastCommunicationTime();
159:
160: /**
161: * Returns message to be displayed to the client when maximum
162: * connection reaches.
163: * @since 1.4.5
164: */
165: String getMaxConnectionMsg();
166:
167: /**
168: * Returns the ClientHandler name
169: * @since 1.4.6
170: */
171: String getName();
172:
173: /**
174: * Returns the {@link java.io.ObjectInputStream} associated with
175: * the Client being handled.
176: * It will be <code>null</code> if no {@link ClientObjectHandler}
177: * was set in {@link QuickServer}.
178: * @see #getObjectOutputStream
179: * @since 1.2
180: */
181: ObjectInputStream getObjectInputStream();
182:
183: /**
184: * Returns the {@link java.io.ObjectOutputStream} associated with
185: * the Client being handled.
186: * It will be <code>null</code> if no {@link ClientObjectHandler}
187: * was set in {@link QuickServer}.
188: * @see #getObjectInputStream
189: * @since 1.2
190: */
191: ObjectOutputStream getObjectOutputStream();
192:
193: /**
194: * Returns the {@link java.io.OutputStream} associated with
195: * the Client being handled.
196: * @see #setOutputStream
197: */
198: OutputStream getOutputStream();
199:
200: /**
201: * Returns client SelectionKey associated, if any.
202: * @since 1.4.5
203: */
204: SelectionKey getSelectionKey();
205:
206: /**
207: * Returns the QuickServer object that created it.
208: */
209: QuickServer getServer();
210:
211: /** Returns client socket associated. */
212: Socket getSocket();
213:
214: /**
215: * Returns client socket channel associated, if any.
216: * @since 1.4.5
217: */
218: SocketChannel getSocketChannel();
219:
220: /**
221: * Returns the Client socket timeout in milliseconds.
222: * @see #setTimeout
223: * @since 1.4.5
224: */
225: int getTimeout();
226:
227: /**
228: * Associates the ClientHanlder with the client encapsulated by
229: * <code>theClient</code>.
230: * @param theClient object that encapsulates client socket
231: * and its configuration details.
232: */
233: void handleClient(TheClient theClient);
234:
235: /**
236: * Checks if this client has the event.
237: * @since 1.4.5
238: */
239: boolean hasEvent(ClientEvent event);
240:
241: /**
242: * Returns the ClientHandler detailed information.
243: * If ClientData is present and is ClientIdentifiable will return ClientInfo else
244: * it will return Clients InetAddress and port information.
245: */
246: String info();
247:
248: /**
249: * Checks if the passed ClientEvent is the one next for
250: * processing if a thread is allowed through this object.
251: * @since 1.4.6
252: */
253: boolean isClientEventNext(ClientEvent clientEvent);
254:
255: /**
256: * Checks if the client is closed.
257: * @since 1.4.1
258: */
259: boolean isClosed();
260:
261: /**
262: * Checks if the client is still connected.
263: * @exception SocketException if Socket is not open.
264: * @since 1.4.5
265: */
266: boolean isConnected() throws SocketException;
267:
268: /**
269: * Checks if the client is still connected and if socket is open. This is same as isConnected()
270: * but does not throw SocketException.
271: * @since 1.4.6
272: */
273: boolean isOpen();
274:
275: /**
276: * Returns flag indicating if the client is connected in secure mode
277: * (SSL or TLS).
278: * @return secure flag
279: * @since 1.4.0
280: */
281: boolean isSecure();
282:
283: /**
284: * Makes current Client connection to secure protocol based on the
285: * secure configuration set to the server. This method will just call
286: * <code>makeSecure(false, false, true, null)</code>.
287: * @throws IOException
288: * @throws NoSuchAlgorithmException
289: * @throws KeyManagementException
290: * @since 1.4.0
291: */
292: void makeSecure() throws IOException, NoSuchAlgorithmException,
293: KeyManagementException;
294:
295: /**
296: * Makes current Client connection to secure protocol.
297: * @param useClientMode falg if the socket should start its first handshake in "client" mode.
298: * @param needClientAuth flag if the clients must authenticate themselves.
299: * @param autoClose close the underlying socket when this socket is closed
300: * @param protocol the standard name of the requested protocol. If <code>null</code> will use the protocol set in secure configuration of the server.
301: * @throws IOException
302: * @throws NoSuchAlgorithmException
303: * @throws KeyManagementException
304: * @since 1.4.0
305: */
306: void makeSecure(boolean useClientMode, boolean needClientAuth,
307: boolean autoClose, String protocol) throws IOException,
308: NoSuchAlgorithmException, KeyManagementException;
309:
310: /**
311: * Makes current Client connection to secure protocol.
312: * This method will just call <code>makeSecure(false, false, true, protocol)</code>.
313: * @throws IOException
314: * @throws NoSuchAlgorithmException
315: * @throws KeyManagementException
316: * @since 1.4.0
317: */
318: void makeSecure(String protocol) throws IOException,
319: NoSuchAlgorithmException, KeyManagementException;
320:
321: /**
322: * Read the binary input. This will block till some data is
323: * received from the stream. Allowed only when
324: * <code>DataType.IN</code> is in <code>DataMode.BINARY</code> mode.
325: * @return The data as a String
326: * @since 1.4
327: */
328: byte[] readBinary() throws IOException;
329:
330: /**
331: * Read the byte input. This will block till some data is
332: * received from the stream. Allowed only when
333: * <code>DataType.IN</code> is in <code>DataMode.BYTE</code> mode.
334: * @return The data as a String
335: * @since 1.3.2
336: */
337: String readBytes() throws IOException;
338:
339: /**
340: * Register OP_READ with the SelectionKey associated with the channel. If SelectionKey is
341: * not set then it registers the channel with the Selector.
342: * @since 1.4.5
343: */
344: void registerForRead() throws IOException, ClosedChannelException;
345:
346: /**
347: * Register OP_WRITE with the SelectionKey associated with the channel.
348: * @since 1.4.5
349: */
350: void registerForWrite() throws IOException, ClosedChannelException;
351:
352: void run();
353:
354: /**
355: * Send a binary data to the connected client.
356: * If client is not connected it will just return.
357: * @since 1.4
358: * @exception IOException
359: * if Socket IO Error or Socket was closed by the client.
360: */
361: void sendClientBinary(byte[] data) throws IOException;
362:
363: /**
364: * Send a binary data to the connected client.
365: * If client is not connected it will just return.
366: * @since 1.4.5
367: * @exception IOException
368: * if Socket IO Error or Socket was closed by the client.
369: */
370: void sendClientBinary(byte[] data, int off, int len)
371: throws IOException;
372:
373: /**
374: * Send a String message to the connected client as a string of bytes.
375: * If client is not connected it will just return.
376: * @since 1.3.1
377: * @exception IOException
378: * if Socket IO Error or Socket was closed by the client.
379: */
380: void sendClientBytes(String msg) throws IOException;
381:
382: /**
383: * Send a String message to the connected client
384: * it adds a new line{\r\n} to the end of the string.
385: * If client is not connected it will just return.
386: * @exception IOException
387: * if Socket IO Error or Socket was closed by the client.
388: */
389: void sendClientMsg(String msg) throws IOException;
390:
391: /**
392: * Send a Object message to the connected client. The message Object
393: * passed must be serializable. If client is not connected it
394: * will just return.
395: * @exception IOException if Socket IO Error or Socket was closed
396: * by the client.
397: * @exception IllegalStateException if DataType.OUT is not in
398: * DataMode.OBJECT
399: * @see #setDataMode
400: * @since 1.2
401: */
402: void sendClientObject(Object msg) throws IOException;
403:
404: /**
405: * Send a String message to the logger associated with
406: * {@link QuickServer#getAppLogger} with Level.INFO as its level.
407: */
408: void sendSystemMsg(String msg);
409:
410: /**
411: * Send a String message to the logger associated with
412: * {@link QuickServer#getAppLogger}.
413: * @since 1.2
414: */
415: void sendSystemMsg(String msg, Level level);
416:
417: /**
418: * Sets the Charset to be used for String decoding and encoding.
419: * @param charset to be used for String decoding and encoding
420: * @see #getCharset
421: * @since 1.4.5
422: */
423: void setCharset(String charset);
424:
425: /**
426: * Sets the communication logging flag.
427: * @see #getCommunicationLogging
428: * @since 1.3.2
429: */
430: void setCommunicationLogging(boolean communicationLogging);
431:
432: /**
433: * Sets the {@link DataMode} for the ClientHandler
434: *
435: * Note: When mode is DataMode.OBJECT and type is DataType.IN
436: * this call will block until the client ObjectOutputStream has
437: * written and flushes the header.
438: * @since 1.2
439: * @exception IOException if mode could not be changed.
440: * @param dataMode mode of data exchange - String or Object.
441: * @param dataType type of data for which mode has to be set.
442: */
443: void setDataMode(DataMode dataMode, DataType dataType)
444: throws IOException;
445:
446: /**
447: * Sets message to be displayed when maximum connection reaches.
448: * @since 1.4.5
449: */
450: void setMaxConnectionMsg(String msg);
451:
452: /**
453: * Set the {@link java.io.OutputStream} associated with
454: * the Client being handled.
455: * @since 1.1
456: * @see #getOutputStream
457: * @exception IOException if ObjectOutputStream could not be created.
458: */
459: void setOutputStream(OutputStream out) throws IOException;
460:
461: /**
462: * Sets flag indicating if the client is connected in secure mode
463: * (SSL or TLS).
464: * @param secure
465: * @since 1.4.0
466: */
467: void setSecure(boolean secure);
468:
469: /**
470: * Sets client SelectionKey associated, if any.
471: * @since 1.4.5
472: */
473: void setSelectionKey(SelectionKey selectionKey);
474:
475: /**
476: * Returns client socket associated.
477: * @since 1.4.0
478: * @see #updateInputOutputStreams
479: */
480: void setSocket(Socket socket);
481:
482: /**
483: * Sets client socket channel associated, if any.
484: * @since 1.4.5
485: */
486: void setSocketChannel(SocketChannel socketChannel);
487:
488: /**
489: * Sets the client socket's timeout.
490: * @param time client socket timeout in milliseconds.
491: * @see #getTimeout
492: * @since 1.4.5
493: */
494: void setTimeout(int time);
495:
496: /**
497: * Returns the ClientHandler information.
498: * If ClientData is present and is ClientIdentifiable will return ClientInfo else
499: * it will return Clients InetAddress and port information.
500: */
501: String toString();
502:
503: /**
504: * Updates the InputStream and OutputStream for the ClientHandler for the
505: * set Socket.
506: * @since 1.4.0
507: * @see #setSocket
508: */
509: void updateInputOutputStreams() throws IOException;
510:
511: /**
512: * Updates the last communication time for this client
513: * @since 1.3.3
514: */
515: void updateLastCommunicationTime();
516:
517: /**
518: * Returns the {@link java.sql.Connection} object for the
519: * DatabaseConnection that is identified by id passed. If id passed
520: * does not match with any connection loaded by this class it will
521: * return <code>null</code>.
522: * This just calls <code>getServer().getDBPoolUtil().getConnection(id)</code>
523: * @since 1.3
524: * @deprecated as of v1.4.5 use <code>getServer().getDBPoolUtil().getConnection(id)</code>
525: */
526: Connection getConnection(String id) throws Exception;
527:
528: /**
529: * Checks if the client is still connected.
530: * @exception SocketException if Socket is not open.
531: * @deprecated since 1.4.5 Use {@link #isConnected}
532: */
533: boolean isConected() throws SocketException;
534:
535: /**
536: * Send a String message to the system output stream.
537: * @param newline indicates if new line required at the end.
538: * @deprecated Use {@link #sendSystemMsg(java.lang.String)},
539: * since it uses Logging.
540: */
541: void sendSystemMsg(String msg, boolean newline);
542:
543: /**
544: * Returns the {@link java.io.BufferedWriter} associated with
545: * the Client being handled.
546: * @deprecated since 1.4.5 use getOutputStream()
547: */
548: BufferedWriter getBufferedWriter();
549: }
|