001: // PushCacheListener.java
002: // $Id: PushCacheListener.java,v 1.2 2001/10/05 08:07:52 ylafon Exp $
003: // (c) COPYRIGHT MIT, INRIA and Keio, 2001.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.www.protocol.http.cache.push;
007:
008: import java.lang.reflect.Method;
009: import java.lang.reflect.InvocationTargetException;
010:
011: import java.net.Socket;
012: import java.net.ServerSocket;
013:
014: import java.util.ArrayList;
015:
016: /**
017: * PushCacheListener
018: * Accepts incoming connections on specified port number and creates
019: * PushCacheHandler objects to handle dialogue with client.
020: *
021: * @author Paul Henshaw, The Fantastic Corporation, Paul.Henshaw@fantastic.com
022: * @version $Revision: 1.2 $
023: * $Id: PushCacheListener.java,v 1.2 2001/10/05 08:07:52 ylafon Exp $
024: */
025: public class PushCacheListener extends Thread {
026: private int _port_number;
027: private ServerSocket _socket = null;
028: private boolean _running = false;
029: private ArrayList _list = null;
030: private ShutdownHook _hook = null;
031: private boolean _cleaning = false;
032:
033: public class ShutdownHook extends Thread {
034: public ShutdownHook() {
035: // NULL
036: }
037:
038: public void run() {
039: try {
040: stopRunning();
041: } catch (Exception e) {
042: e.printStackTrace();
043: }
044: }
045: }
046:
047: /**
048: * Register a hanlder with the listener.
049: * stopRunning will be called on all registered handlers when
050: * the listener is stopped.
051: */
052: protected void registerHandler(PushCacheHandler handler) {
053: _list.add(handler);
054: }
055:
056: /**
057: * Reregister a handler from the listener
058: */
059: protected void deregisterHandler(PushCacheHandler handler) {
060: if (!_cleaning) {
061: _list.remove(handler);
062: }
063: }
064:
065: /**
066: * Close sockets, stop handlers.
067: */
068: protected void cleanup() {
069: if (_cleaning) {
070: return;
071: }
072: _cleaning = true;
073: try {
074: _running = false;
075: if (_socket != null) {
076: _socket.close();
077: }
078: _socket = null;
079: } catch (java.io.IOException e) {
080: // IGNORE
081: }
082:
083: for (int i = 0; i < _list.size(); i++) {
084: PushCacheHandler handler = (PushCacheHandler) _list.get(i);
085: handler.stopRunning();
086: }
087: _list.clear();
088: _list = null;
089: }
090:
091: /**
092: * Request this thread to exit gracefully
093: */
094: public void stopRunning() {
095: cleanup();
096: }
097:
098: /**
099: * Listen for connections, creating a handler for each new connection
100: */
101: public void run() {
102: _running = true;
103: try {
104: while (_running) {
105: Socket s = _socket.accept();
106: PushCacheHandler handler = new PushCacheHandler(this , s);
107: handler.start();
108: }
109: } catch (Exception e) {
110: e.printStackTrace();
111: }
112: cleanup();
113: }
114:
115: /**
116: * Construct a PushCacheListener
117: * @param port_number port number on which to listen.
118: */
119: public PushCacheListener(int port_number)
120: throws java.io.IOException {
121: super ();
122: _port_number = port_number;
123: _list = new ArrayList();
124: _socket = new ServerSocket(_port_number);
125: // add the shutdown hook, if we can!
126: Class _c = java.lang.Runtime.class;
127: Class _cp[] = { java.lang.Thread.class };
128: try {
129: Method _m = _c.getMethod("addShutdownHook", _cp);
130: Runtime _r = Runtime.getRuntime();
131: _hook = new ShutdownHook();
132: Object[] _param = { _hook };
133: _m.invoke(_r, _param);
134: } catch (NoSuchMethodException ex) {
135: _hook = null;
136: // not using a recent jdk...
137: } catch (InvocationTargetException ex) {
138: // debug traces?
139: } catch (IllegalAccessException ex) {
140: // debug traces?
141: }
142: }
143: }
|