import java.io.*;
import java.net.*;

public class StudentListTunnelApp {

  public StudentListTunnelApp() {

  }

  // Adds Student Names to List
  public void buildStudentList(StudentList value) {

    value.addStudent("Bob Robinson");
    value.addStudent("Steve Bobinson");
    value.addStudent("Rob Stevinson");
    value.addStudent("Todd Thompson");
    value.addStudent("Tom Toddson");
    value.addStudent("Rob Bobinson");
  }

  // Write the StudentList to the Connection
  public void writeStudentList(URLConnection connection,
    StudentList value) {

    try {

      // Set this to false in order to ignore caching
      connection.setUseCaches(false);

      // Set the content-type of the request
      //  application/octet-stream is used when writing
      // application specific byte size data
      connection.setRequestProperty("CONTENT_TYPE",
        "application/octet-stream");

      // Set these vales to true to use the same connection
      // for both input and output
      connection.setDoInput(true);
      connection.setDoOutput(true);

      // Create the ObjectOutputStream passing it the
      // ByteArrayOutputStream object.
      ObjectOutputStream os =
        new ObjectOutputStream(connection.getOutputStream());

      // Write the StudentList to the ObjectOutputStream
      System.err.println("Writing StudentList Object.");
      os.writeObject(value);
      os.flush();
      os.close();
    }
    catch (IOException e) {

      System.err.println(e.getMessage());
    }
  }

  public StudentList readStudentList(URLConnection connection)
  {

    StudentList list = null;

    try {

      // Create the ObjectInputStream passing it the
      // InputStream object from the URLConnection
      ObjectInputStream is = new ObjectInputStream(
        connection.getInputStream());

      System.err.println("Waiting for response.");

      // Read the stored object and downcast it back to
      // a StudentList
      list = (StudentList)is.readObject();
      is.close();
    }
    catch (IOException e) {

      System.err.println(e.getMessage());
    }
    catch (ClassNotFoundException ce) {

      System.err.println(ce.getMessage());
    }
    return list;
  }

  public void invoke() {

    try {

      StudentList list = new StudentList();

      buildStudentList(list);

      // create our URL
      URL url = new URL("http://localhost:8080" +
        "/servlet/StudentListTunnelServlet");

      // Open our URLConnection
      System.err.println("Opening Connection.");
      URLConnection con = url.openConnection();

      // Write the StudentList
      writeStudentList(con, list);

      // Get the StudentList from the response
      // and print it out.
      StudentList inList = readStudentList(con);
      if ( inList != null ) {

        System.out.println("After being read back in.");
        inList.listStudents();
      }
      else {

        System.err.println("readObject failed.");
      }

      System.out.println("\n Press enter to quit.");
      System.in.read();
    }
    catch (MalformedURLException mue) {

      System.err.println(mue.getMessage());
    }
    catch (Exception e) {

      System.err.println(e.getMessage());
    }
  }

  public static void main(String[] args) {

    StudentListTunnelApp studentListTunnelApp =
      new StudentListTunnelApp();
    studentListTunnelApp.invoke();
  }
}
