content: //  Licensed to the Apache Software Foundation (ASF) under one
  //  or more contributor license agreements.  See the NOTICE file
  //  distributed with this work for additional information
  //  regarding copyright ownership.  The ASF licenses this file
  //  to you under the Apache License, Version 2.0 (the
  //  "License"); you may not use this file except in compliance
  //  with the License.  You may obtain a copy of the License at
  //
  //      http://www.apache.org/licenses/LICENSE-2.0
  //
  //  Unless required by applicable law or agreed to in writing, software
  //  distributed under the License is distributed on an "AS IS" BASIS,
  //  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  //  See the License for the specific language governing permissions and
  //  limitations under the License.
  
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  class ProtocolServer extends Thread
  {
    protected ServerSocket listener = null;
    protected static ProtocolServer instance = null;
  
    public ProtocolServer (int port)
    {
      try
        {
  	listener = new ServerSocket(port);
        }
      catch(IOException ioe)
        {
  	ioe.printStackTrace();
        }
    }
    
    public synchronized void run ()
    {
      while (true)
        {
  	try
  	  {
  	    Socket socket = listener.accept();
  	    new ProtocolRequestHandler(socket).start();
  	  }
  	catch (IOException ioe)
  	  {
  	    ioe.printStackTrace();
  	  }
        }
    }
  
    public static ProtocolServer getInstance (int port)
    {
      if (instance == null)
        {
  	instance = new ProtocolServer (port);
        }
      return instance;
    }
  }// end of class ProtocolServer
  
  class ProtocolRequestHandler extends Thread
  {
    protected Socket socket = null;
    protected String requestBody;
  
    // constructor
    public ProtocolRequestHandler (Socket socket)
    {
      this.socket = socket;
    }
  
    public synchronized void run ()
    {
      try 
        {
  	// unmarshal the request
  	System.out.println ("call unmarshalRequest");
  	requestBody = unmarshalRequest();
  
  	// marshal the response
  	System.out.println ("call marshalResponse");
  	byte[] response = marshalResponse (requestBody);
  
  	// send the response
  	if (response != null)
  	  {
  	    BufferedOutputStream responseStream =
  	      new BufferedOutputStream(socket.getOutputStream());
  	    responseStream.write (response);
  	    responseStream.flush ();
  	  }
  	// close the socket
  	System.out.println("close socket");
  	socket.close ();
        }
      catch (Exception e)
        {
  	e.printStackTrace();
  	try
  	  {
  	    socket.close ();
  	  }
  	catch (Exception socke)
  	  {
  	    socke.printStackTrace();
  	  }
        }
    }
  
    protected String unmarshalRequest() throws Exception
    { 
      BufferedReader requestReader =
        new BufferedReader (new InputStreamReader(socket.getInputStream()));
      
      String request = requestReader.readLine();
      requestReader.readLine();
      System.out.println ("request is " + request);
  
      StringTokenizer tok = new StringTokenizer (request, " ");
      String host = tok.nextToken();
      String fileName = tok.nextToken();
  
      return fileName;
    }
  
    protected byte[] marshalResponse(String requestBody) throws Exception
    {
      byte[] responseBody;
  
      // find the file corresponding to the file name defined in requestBody
      File responseFile = new File (requestBody);
      if (responseFile.canRead())
        {
  	FileInputStream responseFileStream = 
  	  new FileInputStream (responseFile);
  
  	// read data from the file.
  	int bytesRead = 0;
  	byte[] buffer = new byte[1024];
  	responseBody = new byte[0];
  	byte[] temp = new byte[0];
   	while ((bytesRead = responseFileStream.read (buffer)) != -1)
  	  {
  	    temp = responseBody;
  	    responseBody = new byte[temp.length + bytesRead];
  	    for (int i = 0; i < temp.length; i++)
  	      responseBody[i] = temp[i];
  	    for (int i = 0; i < bytesRead; i++)
  	      responseBody[temp.length + i] = buffer[i];
  	  }	
        }
      else
        {
  	//String errorMessage = new String ("Error reading " + requestBody);
  	//responseBody = new byte[1024];
  	//responseBody = errorMessage.getBytes();
  	return null;
        }
      System.out.println (new String(responseBody));
      return responseBody;
    }
  }// end of class ProtocolRequestHandler
  
  
  public class ProtocolServerTest
  {
      public static void main(String[] args)
      {
          int port = 8175;
          if(args.length > 0)
              port = Integer.parseInt(args[0]); 
  
          // Call networkClient and make connection to server through socket.
          ProtocolServer protocolServer = ProtocolServer.getInstance (port);
          protocolServer.start();
      }
  }// End of class
  
  