Project Report: fawkez

Packagesummary org.jcoderz.commons.connector.http.transport

org.jcoderz.commons.connector.http.transport.SimpleServer

LineHitsNoteSource
1  /*
2   * $Id: SimpleServer.java 1375 2009-03-29 16:40:00Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.connector.http.transport;
34  
35  import java.net.ServerSocket;
36  import java.net.Socket;
37  import java.net.SocketTimeoutException;
38  import java.util.HashMap;
39  import java.util.Iterator;
40  import java.util.Map;
41  import java.util.logging.Level;
42  import java.util.logging.Logger;
43  
44  /**
45   * This class defines a simple http server used for testing
46   * the HttpConnectionImpl based on the commons-httpclient lib.
47   */
48 (1)public class SimpleServer
49        extends Thread
50  {
51     /** Class name used for logging. */
5275    private static final String CLASSNAME
53           = SimpleServer.class.getName();
54     /** Logger in use. */
55100    private static final Logger logger
56           = Logger.getLogger(CLASSNAME);
57     private static final int SOCKET_TIMEOUT = 10000;
58     private static final int JOIN_TIMEFRAME = 5000;
59     private static final int WAITING_LOOPS = 10;
60     /** Thread for stopping the server. */
61     private final Terminator mTerminator;
62     /** Flag indicating that the server have to be stopped. */
63100    private boolean mDoStop = false;
64     /** Used for sychronize stopping the server. */
65100    private final Object mMonitor = new Object();
66     /** Handler for client requests. */
67100    private final Map mHandler = new HashMap();
68     /** Server port. */
69     private final int mPort;
70     /** Flag indicating if the server has been started. */
71100    private volatile boolean mServerStarted = false;
72  
73  
74     /**
75      * Constructor.
76      * @param port
77    * the server port in use
78      */
79     public SimpleServer (int port)
80100    {
81100       mPort = port;
82100       mTerminator = new Terminator(this);
83100    }
84  
85     /**
86      * Main method. Starts a thread for terminating the server and starts
87      * a ClientHandler thread for every incomming request.
88      * @param args
89    * args include the port number to use
90      */
91     public static void main (String[] args)
92     {
930       if (args.length != 1)
94        {
950          logger.info("Usage: SimpleServer <port>");
960          return;
97        }
980       final SimpleServer server = new SimpleServer(Integer.parseInt(args[0]));
990       server.startServer();
1000       server.stopServer();
1010    }
102  
103     /**
104      * Starts the server thread.
105      */
106     public void run ()
107     {
1080       startServer();
1090       stopServer();
1100    }
111  
112     /**
113      * Creates a client socket for every incoming request and creates a
114      * ClientHandler thread to handle the request/response.
115      * Server will be stopped after a certain timeframe.
116      */
117     public void startServer ()
118     {
119100       logger.info("Starting server..");
120        try
121        {
122100          final ServerSocket s = new ServerSocket(mPort);
123100          s.setSoTimeout(SOCKET_TIMEOUT);
124100          int clientCounter = 0;
125100          int waitingCounter = 0;
126100          ClientHandler client = null;
127100          logger.info("Waiting for connection on " + s);
128100          while (!haveToStop() && waitingCounter < WAITING_LOOPS)
129           {
130100             Socket incoming = null;
131              try
132              {
133100                mServerStarted = true;
134100                incoming = s.accept();
135              }
1360             catch (SocketTimeoutException ste)
137              {
1380                waitingCounter++;
139100             }
140  
141100             if (incoming != null)
142              {
143100                clientCounter++;
144100                client = new ClientHandler(incoming, clientCounter);
145100                mHandler.put(Integer.toString(clientCounter), client);
146100                client.start();
147              }
148100          }
149        }
1500       catch (Exception e)
151        {
1520          logger.log(Level.WARNING, "Failed to start SimpleServer: " + e, e);
1530(2)         e.printStackTrace();
1540       }
155        // don't let others wait for ever.
1560       mServerStarted = true;
1570    }
158  
159     /**
160      * Sets the flag for stopping the server.
161      */
162     public void doStop ()
163     {
164100       synchronized (mMonitor)
165        {
166100          mDoStop = true;
16750       }
168100    }
169  
170     /**
171      * Checks the flag for stopping the server.
172      * @return boolean
173      *          the flag for stopping the server
174      */
175     public boolean haveToStop ()
176     {
177100       synchronized (mMonitor)
178        {
179100          return mDoStop;
1800       }
181     }
182  
183     /**
184      * Stops the client handler threads.
185      *
186      */
187     public void stopServer ()
188     {
1890       logger.info("\n---Stopping Server with " + mHandler.size()
190              + " client handler---\n");
1910       final Iterator it = mHandler.keySet().iterator();
1920       while (it.hasNext())
193        {
194           try
195           {
1960             final String clientId = (String) it.next();
1970             final ClientHandler client = (ClientHandler) mHandler.get(clientId);
1980             if (client != null)
199              {
2000                client.haveToStop();
2010                client.join(JOIN_TIMEFRAME);
2020                if (client.isAlive())
203                 {
2040                   interruptClient(client);
205                 }
206              }
207           }
2080          catch (Exception ex)
209           {
210              // ignore
2110          }
212        }
2130       if (mTerminator != null && mTerminator.isAlive())
214        {
2150          mTerminator.interrupt();
216        }
217  
2180       logger.warning("---Stopping DONE---");
2190    }
220  
221     /**
222      * Returns <tt>true</tt> if the server has been started.
223      * @return <tt>true</tt> if the server has been started;
224      *       <tt>false</tt> otherwise.
225      */
226     public boolean isServerStarted ()
227     {
228100       return mServerStarted;
229     }
230     /**
231      * Interrupts the client handler thread.
232      * @param client
233    * the thread to interrupt
234      * @throws InterruptedException
235    * if interrupt fails
236      */
237     private void interruptClient (ClientHandler client)
238           throws InterruptedException
239     {
240        try
241        {
2420          client.interrupt();
2430          logger.info("Needed to interrupt client handler thread.");
244        }
2450       catch (Exception ex)
246        {
2470          logger.log(Level.WARNING,
248              "Exception while interrupting client handler thread: "
249              + ex.getMessage(), ex);
2500       }
2510       client.join(JOIN_TIMEFRAME);
2520       if (client.isAlive())
253        {
2540          logger.warning("unable to interrupt client thread");
255        }
2560    }
257  }

Findings in this File

c (1) 48 : 0 Type Javadoc comment is missing an @author tag.
d (2) 153 : 10 Avoid printStackTrace(); use a logger call instead.