/* ESXX - The friendly ECMAscript/XML Application Server Copyright (C) 2007-2015 Martin Blom <martin@blom.org> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.esxx; import org.esxx.js.*; import org.esxx.saxon.ESXXExpression; import java.io.*; import java.net.URI; import java.util.Properties; import java.util.Map; import java.util.HashMap; import javax.xml.transform.dom.*; import org.mozilla.javascript.*; import org.w3c.dom.Document; import org.w3c.dom.Node; import net.sf.saxon.s9api.*; import static net.sf.saxon.s9api.Serializer.Property.*; class Worker { public Worker(ESXX esxx) { this.esxx = esxx; } public Response handleRequest(Context cx, Request request) throws Exception { long start_time = System.currentTimeMillis(); Application app = esxx.getCachedApplication(cx, request); try { // if (app.isDebuggerActivated()) { // org.mozilla.javascript.tools.debugger.Main.mainEmbedded(esxx.getContextFactory(), // global, // app.getAppName()); // } // Create a Request object JSRequest jsreq = (JSRequest) JSESXX.newObject(cx, app.getJSGlobal(), "Request", new Object[] { request }); JSResponse result = null; try { result = app.executeInitOnce(cx, jsreq); if (app.hasHandlers()) { // Execute the SOAP or HTTP handler (if available) String request_method = request.getRequestMethod(); String soap_action = jsreq.jsGet_soapAction(); if ("POST".equals(request_method) && soap_action != null && app.hasSOAPHandlers()) { result = app.executeSOAPAction(cx, jsreq, soap_action, request.getPathInfo()); } else { result = app.executeHTTPMethod(cx, jsreq, request_method, request.getPathInfo()); } } else if (result == null) { // No handlers; the document is the result result = app.wrapResult(cx, app.getMainDocument()); } } catch (InterruptedException ex) { ESXX.checkTimeout(cx); // Throws TimeOut throw ex; } catch (Exception ex) { // On errors, invoke error handler result = app.executeErrorHandler(cx, jsreq, ex); } Response response = result.getResponse(); response.unwrapResult(); if (response.getResult() instanceof Node) { try { handleTransformation(cx, request, response, result, app); } catch (Exception ex) { // Invoke error handler on XSLT errors as well response = app.executeErrorHandler(cx, jsreq, ex).getResponse(); response.unwrapResult(); if (response.getResult() instanceof Node) { handleTransformation(cx, request, response, result, app); } } } // Return response return response; } finally { esxx.releaseApplication(app, start_time); } } private static String getDebugLogForComment(Request request) { return "Start ESXX Request Log\n" + request.getLogAsString().replaceAll("--", "\u2012\u2012") + "End ESXX Request Log"; } private void handleTransformation(Context cx, Request request, Response response, JSResponse js_response, Application app) throws IOException, SaxonApiException { ESXX esxx = ESXX.getInstance(); String content_type = response.getContentType(true); Node node = (Node) response.getResult(); String ct = ESXX.parseMIMEType(content_type, null); URI stylesheet = app.getStylesheet(cx, ct, request.getPathInfo()); if (stylesheet == null) { // Just serialize and attach debug log response.setResult(esxx.serializeNode(node) + "<!--" + getDebugLogForComment(request) + "-->"); response.setContentType(content_type); } else { Map<QName, Object> params = new HashMap<QName, Object>(); Scriptable jsparams = js_response.jsGet_params(); for (Object o : jsparams.getIds()) { if (o instanceof String) { params.put(new QName((String) o), jsparams.get((String) o, jsparams)); } } ByteArrayOutputStream os = new ByteArrayOutputStream(); Serializer s = new Serializer(); s.setOutputStream(os); Stylesheet.transform(cx, app.getJSGlobal(), esxx.getCachedStylesheet(stylesheet, null), params, node, true, getDebugLogForComment(request), s); response.setContentType(ESXX.coalesce(s.getOutputProperty(MEDIA_TYPE), content_type)); response.setResult(os); } } private ESXX esxx; }