001: package org.cougaar.demo.mandelbrot.v3;
002:
003: import java.io.IOException;
004: import java.io.OutputStream;
005: import java.io.PrintWriter;
006: import javax.servlet.ServletException;
007: import javax.servlet.http.HttpServletRequest;
008: import javax.servlet.http.HttpServletResponse;
009: import org.cougaar.core.plugin.ServletPlugin;
010: import org.cougaar.core.service.UIDService;
011: import org.cougaar.demo.mandelbrot.util.Arguments;
012: import org.cougaar.demo.mandelbrot.util.ImageOutput;
013: import org.cougaar.util.FutureResult;
014:
015: /**
016: * This servlet publishes a {@link Job} and waits for a result notification.
017: */
018: public class FractalServlet extends ServletPlugin {
019:
020: private static final long DEFAULT_TIMEOUT = 60000;
021:
022: private UIDService uidService;
023:
024: public void load() {
025: // get the required unique identifier service
026: uidService = (UIDService) getServiceBroker().getService(this ,
027: UIDService.class, null);
028: if (uidService == null) {
029: throw new RuntimeException(
030: "Unable to obtain the UIDService");
031: }
032:
033: super .load();
034: }
035:
036: public void unload() {
037: super .unload();
038:
039: if (uidService != null) {
040: getServiceBroker().releaseService(this , UIDService.class,
041: uidService);
042: uidService = null;
043: }
044: }
045:
046: /**
047: * Override "isTransactional" to false.
048: * <p>
049: * By default, our "publishAdd" will be buffered until the end of our "doGet"
050: * call. We want to publish it immediately, so the calculator plugin can see
051: * it and notify us of the result. Therefore, we don't want our "doGet" to
052: * run in the "execute()" method's buffered blackboard transaction.
053: */
054: protected boolean isTransactional() {
055: return false;
056: }
057:
058: protected void doGet(HttpServletRequest req, HttpServletResponse res)
059: throws ServletException, IOException {
060:
061: // parse the URL parameters
062: Arguments args = new Arguments(req.getParameterMap());
063: long timeout = args.getLong("timeout", DEFAULT_TIMEOUT);
064: if (timeout < 0) {
065: timeout = Long.MAX_VALUE;
066: }
067:
068: // create a synchronized result holder
069: FutureResult future = new FutureResult();
070:
071: // publish the request
072: Job job = new Job(uidService.nextUID(), args, future);
073: publishAdd(job);
074:
075: // wait for the result
076: byte[] data = null;
077: Exception e = null;
078: try {
079: data = (byte[]) future.timedGet(timeout);
080: } catch (Exception ex) {
081: // either a timeout or an invalid argument
082: e = ex;
083: }
084:
085: // cleanup the blackboard
086: publishRemove(job);
087:
088: if (e != null) {
089: // write error
090: res.setContentType("text/plain");
091: res.setStatus(HttpServletResponse.SC_NOT_FOUND);
092: PrintWriter out = res.getWriter();
093: e.printStackTrace(out);
094: return;
095: }
096:
097: // write the data as a JPEG
098: res.setContentType("image/jpeg");
099: OutputStream out = res.getOutputStream();
100: ImageOutput.writeJPG(args.getInt("width"), args
101: .getInt("height"), data, out);
102: out.close();
103: }
104: }
|