001: package org.cougaar.demo.mandelbrot;
002:
003: import java.io.IOException;
004: import java.io.PrintWriter;
005: import javax.servlet.ServletException;
006: import javax.servlet.http.HttpServletRequest;
007: import javax.servlet.http.HttpServletResponse;
008: import org.cougaar.core.servlet.ComponentServlet;
009: import org.cougaar.demo.mandelbrot.util.Arguments;
010:
011: /**
012: * This servlet writes the HTML page that embeds the generated JPEG image.
013: * <p>
014: * All the fractal math and drawing are done in the MandelbrotServlet.
015: * That servlet listens on the "/image" servlet path.
016: * <p>
017: * This servlet writes the outer HTML page and "<img src=.../>" tag.
018: * The browser then requests the JPEG from the "/image" servlet.
019: */
020: public class FrontPageServlet extends ComponentServlet {
021:
022: // default mandelbrot parameters
023: private static final Arguments DEFAULT_SELECTION = new Arguments(
024: new String[] { "width=750", "height=500", "x_min=-2.0",
025: "x_max=1.0", "y_min=-1.0", "y_max=1.0" });
026:
027: // this is the servlet path of our MandelbrotServlet, which
028: // does the real work. It generates the JPEG image.
029: private static final String IMAGE_SERVLET_PATH = "/image";
030:
031: protected void doGet(HttpServletRequest req, HttpServletResponse res)
032: throws ServletException, IOException {
033:
034: // parse the URL parameters
035: Arguments args = new Arguments(req.getParameterMap(),
036: DEFAULT_SELECTION.keySet(), DEFAULT_SELECTION);
037:
038: // fix x/y coordinates to be upright
039: if (args.getDouble("x_max") < args.getDouble("x_min")) {
040: args.swap("x_max", "x_min");
041: }
042: if (args.getDouble("y_max") < args.getDouble("y_min")) {
043: args.swap("y_max", "y_min");
044: }
045:
046: // fix x/y aspect ratio to match our width/height ratio
047: //
048: // this ensures that
049: // (width/height) == ((x_max - x_min)/(y_max - y_min));
050: int w = Math.max(args.getInt("width"), 1);
051: int h = Math.max(args.getInt("height"), 1);
052: double wh_ratio = ((double) w / h);
053: double x_range = (args.getDouble("x_max") - args
054: .getDouble("x_min"));
055: double y_range = (args.getDouble("y_max") - args
056: .getDouble("y_min"));
057: double xy_ratio = (x_range / y_range);
058: if (xy_ratio < wh_ratio) {
059: double x_max = wh_ratio * y_range + args.getDouble("x_min");
060: args.setDouble("x_max", x_max);
061: x_range = (x_max - args.getDouble("x_min"));
062: } else {
063: double y_min = args.getDouble("y_max") - x_range / wh_ratio;
064: args.setDouble("y_min", y_min);
065: y_range = (args.getDouble("y_max") - y_min);
066: }
067:
068: // figure out the image servlet URI
069: String baseURI = req.getRequestURI();
070: String ext;
071: if ((ext = req.getPathInfo()) != null) {
072: baseURI = baseURI.substring(0, baseURI.length()
073: - ext.length());
074: }
075: if ((ext = req.getServletPath()) != null) {
076: baseURI = baseURI.substring(0, baseURI.length()
077: - ext.length());
078: }
079: String imgURI = baseURI + IMAGE_SERVLET_PATH;
080:
081: // write the top-level html page
082: res.setContentType("text/html");
083: PrintWriter out = res.getWriter();
084: out.println(
085: // header
086: "<html><head><title>Mandelbrot Servlet</title></head><body>"
087: + "<h2>Mandelbrot Servlet</h2>" +
088:
089: // zoom out
090: "<form method=\"GET\" action=\""
091: + req.getRequestURI()
092: + "\">\n"
093: + "Click on two points in the image to zoom in, or "
094: + DEFAULT_SELECTION
095: .toString("<input name=\"$key\" type=\"hidden\" value=\"$value\">\n")
096: + "<input type=\"submit\" value=\"Zoom Out\">\n"
097: + "</form>\n"
098: +
099:
100: // image
101: "<img id=\"myImage"
102: + "\" width=\""
103: + args.getInt("width")
104: + "\" height=\""
105: + args.getInt("height")
106: + "\" src=\""
107: + imgURI
108: + "?"
109: + args.toString("&$key=$value")
110: + "\"/>\n"
111: +
112:
113: // selection
114: "<form method=\"GET\" name=\"f\" action=\""
115: + req.getRequestURI()
116: + "\">\n"
117: + args
118: .toString(" $key=<input name=\"$key\" type=\"text\" size=\"4\""
119: + " value=\"$value\">\n")
120: + "<input type=\"submit\" value=\"Submit\">\n"
121: +
122:
123: // reset
124: "<input type=\"button\" name=\"reset\" value=\"Reset\" onClick=\""
125: + DEFAULT_SELECTION
126: .toString("document.f.$key.value='$value';")
127: + "\">\n"
128: + "</form>\n"
129: +
130:
131: // javascript
132: "<script type=\"text/javascript\">\n"
133: + "var myImage = document.getElementById(\"myImage\");\n"
134: + "var click_count=0;\n"
135: + "function onImageClick(e) {\n"
136: + " var w = e.clientX - myImage.x +\n"
137: + " (document.all ? document.body.scrollLeft : window.scrollX);\n"
138: + " var h = e.clientY - myImage.y +\n"
139: + " (document.all ? document.body.scrollTop : window.scrollY);\n"
140: + " var x = "
141: + args.getDouble("x_min")
142: + " +\n"
143: + " (w/"
144: + args.getInt("width")
145: + ")*"
146: + x_range
147: + ";\n"
148: + " var y = "
149: + args.getDouble("y_min")
150: + " +\n"
151: + " (h/"
152: + args.getInt("height")
153: + ")*"
154: + y_range
155: + ";\n"
156: + " if ((click_count++ % 2) == 0) {\n"
157: + " document.f.x_max.value=x;\n"
158: + " document.f.y_max.value=y;\n"
159: + " } else {\n"
160: + " document.f.x_min.value=x;\n"
161: + " document.f.y_min.value=y;\n"
162: + " document.f.submit();\n"
163: + // could use myImg.src=...
164: " }\n"
165: + "}\n"
166: + "myImage.onmousedown = onImageClick;\n"
167: + "</script>\n" +
168:
169: // footer
170: "</body></html>");
171: out.close();
172: }
173: }
|