169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage sample.evolve;
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.tools.web.*;
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.*;
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A web server for demonstrating class evolution.  It must be
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * run with a DemoLoader.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If a html file /java.html is requested, this web server calls
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WebPage.show() for constructing the contents of that html file
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * So if a DemoLoader changes the definition of WebPage, then
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the image of /java.html is also changed.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Note that WebPage is not an applet.  It is rather
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * similar to a CGI script or a servlet.  The web server never
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * sends the class file of WebPage to web browsers.
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Furthermore, if a html file /update.html is requested, this web
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * server overwrites WebPage.class (class file) and calls update()
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * in VersionManager so that WebPage.class is loaded into the JVM
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * again.  The new contents of WebPage.class are copied from
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * either sample/evolve/WebPage.class
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * or sample/evolve/sample/evolve/WebPage.class.
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class DemoServer extends Webserver {
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static void main(String[] args) throws IOException
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	if (args.length == 1) {
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    DemoServer web = new DemoServer(Integer.parseInt(args[0]));
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    web.run();
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	}
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	else
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    System.err.println(
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		"Usage: java sample.evolve.DemoServer <port number>");
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public DemoServer(int port) throws IOException {
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	super(port);
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	htmlfileBase = "sample/evolve/";
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final String ver0 = "sample/evolve/WebPage.class.0";
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private static final String ver1 = "sample/evolve/WebPage.class.1";
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String currentVersion = ver0;
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void doReply(InputStream in, OutputStream out, String cmd)
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	throws IOException, BadHttpRequest
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	if (cmd.startsWith("GET /java.html ")) {
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    runJava(out);
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    return;
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	}
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	else if (cmd.startsWith("GET /update.html ")) {
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    try {
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		if (currentVersion == ver0)
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		    currentVersion = ver1;
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		else
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		    currentVersion = ver0;
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		updateClassfile(currentVersion);
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		VersionManager.update("sample.evolve.WebPage");
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    }
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    catch (CannotUpdateException e) {
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		logging(e.toString());
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    }
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    catch (FileNotFoundException e) {
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		logging(e.toString());
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    }
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	}
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	super.doReply(in, out, cmd);
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void runJava(OutputStream outs) throws IOException {
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	OutputStreamWriter out = new OutputStreamWriter(outs);
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	out.write("HTTP/1.0 200 OK\r\n\r\n");
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	WebPage page = new WebPage();
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	page.show(out);
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	out.close();
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* updateClassfile() copies the specified file to WebPage.class.
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void updateClassfile(String filename)
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	throws IOException, FileNotFoundException
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	byte[] buf = new byte[1024];
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	FileInputStream fin
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    = new FileInputStream(filename);
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	FileOutputStream fout
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    = new FileOutputStream("sample/evolve/WebPage.class");
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	for (;;) {
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    int len = fin.read(buf);
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    if (len >= 0)
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		fout.write(buf, 0, len);
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	    else
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal		break;
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal	}
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
103