001: /*
002: * Created on Dec 9, 2004
003: */
004: package uk.org.ponder.servletutil;
005:
006: import javax.servlet.ServletConfig;
007: import javax.servlet.ServletContext;
008: import javax.servlet.http.HttpServlet;
009: import javax.servlet.http.HttpServletRequest;
010: import javax.servlet.http.HttpServletResponse;
011:
012: import org.springframework.web.context.WebApplicationContext;
013: import org.springframework.web.context.support.WebApplicationContextUtils;
014:
015: import uk.org.ponder.errorutil.ThreadErrorState;
016: import uk.org.ponder.hashutil.EighteenIDGenerator;
017: import uk.org.ponder.rsac.RSACBeanLocatorImpl;
018: import uk.org.ponder.rsac.servlet.RSACUtils;
019: import uk.org.ponder.saxalizer.XMLProvider;
020: import uk.org.ponder.transaction.TransactionThreadMap;
021: import uk.org.ponder.util.Logger;
022: import uk.org.ponder.util.UniversalRuntimeException;
023: import uk.org.ponder.webapputil.ErrorObject;
024:
025: /**
026: * InformationServlet represents a generalised web service handler.
027: * The portion of the URL after the servlet mapping is used as an index
028: * into a table of InformationHandler objects, which are handed the
029: * deserialised argument decoded from the request body. These return an
030: * object which is serialized as the response.
031: * @author Antranig Basman (antranig@caret.cam.ac.uk)
032: *
033: */
034: public class InformationServlet extends HttpServlet {
035: private InformationHandlerRoot handlerroot;
036:
037: //private RSACBeanLocator rsacbeanlocator;
038:
039: public void doGet(HttpServletRequest req, HttpServletResponse res) {
040: service(req, res);
041: }
042:
043: public void doPost(HttpServletRequest req, HttpServletResponse res) {
044: service(req, res);
045: }
046:
047: public void init(ServletConfig config) {
048: ServletContext sc = config.getServletContext();
049: Logger.log.warn("Information starting up for context "
050: + sc.getRealPath(""));
051: WebApplicationContext wac = WebApplicationContextUtils
052: .getWebApplicationContext(sc);
053: //rsacbeanlocator = (RSACBeanLocator) wac.getBean("RSACBeanLocator");
054: handlerroot = (InformationHandlerRoot) wac
055: .getBean("informationHandlerRoot");
056: }
057:
058: private EighteenIDGenerator idgenerator = new EighteenIDGenerator();
059:
060: public void service(HttpServletRequest req, HttpServletResponse res) {
061: ThreadErrorState.beginRequest();
062: // RSACUtils.startServletRequest(req, res,
063: // rsacbeanlocator, RSACUtils.HTTP_SERVLET_FACTORY);
064: try {
065: String baseURL2 = ServletUtil.getBaseURL2(req);
066: Logger.log.info("baseURL2: " + baseURL2);
067: String requestURI = req.getRequestURL().toString();
068: int lastslashpos = requestURI.lastIndexOf('/');
069:
070: //String handlerID = requestURI.substring(baseURL.length());
071: String handlerID = requestURI.substring(lastslashpos + 1);
072: InformationHandler handler = handlerroot
073: .getHandler(handlerID);
074: if (handler == null) {
075: String errmess = "The request handler " + handlerID
076: + " could not be found to service the request "
077: + req.getRequestURI();
078: Logger.log.warn(errmess);
079: res
080: .sendError(HttpServletResponse.SC_NOT_FOUND,
081: errmess);
082: } else {
083: XMLProvider xmlprovider = handlerroot.getXMLProvider();
084: Throwable t = null;
085: String errorid = null;
086: //String extraerrors = "";
087: try {
088: //String input = StreamCopier.streamToString(req.getInputStream());
089: Object arg = xmlprovider.readXML(null, req
090: .getInputStream());
091: Object togo = handler.handleRequest(arg);
092: if (togo != null) {
093: xmlprovider.writeXML(togo, res
094: .getOutputStream());
095: String debugstring = xmlprovider.toString(togo);
096: Logger.log
097: .info("InformationServlet returning response:\n"
098: + debugstring);
099: } else {
100:
101: }
102: } catch (Throwable t1) {
103: Logger.log.warn("Error handling request: ", t1);
104: errorid = handlerroot.getIDGenerator().generateID();
105: t = t1;
106: }
107: // ErrorStateEntry threaderrors = ThreadErrorState.getErrorState();
108: // TargettedMessageList errors = null;
109: //
110: // if (threaderrors == null) {
111: // Logger.log.error("Got null ESE from ThreadLocal");
112: // errors = new TargettedMessageList();
113: // }
114: // else {
115: // errors = threaderrors.errors;
116: // }
117: // if (errors.size() > 0) {
118: // for (int i = 0; i < errors.size(); ++i) {
119: // extraerrors += errors.messageAt(i).messagecode
120: // + errors.messageAt(i).exceptionclass;
121: // }
122: // }
123: if (errorid != null) {
124: ErrorObject err = new ErrorObject("Error ID "
125: + errorid + " processing request "
126: + req.getRequestURI(), handlerID, t);
127: // TODO: This is probably not quite right - what if an error occurs
128: // partway through writing the output?
129: xmlprovider.writeXML(err, res.getOutputStream());
130: Logger.log.warn("Error ID " + errorid
131: + " processing request "
132: + req.getRequestURL(), t);
133: }
134: } // end if there is a handler
135: //TODO: global registry of transactions
136: TransactionThreadMap.assertAllTransactionsConcluded();
137: } catch (Throwable t) {
138: Logger.log.fatal(
139: "Completely fatal exception handling request "
140: + req.getRequestURI(), t);
141: throw UniversalRuntimeException.accumulate(t,
142: "Fatal exception in InformationServlet");
143: } finally {
144: // rsacbeanlocator.endRequest();
145: }
146: }
147: }
|