001: /*
002: License $Id: Handler.java,v 1.6 2005/03/15 15:43:17 hendriks73 Exp $
003:
004: Copyright (c) 2001-2005 tagtraum industries.
005:
006: LGPL
007: ====
008:
009: jo! is free software; you can redistribute it and/or
010: modify it under the terms of the GNU Lesser General Public
011: License as published by the Free Software Foundation; either
012: version 2.1 of the License, or (at your option) any later version.
013:
014: jo! is distributed in the hope that it will be useful,
015: but WITHOUT ANY WARRANTY; without even the implied warranty of
016: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: Lesser General Public License for more details.
018:
019: You should have received a copy of the GNU Lesser General Public
020: License along with this library; if not, write to the Free Software
021: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022:
023: For LGPL see <http://www.fsf.org/copyleft/lesser.txt>
024:
025:
026: Sun license
027: ===========
028:
029: This release contains software by Sun Microsystems. Therefore
030: the following conditions have to be met, too. They apply to the
031: files
032:
033: - lib/mail.jar
034: - lib/activation.jar
035: - lib/jsse.jar
036: - lib/jcert.jar
037: - lib/jaxp.jar
038: - lib/crimson.jar
039: - lib/servlet.jar
040: - lib/jnet.jar
041: - lib/jaas.jar
042: - lib/jaasmod.jar
043:
044: contained in this release.
045:
046: a. Licensee may not modify the Java Platform
047: Interface (JPI, identified as classes contained within the javax
048: package or any subpackages of the javax package), by creating additional
049: classes within the JPI or otherwise causing the addition to or modification
050: of the classes in the JPI. In the event that Licensee creates any
051: Java-related API and distribute such API to others for applet or
052: application development, you must promptly publish broadly, an accurate
053: specification for such API for free use by all developers of Java-based
054: software.
055:
056: b. Software is confidential copyrighted information of Sun and
057: title to all copies is retained by Sun and/or its licensors. Licensee
058: shall not modify, decompile, disassemble, decrypt, extract, or otherwise
059: reverse engineer Software. Software may not be leased, assigned, or
060: sublicensed, in whole or in part. Software is not designed or intended
061: for use in on-line control of aircraft, air traffic, aircraft navigation
062: or aircraft communications; or in the design, construction, operation or
063: maintenance of any nuclear facility. Licensee warrants that it will not
064: use or redistribute the Software for such purposes.
065:
066: c. Software is provided "AS IS," without a warranty
067: of any kind. ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES,
068: INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
069: PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
070:
071: d. This License is effective until terminated. Licensee may
072: terminate this License at any time by destroying all copies of Software.
073: This License will terminate immediately without notice from Sun if Licensee
074: fails to comply with any provision of this License. Upon such termination,
075: Licensee must destroy all copies of Software.
076:
077: e. Software, including technical data, is subject to U.S.
078: export control laws, including the U.S. Export Administration Act and its
079: associated regulations, and may be subject to export or import regulations
080: in other countries. Licensee agrees to comply strictly with all such
081: regulations and acknowledges that it has the responsibility to obtain
082: licenses to export, re-export, or import Software. Software may not be
083: downloaded, or otherwise exported or re-exported (i) into, or to a national
084: or resident of, Cuba, Iraq, Iran, North Korea, Libya, Sudan, Syria or any
085: country to which the U.S. has embargoed goods; or (ii) to anyone on the
086: U.S. Treasury Department's list of Specially Designated Nations or the U.S.
087: Commerce Department's Table of Denial Orders.
088:
089:
090: Feedback
091: ========
092:
093: We encourage your feedback and suggestions and want to use your feedback to
094: improve the Software. Send all such feedback to:
095: <feedback@tagtraum.com>
096:
097: For more information on tagtraum industries and jo!
098: please see <http://www.tagtraum.com/>.
099:
100:
101: */
102: package com.tagtraum.framework.server;
103:
104: import com.tagtraum.framework.log.Log;
105:
106: /**
107: * Abstract superclass for a handler.
108: *
109: * @author <a href="mailto:hs@tagtraum.com">Hendrik Schreiber</a>
110: * @version 1.1beta1 $Id: Handler.java,v 1.6 2005/03/15 15:43:17 hendriks73 Exp $
111: * @see TCPHandler
112: * @see UDPHandler
113: * @see #service()
114: */
115: public abstract class Handler extends Thread implements I_Handler {
116:
117: /**
118: * Source-Version
119: */
120: public static String vcid = "$Id: Handler.java,v 1.6 2005/03/15 15:43:17 hendriks73 Exp $";
121:
122: /**
123: * Service that belongs to this <code>Handler</code>.
124: */
125: protected I_Service service;
126:
127: /**
128: * Log that belongs to this <code>Handler</code>.
129: */
130: Log log;
131:
132: /**
133: * Flag that indicates whether the Handler was stopped.
134: */
135: protected boolean stopped;
136:
137: /**
138: * Flag that indicates whether the Handler is ready for connections.
139: */
140: boolean ready;
141:
142: /**
143: * Time the service-method was entered, or -1 if the service method
144: * is not executed at the moment.
145: */
146: long serviceStart;
147:
148: /**
149: * ThreadGroup-constructor.
150: */
151: public Handler(ThreadGroup tg) {
152: super (tg, "Handlerthread");
153: this .serviceStart = -1;
154: }
155:
156: /**
157: * Returns this <code>Handler's</code> {@link I_Service}.
158: *
159: * @return Service, that belongs to this <code>Handler</code>
160: */
161: public I_Service getService() {
162: return (I_Service) service;
163: }
164:
165: /**
166: * Initializes this <code>Handler</code>. After calling this
167: * method the <code>Handler</code> has to be in a state that
168: * is "ready to use".<p>
169: * When this methos is overridden <code>super.init(I_Service)</code>
170: * should be called.
171: *
172: * @param aService Service, that this <code>Handler</code> belongs to.
173: * @exception HandlerException if something goes wrong
174: */
175: public void init(I_Service aService) throws HandlerException {
176: if (aService == null) {
177: throw new IllegalArgumentException("Service can't be null.");
178: }
179: this .service = aService;
180: this .log = Log.getLog(service.getName());
181: start();
182: int startCounter = 0;
183: synchronized (this ) {
184: try {
185: while (!ready) {
186: wait(1000);
187: startCounter++;
188: if (startCounter > 10) {
189: throw new HandlerException(
190: "Failed to start the Handler "
191: + this .getName()
192: + " within 10 seconds. Giving up.");
193: }
194: }
195: } catch (InterruptedException ie) {
196: ie.printStackTrace();
197: }
198: }
199: }
200:
201: /**
202: * This is the central method that should be overridden
203: * in order to implement a real service.
204: * It is called after the socket was set.
205: */
206: public abstract void service();
207:
208: /**
209: * Proxy-method that enables the easier access to service attributes.
210: *
211: * @param key key of the wanted attribute
212: * @return the attribute or <code>null</code>
213: */
214: public Object getServiceAttribute(String key) {
215: if (getService() == null) {
216: throw new IllegalStateException("No service set.");
217: }
218: return getService().getAttribute(key);
219: }
220:
221: /**
222: * Proxy-method that enables the easier access to service attributes.
223: * Attribute erm�glicht.
224: *
225: * @param key key of the wanted attribute
226: * @param value the attribute
227: */
228: public void setServiceAttribute(String key, Object value) {
229: if (getService() == null) {
230: throw new IllegalStateException("No service set.");
231: }
232: getService().setAttribute(key, value);
233: }
234:
235: /**
236: * Returns the time when {@link #service()} was called or
237: * -1 if {@link #service()} is not executed at the moment.
238: */
239: public long getServiceStart() {
240: return serviceStart;
241: }
242:
243: /**
244: * Stops this <code>Handler</code> and frees all used resources.
245: */
246: public synchronized void destroy() {
247: if (Log.getLog(service.getName()).isLog(Log.METHOD)) {
248: Log.getLog(service.getName()).log(
249: "Handler#destroy(): " + getName(), Log.METHOD);
250: // first try it the soft way
251: }
252: stopped = true;
253: notifyAll();
254: try {
255: join(900); // give it some time to die
256: } catch (InterruptedException ignore) {
257: }
258: if (isAlive()) {
259: try {
260: // we are brutal to make sure it really dies.
261: stop();
262: } catch (ThreadDeath td) {
263: if (Log.getLog(service.getName()).isLog(Log.METHOD)) {
264: Log.getLog(service.getName()).log(
265: "Handler#destroy(): " + getName()
266: + " was stopped using stop().",
267: Log.METHOD);
268: }
269: throw td;
270: }
271: }
272: }
273:
274: }
|