r9601 - in helma-ng/trunk: apps/storage modules/helma modules/helma/webapp src/org/helma/javascript src/org/helma/web

[email protected]
Newsgroups gmane.comp.java.helma.cvs
Message-ID <20090410121056.888663D0D6@mia>
Author: hannes
Date: 2009-04-10 14:10:56 +0200 (Fri, 10 Apr 2009)
New Revision: 9601

Modified:
   helma-ng/trunk/apps/storage/main.js
   helma-ng/trunk/modules/helma/httpserver.js
   helma-ng/trunk/modules/helma/logging.js
   helma-ng/trunk/modules/helma/profiler.js
   helma-ng/trunk/modules/helma/system.js
   helma-ng/trunk/modules/helma/webapp.js
   helma-ng/trunk/modules/helma/webapp/response.js
   helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java
   helma-ng/trunk/src/org/helma/web/HelmaServlet.java
Log:
Several fixes in web framework
- Switch to JS implementation of response object, Request/Response host objects are no longer used.
- JS-Object based exception handling, e.g. throw {retry: true} to retry a request after chaning optimization level.
- Switch back to using the HelmaServlet written in Java, it's useful to have the servlet outside the JS environment.
- Make res.redirect() work again.
- Shorten setRhinoOptimizationLevel() to setOptimizationLevel in helma/system and add getOptimizationLevel().
- Auto-wrap multiline log messages in <pre> tags in log4j response appender.

Details at http://dev.helma.org/trac/helma/changeset/9601

Modified: helma-ng/trunk/apps/storage/main.js
===================================================================
--- helma-ng/trunk/apps/storage/main.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/apps/storage/main.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -31,16 +31,14 @@
     var book = new model.Book({author: author, title: req.params.title});
     // author is saved transitively
     book.save();
