001: /*
002: * This file is part of the QuickServer library
003: * Copyright (C) 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.impl;
016:
017: import org.quickserver.net.server.*;
018: import org.quickserver.net.*;
019: import org.quickserver.util.*;
020:
021: import java.io.*;
022: import java.net.*;
023: import java.util.*;
024: import java.util.logging.*;
025:
026: import java.nio.channels.*;
027:
028: public class BlockingClientHandler extends BasicClientHandler {
029: private static final Logger logger = Logger
030: .getLogger(BlockingClientHandler.class.getName());
031:
032: public BlockingClientHandler(int instanceCount) {
033: super (instanceCount);
034: }
035:
036: public BlockingClientHandler() {
037: super ();
038: }
039:
040: public void clean() {
041: logger.finest("Starting clean - " + getName());
042: super .clean();
043: logger.finest("Finished clean - " + getName());
044: }
045:
046: protected void finalize() throws Throwable {
047: clean();
048: super .finalize();
049: }
050:
051: public void handleClient(TheClient theClient) {
052: super .handleClient(theClient);
053: }
054:
055: protected void setInputStream(InputStream in) throws IOException {
056: this .in = in;
057: if (getDataMode(DataType.IN) == DataMode.STRING) {
058: b_in = null;
059: o_in = null;
060: bufferedReader = new BufferedReader(new InputStreamReader(
061: this .in));
062: } else if (getDataMode(DataType.IN) == DataMode.OBJECT) {
063: b_in = null;
064: bufferedReader = null;
065: o_in = new ObjectInputStream(in);
066: } else if (getDataMode(DataType.IN) == DataMode.BYTE
067: || getDataMode(DataType.IN) == DataMode.BINARY) {
068: o_in = null;
069: bufferedReader = null;
070: b_in = new BufferedInputStream(in);
071: }
072: }
073:
074: public BufferedReader getBufferedReader() {
075: return bufferedReader;
076: }
077:
078: public synchronized void closeConnection() {
079: if (connection == false)
080: return;
081: connection = false;
082: try {
083: if (hasEvent(ClientEvent.MAX_CON_BLOCKING) == false) {
084: notifyCloseOrLost();
085: }
086:
087: if (out != null) {
088: logger.finest("Closing output streams");
089: try {
090: out.flush();
091: } catch (IOException ioe) {
092: logger.finest("Flushing output streams failed: "
093: + ioe);
094: }
095:
096: if (socket != null && isSecure() == false) {
097: socket.shutdownOutput();
098: }
099: if (dataModeOUT == DataMode.OBJECT) {
100: o_out.close();
101: } else {
102: b_out.close();
103: }
104: if (out != null)
105: out.close();
106: }
107:
108: if (in != null) {
109: logger.finest("Closing input streams");
110: //if(socket!=null) socket.shutdownInput();
111:
112: if (dataModeIN == DataMode.STRING) {
113: if (bufferedReader != null)
114: bufferedReader.close();
115: } else if (dataModeIN == DataMode.OBJECT) {
116: o_in.close();
117: } else {
118: b_in.close();
119: }
120: if (in != null)
121: in.close();
122: }
123: } catch (IOException e) {
124: logger.warning("Error in closeConnection : " + e);
125: if (logger.isLoggable(Level.FINE)) {
126: logger
127: .fine("StackTrace:\n"
128: + MyString.getStackTrace(e));
129: }
130: } catch (NullPointerException npe) {
131: logger.fine("NullPointerException: " + npe);
132: if (logger.isLoggable(Level.FINE)) {
133: logger.fine("StackTrace:\n"
134: + MyString.getStackTrace(npe));
135: }
136: }
137: }
138:
139: public void run() {
140: if (unprocessedClientEvents.size() == 0) {
141: logger.finest("No unprocessed ClientEvents!");
142: return;
143: }
144:
145: ClientEvent currentEvent = (ClientEvent) unprocessedClientEvents
146: .remove(0);
147:
148: if (logger.isLoggable(Level.FINEST)) {
149: StringBuffer sb = new StringBuffer();
150: sb.append("Running ").append(getName());
151: sb.append(" using ");
152: sb.append(Thread.currentThread().getName());
153: sb.append(" for ");
154:
155: synchronized (clientEvents) {
156: if (clientEvents.size() > 1) {
157: sb.append(currentEvent + ", Current Events - "
158: + clientEvents);
159: } else {
160: sb.append(currentEvent);
161: }
162: }
163: logger.finest(sb.toString());
164: }
165:
166: if (currentEvent == null) {
167: threadEvent.set(null);
168: return;
169: } else {
170: threadEvent.set(currentEvent);
171: }
172:
173: try {
174: if (socket == null)
175: throw new SocketException("Socket was null!");
176:
177: prepareForRun();
178:
179: if (getThreadEvent() == ClientEvent.MAX_CON_BLOCKING) {
180: processMaxConnection(currentEvent);
181: }
182:
183: try {
184: if (getThreadEvent() == ClientEvent.RUN_BLOCKING) {
185: clientEventHandler.gotConnected(this );
186:
187: if (authorised == false) {
188: if (clientAuthenticationHandler == null
189: && authenticator == null) {
190: authorised = true;
191: } else {
192: if (clientAuthenticationHandler != null) {
193: AuthStatus authStatus = null;
194: do {
195: authStatus = processAuthorisation();
196: } while (authStatus == AuthStatus.FAILURE);
197:
198: if (authStatus == AuthStatus.SUCCESS)
199: authorised = true;
200: } else {
201: processAuthorisation();
202: }
203: }
204: }//end of authorised
205:
206: processRead();
207: }
208: } catch (SocketException e) {
209: appLogger.finest("SocketException - Client ["
210: + getHostAddress() + "]: " + e.getMessage());
211: //e.printStackTrace();
212: lost = true;
213: } catch (AppException e) {
214: //errors from Application
215: appLogger.finest("AppException "
216: + Thread.currentThread().getName() + ": "
217: + e.getMessage());
218: } catch (javax.net.ssl.SSLException e) {
219: lost = true;
220: if (Assertion.isEnabled()) {
221: appLogger.info("SSLException - Client ["
222: + getHostAddress() + "] "
223: + Thread.currentThread().getName() + ": "
224: + e);
225: } else {
226: appLogger.warning("SSLException - Client ["
227: + getHostAddress() + "]: " + e);
228: }
229: } catch (ConnectionLostException e) {
230: lost = true;
231: if (e.getMessage() != null)
232: appLogger.finest("Connection lost "
233: + Thread.currentThread().getName() + ": "
234: + e.getMessage());
235: else
236: appLogger.finest("Connection lost "
237: + Thread.currentThread().getName());
238: } catch (IOException e) {
239: lost = true;
240: appLogger.fine("IOError "
241: + Thread.currentThread().getName() + ": " + e);
242: } catch (AssertionError er) {
243: logger.warning("[AssertionError] " + getName() + " "
244: + er);
245: if (logger.isLoggable(Level.FINEST)) {
246: logger.finest("StackTrace "
247: + Thread.currentThread().getName() + ": "
248: + MyString.getStackTrace(er));
249: }
250: assertionSystemExit();
251: } catch (Error er) {
252: logger.warning("[Error] " + er);
253: if (logger.isLoggable(Level.FINEST)) {
254: logger.finest("StackTrace "
255: + Thread.currentThread().getName() + ": "
256: + MyString.getStackTrace(er));
257: }
258: if (Assertion.isEnabled()) {
259: assertionSystemExit();
260: }
261: lost = true;
262: } catch (RuntimeException re) {
263: logger.warning("[RuntimeException] "
264: + MyString.getStackTrace(re));
265: if (Assertion.isEnabled()) {
266: assertionSystemExit();
267: }
268: lost = true;
269: }
270:
271: if (getThreadEvent() != ClientEvent.MAX_CON_BLOCKING) {
272: notifyCloseOrLost();
273: }
274:
275: if (connection) {
276: logger.finest(Thread.currentThread().getName()
277: + " calling closeConnection()");
278: closeConnection();
279: }
280: } catch (javax.net.ssl.SSLException se) {
281: logger.warning("SSLException "
282: + Thread.currentThread().getName() + " - " + se);
283: } catch (IOException ie) {
284: logger.warning("IOError "
285: + Thread.currentThread().getName()
286: + " - Closing Client : " + ie);
287: } catch (RuntimeException re) {
288: logger.warning("[RuntimeException] " + getName() + " "
289: + Thread.currentThread().getName() + " - "
290: + MyString.getStackTrace(re));
291: if (Assertion.isEnabled()) {
292: assertionSystemExit();
293: }
294: } catch (Exception e) {
295: logger.warning("Error " + Thread.currentThread().getName()
296: + " - Event:" + getThreadEvent() + " - Socket:"
297: + socket + " : " + e);
298: logger.fine("StackTrace: " + getName() + "\n"
299: + MyString.getStackTrace(e));
300: if (Assertion.isEnabled()) {
301: assertionSystemExit();
302: }
303: } catch (Error e) {
304: logger.warning("Error " + Thread.currentThread().getName()
305: + " - Event:" + getThreadEvent() + " - Socket:"
306: + socket + " : " + e);
307: logger.fine("StackTrace: " + getName() + "\n"
308: + MyString.getStackTrace(e));
309: if (Assertion.isEnabled()) {
310: assertionSystemExit();
311: }
312: }
313:
314: synchronized (this ) {
315: try {
316: if (socket != null && socket.isClosed() == false) {
317: logger.finest("Closing Socket");
318: socket.close();
319: }
320: } catch (Exception re) {
321: logger.warning("Error closing Socket/Channel: " + re);
322: }
323: }//end synchronized
324:
325: willClean = true;
326: returnClientData();
327:
328: boolean returnClientHandler = false;
329: synchronized (lockObj) {
330: returnClientHandler = checkReturnClientHandler();
331: }
332:
333: if (returnClientHandler) {
334: returnClientHandler(); //return to pool
335: }
336: }
337:
338: protected boolean checkReturnClientHandler() {
339: return true;
340: }
341:
342: private void processRead() throws IOException,
343: ClassNotFoundException, AppException {
344: AuthStatus authStatus = null;
345:
346: String rec = null;
347: Object recObject = null; //v1.2
348: byte[] recByte = null; //1.4
349:
350: while (connection) {
351: try {
352: if (dataModeIN == DataMode.STRING) {
353: rec = bufferedReader.readLine();
354: if (rec == null) {
355: lost = true;
356: break;
357: }
358: if (getCommunicationLogging() && authorised == true) {
359: appLogger.fine("Got STRING ["
360: + getHostAddress() + "] : " + rec);
361: }
362: if (authorised == false)
363: authStatus = clientAuthenticationHandler
364: .handleAuthentication(this , rec);
365: else
366: clientCommandHandler.handleCommand(this , rec);
367: } else if (dataModeIN == DataMode.OBJECT) {
368: recObject = o_in.readObject();
369: if (recObject == null) {
370: lost = true;
371: break;
372: }
373: if (getCommunicationLogging() && authorised == true) {
374: appLogger.fine("Got OBJECT ["
375: + getHostAddress() + "] : "
376: + recObject.toString());
377: }
378: if (authorised == false)
379: authStatus = clientAuthenticationHandler
380: .handleAuthentication(this , recObject);
381: else
382: clientObjectHandler.handleObject(this ,
383: recObject);
384: } else if (dataModeIN == DataMode.BYTE) {
385: rec = readBytes();
386: if (rec == null) {
387: lost = true;
388: break;
389: }
390: if (getCommunicationLogging() && authorised == true) {
391: appLogger.fine("Got BYTE [" + getHostAddress()
392: + "] : " + rec);
393: }
394: if (authorised == false)
395: authStatus = clientAuthenticationHandler
396: .handleAuthentication(this , rec);
397: else
398: clientCommandHandler.handleCommand(this , rec);
399: } else if (dataModeIN == DataMode.BINARY) {
400: recByte = readBinary();
401: if (recByte == null) {
402: lost = true;
403: break;
404: }
405: if (getCommunicationLogging() && authorised == true) {
406: appLogger.fine("Got BINARY ["
407: + getHostAddress() + "] : "
408: + MyString.getMemInfo(recByte.length));
409: }
410: if (authorised == false)
411: authStatus = clientAuthenticationHandler
412: .handleAuthentication(this , recByte);
413: else
414: clientBinaryHandler.handleBinary(this , recByte);
415: } else {
416: throw new IllegalStateException(
417: "Incoming DataMode is not supported: "
418: + dataModeIN);
419: }
420: updateLastCommunicationTime();
421:
422: while (authStatus == AuthStatus.FAILURE)
423: authStatus = processAuthorisation();
424:
425: if (authStatus == AuthStatus.SUCCESS)
426: authorised = true;
427: } catch (SocketTimeoutException e) {
428: handleTimeout(e);
429: }
430: }//end of while
431: }
432:
433: protected void returnClientHandler() {
434: logger.finest(getName());
435: super .returnClientHandler();
436: }
437:
438: public void setDataMode(DataMode dataMode, DataType dataType)
439: throws IOException {
440: if (getDataMode(dataType) == dataMode)
441: return;
442:
443: appLogger.fine("Setting Type:" + dataType + ", Mode:"
444: + dataMode);
445: super .checkDataModeSet(dataMode, dataType);
446:
447: setDataModeBlocking(dataMode, dataType);
448: }
449:
450: private void setDataModeBlocking(DataMode dataMode,
451: DataType dataType) throws IOException {
452: logger.finest("ENTER");
453: if (dataMode == DataMode.STRING) {
454: if (dataType == DataType.OUT) {
455: if (dataModeOUT == DataMode.BYTE
456: || dataModeOUT == DataMode.BINARY) {
457: dataModeOUT = dataMode;
458: } else if (dataModeOUT == DataMode.OBJECT) {
459: dataModeOUT = dataMode;
460: o_out.flush();
461: o_out = null;
462: b_out = new BufferedOutputStream(out);
463: } else {
464: Assertion.affirm(false,
465: "Unknown DataType.OUT DataMode - "
466: + dataModeOUT);
467: }
468: Assertion.affirm(b_out != null,
469: "BufferedOutputStream is still null!");
470: } else if (dataType == DataType.IN) {
471: dataModeIN = dataMode;
472:
473: if (o_in != null) {
474: if (o_in.available() != 0)
475: logger
476: .warning("Data looks to be present in ObjectInputStream");
477: o_in = null;
478: }
479: if (b_in != null) {
480: if (b_in.available() != 0)
481: logger
482: .warning("Data looks to be present in BufferedInputStream");
483: b_in = null;
484: }
485: bufferedReader = new BufferedReader(
486: new InputStreamReader(in));
487: Assertion.affirm(bufferedReader != null,
488: "BufferedReader is still null!");
489: }
490: } else if (dataMode == DataMode.OBJECT) {
491: if (dataType == DataType.OUT) {
492: dataModeOUT = dataMode;
493: if (b_out != null) {
494: b_out.flush();
495: b_out = null;
496: }
497: o_out = new ObjectOutputStream(out);
498: Assertion.affirm(o_out != null,
499: "ObjectOutputStream is still null!");
500: } else if (dataType == DataType.IN) {
501: dataModeIN = dataMode;
502: if (b_in != null) {
503: if (b_in.available() != 0)
504: logger
505: .warning("Data looks to be present in BufferedInputStream");
506: b_in = null;
507: }
508: bufferedReader = null;
509: o_in = new ObjectInputStream(in); //will block
510: Assertion.affirm(o_in != null,
511: "ObjectInputStream is still null!");
512: }
513: } else if (dataMode == DataMode.BYTE
514: || dataMode == DataMode.BINARY) {
515: if (dataType == DataType.OUT) {
516: if (dataModeOUT == DataMode.STRING
517: || dataModeOUT == DataMode.BYTE
518: || dataModeOUT == DataMode.BINARY) {
519: dataModeOUT = dataMode;
520: } else if (dataModeOUT == DataMode.OBJECT) {
521: dataModeOUT = dataMode;
522: if (o_out != null) {
523: o_out.flush();
524: o_out = null;
525: }
526: b_out = new BufferedOutputStream(out);
527: } else {
528: Assertion.affirm(false,
529: "Unknown DataType.OUT - DataMode: "
530: + dataModeOUT);
531: }
532: Assertion.affirm(b_out != null,
533: "BufferedOutputStream is still null!");
534: } else if (dataType == DataType.IN) {
535: dataModeIN = dataMode;
536: if (o_in != null) {
537: if (o_in.available() != 0)
538: logger
539: .warning("Data looks to be present in ObjectInputStream");
540: o_in = null;
541: }
542: bufferedReader = null;
543: b_in = new BufferedInputStream(in);
544: Assertion.affirm(b_in != null,
545: "BufferedInputStream is still null!");
546: } else {
547: throw new IllegalArgumentException(
548: "Unknown DataType : " + dataType);
549: }
550: } else {
551: throw new IllegalArgumentException("Unknown DataMode : "
552: + dataMode);
553: }
554: }
555:
556: protected byte[] readInputStream() throws IOException {
557: return readInputStream(b_in);
558: }
559:
560: public void updateInputOutputStreams() throws IOException {
561: setInputStream(getSocket().getInputStream());
562: setOutputStream(getSocket().getOutputStream());
563: }
564:
565: public void setSocketChannel(SocketChannel socketChannel) {
566: if (true)
567: throw new IllegalStateException(
568: "Can't set in blocking mode!");
569: }
570:
571: public SocketChannel getSocketChannel() {
572: if (true)
573: throw new IllegalStateException(
574: "Can't get in blocking mode!");
575: return null;
576: }
577:
578: public void setSelectionKey(SelectionKey selectionKey) {
579: if (true)
580: throw new IllegalStateException(
581: "Can't set in blocking mode!");
582: }
583:
584: public SelectionKey getSelectionKey() {
585: if (true)
586: throw new IllegalStateException(
587: "Can't get in blocking mode!");
588: return null;
589: }
590:
591: public void registerForRead() throws IOException,
592: ClosedChannelException {
593: if (true)
594: throw new IllegalStateException(
595: "Can't register in blocking mode!");
596: }
597:
598: public void registerForWrite() throws IOException,
599: ClosedChannelException {
600: if (true)
601: throw new IllegalStateException(
602: "Can't register in blocking mode!");
603: }
604:
605: protected void setClientWriteHandler(ClientWriteHandler handler) {
606: if (true)
607: throw new IllegalStateException(
608: "Can't register in blocking mode!");
609: }
610: }
|