-    // FIXME redirect currently not working
-    // res.redirect('/');
+    res.redirect('/');
 }
 
 function removeBook(req, res) {
     var book = model.Book.get(req.params.remove);
     // author is removed through cascading delete
     book.remove();
-    // FIXME redirect currently not working
-    // res.redirect('/');
+    res.redirect('/');
 }
 
 function getDeleteLink(book) {

Modified: helma-ng/trunk/modules/helma/httpserver.js
===================================================================
--- helma-ng/trunk/modules/helma/httpserver.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/modules/helma/httpserver.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -2,10 +2,6 @@
  * Module for starting and stopping the jetty http server.
  */
 
-import('helma/webapp', 'webapp');
-include('helma/webapp/request');
-include('helma/webapp/response');
-
 export('start', 'stop');
 
 // mark this module as shared between all requests
@@ -71,15 +67,15 @@
                 // set up helma servlet context
                 var helmaCtx = idMap.get('helmaContext');
                 if (helmaCtx) {
-                    // var helmaServlet = new HelmaServlet(engine);
-                    var helmaServlet = new Packages.javax.servlet.http.HttpServlet({
-                        service: function(servletRequest, servletResponse) {
-                            var req = new Request(servletRequest),
-                                res = new Response(servletResponse);
-                            webapp.handleRequest(req, res);
-                        }
-                    });
+                    var helmaServlet = new HelmaServlet(engine);
                     var servletHolder = new jetty.servlet.ServletHolder(helmaServlet);
+                    var params = config.servletParams || {
+                        'module': 'helma/webapp',
+                        'function': 'handleServletRequest'
+                    };
+                    for (var p in params) {
+                        servletHolder.setInitParameter(p, params[p]);
+                    }
                     helmaCtx.addServlet(servletHolder, "/*");
                 }
                 // start server

Modified: helma-ng/trunk/modules/helma/logging.js
===================================================================
--- helma-ng/trunk/modules/helma/logging.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/modules/helma/logging.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -70,10 +70,15 @@
     if (list) {
         for (var i = 0; i < list.size(); i++) {
             var item = list.get(i);
-            var b = new Buffer();
+            var msg = item[0];
+            var multiline = msg && msg.indexOf('\n') > 0 || msg.indexOf('\r')> 0;
             res.write("<div class=\"helma-debug-line\" style=\"background: #fc3;");
             res.write("color: black; border-top: 1px solid black;\">");
-            res.write(item[0]);
+            if (multiline) {
+                res.write("<pre>").write(msg).write("</pre>");
+            } else {
+                res.write(msg);
+            }
             if (item[1]) {
                 res.write("<h4 style='padding-left: 8px; margin: 4px;'>Script Stack</h4>");
                 res.write("<pre style='margin: 0;'>", item[1], "</pre>");

Modified: helma-ng/trunk/modules/helma/profiler.js
===================================================================
--- helma-ng/trunk/modules/helma/profiler.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/modules/helma/profiler.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -19,7 +19,10 @@
     var profiler;
 
     this.onRequest = function() {
-        system.setRhinoOptimizationLevel(-1);
+        if (system.getOptimizationLevel() > -1) {
+            system.setOptimizationLevel(-1);
+            throw {retry: true};
+        }
         if (!profiler) {
             profiler = new Profiler();
         }
@@ -27,12 +30,16 @@
     };
 
     this.onResponse = this.onError = function(req, res) {
+        if (system.getOptimizationLevel() > -1) {
+            return;
+        }
         var result = profiler.getResult(maxFrames);
         var b = new Buffer();
         b.writeln();
         b.writeln("     total  average  calls    path");
         for (var i = 1; i < result.maxLength; i++) {
-            b.write("—");
+            // b.write("—");
+            b.write("-");
         }
         b.writeln();
         b.writeln(result.data);

Modified: helma-ng/trunk/modules/helma/system.js
===================================================================
--- helma-ng/trunk/modules/helma/system.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/modules/helma/system.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -13,7 +13,8 @@
         'getRepositories',
         'getRhinoContext',
         'getRhinoEngine',
-        'setRhinoOptimizationLevel',
+        'getOptimizationLevel',
+        'setOptimizationLevel',
         'args');
 
 var log = helma.logging.getLogger(__name__);
@@ -64,8 +65,8 @@
  * is 0.
  * @return level an integer between -1 and 9
  */
-function getRhinoOptimizationLevel() {
-    getRhinoEngine().getOptimizationLevel();    
+function getOptimizationLevel() {
+    return getRhinoEngine().getOptimizationLevel();    
 }
 
 /**
@@ -75,7 +76,7 @@
  * is 0.
  * @param level an integer between -1 and 9
  */
-function setRhinoOptimizationLevel(level) {
+function setOptimizationLevel(level) {
     getRhinoEngine().setOptimizationLevel(level);
 }
 

Modified: helma-ng/trunk/modules/helma/webapp/response.js
===================================================================
--- helma-ng/trunk/modules/helma/webapp/response.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/modules/helma/webapp/response.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -1,18 +1,43 @@
 include('helma/buffer');
 import('helma/system', 'system');
 
+export('Response');
+
 // FIXME hack to get this to evaluate
-if (!global.Response || !Response.prototype.render) {
+function Response(servletResponse) {
 
-    system.addHostObject(org.helma.web.Response);
+    var writer;
 
+
+    Object.defineProperty(this, 'write', {
+        value: function write() {
+            writer = writer || servletResponse.getWriter();
+            var length = arguments.length;
+            for (var i = 0; i < length; i++) {
+                writer.write(String(arguments[i]));
+                if (i < length - 1)
+                    writer.write(' ');
+            }
+            return this;
+        }
+    });
+
+    Object.defineProperty(this, 'writeln', {
+        value: function writeln() {
+            this.write.apply(this, arguments);
+            this.write('\r\n');
+            return this;
+        }
+    });
+
+
     /**
      * Render a skin to the response's buffer
      * @param skin
      * @param context
      * @param scope
      */
-    Object.defineProperty(Response.prototype, 'render', {
+    Object.defineProperty(this, 'render', {
         value: function render(skin, context, scope) {
             var render = require('helma/skin').render;
             this.write(render(skin, context, scope));
@@ -22,7 +47,7 @@
     /**
      * Print a debug message to the rendered page.
      */
-    Object.defineProperty(Response.prototype, 'debug', {
+    Object.defineProperty(this, 'debug', {
         value: function debug() {
             var buffer = this.debugBuffer || new Buffer();
             buffer.write("<div class=\"helma-debug-line\" style=\"background: yellow;");
@@ -43,7 +68,7 @@
     /**
      * Write the debug buffer to the response's main buffer.
      */
-    Object.defineProperty(Response.prototype, 'flushDebug', {
+    Object.defineProperty(this, 'flushDebug', {
         value: function() {
             if (this.debugBuffer != null) {
                 this.write(this.debugBuffer);
@@ -53,4 +78,21 @@
         }
     });
 
+    Object.defineProperty(this, 'redirect', {
+        value: function(target) {
+            servletResponse.sendRedirect(target);
+            // fixme: temporary solution until webapp refactoring
+            throw {redirect: target};
+        }
+    });
+
+    Object.defineProperty(this, 'charset', {
+        getter: function() {
+            return servletResponse.getCharacterEncoding();
+        },
+        setter: function(charset) {
+            servletResponse.setCharacterEncoding(charset);
+        }
+    });
+
 }

Modified: helma-ng/trunk/modules/helma/webapp.js
===================================================================
--- helma-ng/trunk/modules/helma/webapp.js	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/modules/helma/webapp.js	2009-04-10 12:10:56 UTC (rev 9601)
@@ -4,29 +4,35 @@
 
 // import modules
 require('core/string');
-require('helma/webapp/request');
-require('helma/webapp/response');
 
+include('helma/webapp/request');
+include('helma/webapp/response');
 import('helma/webapp/continuation', 'continuation');
+
 import('helma/system', 'system');
 import('helma/httpserver', 'server');
 import('helma/logging', 'logging');
 
-export('start', 'stop', 'getConfig', 'handleRequest', 'error', 'notfound');
+export('start', 'stop', 'getConfig', 'handleServletRequest', 'error', 'notfound');
 
 var log = logging.getLogger(__name__);
 
+function handleJackRequest(env) {}
+
 /**
  * Handler function called by the Helma servlet. 
  *
  * @param req
  * @param res
  */
-function handleRequest(req, res) {
+function handleServletRequest(servletRequest, servletResponse) {
     // get config and apply it to req, res
     var config = getConfig();
     if (log.debugEnabled) log.debug('got config: ' + config.toSource());
 
+    var req = new Request(servletRequest);
+    var res = new Response(servletResponse);
+
     req.charset = res.charset = config.charset || 'utf8';
     res.contentType = config.contentType || 'text/html';
 
@@ -41,7 +47,7 @@
     var path = req.path;
     if (path.startsWith('/')) {
         // strip leading slash
-        path = path.slice(1)
+        path = path.slice(1);
     }
 
     function getPattern(spec) {
@@ -107,8 +113,12 @@
         }
         notfound(req, res);
     } catch (e) {
-        invokeMiddleware('onError', config.middleware, [req, res, e]);
-        error(req, res, e);
+        if (e.retry) {
+            throw e;
+        } else if (!e.redirect) {
+            invokeMiddleware('onError', config.middleware, [req, res, e]);
+            error(req, res, e);
+        }
     } finally {
         invokeMiddleware('onResponse', config.middleware, [req, res]);
     }
@@ -124,7 +134,11 @@
                 module[hook].apply(module, args);
             }
         } catch (e) {
-            log.error('Error in ' + signature + ': ' + e);
+            if (e.retry) {
+                throw e;
+            } else if (!e.redirect) {
+                log.error('Error in ' + signature + ': ' + e);
+            }
         }
     }
 }

Modified: helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java
===================================================================
--- helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java	2009-04-10 12:10:56 UTC (rev 9601)
@@ -203,8 +203,17 @@
                     }
                     retval = ((Function) function).call(cx, topLevelScope, module, args);
                     break;
+                } catch (JavaScriptException jsx) {
+                    Scriptable thrown = jsx.getValue() instanceof Scriptable ?
+                            (Scriptable) jsx.getValue() : null;
+                    if (thrown != null && thrown.get("retry", thrown) == Boolean.TRUE) {
+                        ((Map) cx.getThreadLocal("modules")).clear();
+                    } else {
+                        throw jsx;
+                    }
                 } catch (RetryException retry) {
                     // request to try again
+                    ((Map) cx.getThreadLocal("modules")).clear();                    
                 }
             }
             if (retval instanceof Wrapper) {
@@ -272,6 +281,10 @@
         }
     }
 
+    /**
+     * Get the current Rhino optimization level
+     * @return the current optimization level
+     */
     public int getOptimizationLevel() {
         Context cx = Context.getCurrentContext();
         if (cx != null) {
@@ -279,13 +292,15 @@
         }
         return 0;
     }
-    
+
+    /**
+     * Set Rhino optimization level
+     * @param level the new optimization level
+     */
     public void setOptimizationLevel(int level) {
         Context cx = Context.getCurrentContext();
         if (cx != null && cx.getOptimizationLevel() != level) {
             cx.setOptimizationLevel(level);
-            ((Map) cx.getThreadLocal("modules")).clear();
-            throw new RetryException();
         }
     }
 
@@ -676,7 +691,14 @@
 
     }
 
-    public static class RetryException extends Error {}
+    public static class RetryException extends RuntimeException {
+        public final String retry;
+
+        public RetryException(String message) {
+            super(message);
+            retry = message;
+        }
+    }
 }
 
 class AppClassLoader extends HelmaClassLoader {

Modified: helma-ng/trunk/src/org/helma/web/HelmaServlet.java
===================================================================
--- helma-ng/trunk/src/org/helma/web/HelmaServlet.java	2009-04-10 07:32:43 UTC (rev 9600)
+++ helma-ng/trunk/src/org/helma/web/HelmaServlet.java	2009-04-10 12:10:56 UTC (rev 9601)
@@ -37,9 +37,6 @@
 
     static protected Class[] defaultHostClasses =
         new Class[] {
-            Request.class,
-            Response.class,
-            Session.class,
             MacroTag.class
         };
 
@@ -97,7 +94,7 @@
                            final HttpServletResponse res)
             throws ServletException, IOException {
         try {
-            engine.invoke(module, function, new Request(req), new Response(res));
+            engine.invoke(module, function, req, res);
         } catch (RedirectException redir) {
             res.sendRedirect(redir.getMessage());
         } catch (NoSuchMethodException x) {

_______________________________________________
Helma-CVS mailing list
[email protected]
http://helma.org/mailman/listinfo/helma-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.