msg = "[Macro error in " + fullName + ": " + msg + "]"; reval.getResponse().write(" " + msg + " "); app.logEvent(msg);
msg = new StringBuffer("Macro error in ").append(fullName) .append(": ").append(x.getMessage()).toString(); reval.getResponse().write(" [" + msg + "] ");  if (x instanceof ScriptingException) { x = ((ScriptingException) x).getWrappedException(); } app.logError(msg, x);
        public void render(RequestEvaluator reval, Object thisObject, Map paramObject,                           Map handlerCache)                throws RedirectException, UnsupportedEncodingException {            // immediately return for comment macros            if (isCommentMacro) {                return;            }            if ((sandbox != null) && !sandbox.contains(fullName)) {                reval.getResponse().write("[Macro " + fullName + " not allowed in sandbox]");                return;            } else if ("response".equalsIgnoreCase(handler)) {                renderFromResponse(reval);                return;            } else if ("request".equalsIgnoreCase(handler)) {                renderFromRequest(reval);                return;            } else if ("param".equalsIgnoreCase(handler)) {                renderFromParam(reval, paramObject);                return;            } else if ("session".equalsIgnoreCase(handler)) {                renderFromSession(reval);                return;            }            try {                Object handlerObject = null;                // flag to tell whether we found our invocation target object                boolean objectFound = true;                if (handler != null) {                    // try to get handler from handlerCache first                    if (handlerCache != null) {                        handlerObject = handlerCache.get(handler);                    }                    if (handlerObject == null) {                        // if handler object wasn't found in cache retrieve it                        if ((handlerObject == null) && (thisObject != null)) {                            // not a global macro - need to find handler object                            // was called with this object - check it or its parents for matching prototype                            if (!handler.equals("this") &&                                    !handler.equalsIgnoreCase(app.getPrototypeName(thisObject))) {                                // the handler object is not what we want                                Object n = thisObject;                                // walk down parent chain to find handler object                                while (n != null) {                                    Prototype proto = app.getPrototype(n);                                    if ((proto != null) && proto.isInstanceOf(handler)) {                                        handlerObject = n;                                        break;                                    }                                    n = app.getParentElement(n);                                }                            } else {                                // we already have the right handler object                                handlerObject = thisObject;                            }                        }                        if (handlerObject == null) {                            // eiter because thisObject == null or the right object wasn't found                            // in the object's parent path. Check if a matching macro handler                            // is registered with the response object (res.handlers).                            handlerObject = reval.getResponse().getMacroHandlers().get(handler);                        }                        // the macro handler object couldn't be found                        if (handlerObject == null) {                            objectFound = false;                        }                        // else put the found handler object into the cache so we don't have to look again                        else if (handlerCache != null) {                            handlerCache.put(handler, handlerObject);                        }                    }                } else {                    // this is a global macro with no handler specified                    handlerObject = null;                }                if (objectFound) {                    // check if a function called name_macro is defined.                    // if so, the macro evaluates to the function. Otherwise,                    // a property/field with the name is used, if defined.                    String funcName = name + "_macro";                    if (reval.scriptingEngine.hasFunction(handlerObject, funcName)) {                        StringBuffer buffer = reval.getResponse().getBuffer();                        RenderParameters renderParams = defaultRenderParams;                        // remember length of response buffer before calling macro                        int bufLength = buffer.length();                        // pass a clone/copy of the parameter map so if the script changes it,                        CopyOnWriteMap wrappedParams = null;                        Object[] arguments;                        if (params == null) {                            arguments = new Object[] { new SystemMap(4) };                        } else {                            wrappedParams = new CopyOnWriteMap(params);                            arguments = new Object[] { wrappedParams };                        }                        Object value = reval.invokeDirectFunction(handlerObject,                                                                  funcName,                                                                  arguments);                        // if parameter map was modified create new renderParams to override defaults                        if (wrappedParams != null && wrappedParams.wasModified()) {                            renderParams = new RenderParameters(wrappedParams);                        }                        // check if macro wrote out to response buffer                        if (buffer.length() == bufLength) {                            // If the macro function didn't write anything to the response itself,                            // we interpret its return value as macro output.                            writeResponse(value, buffer, renderParams, true);                        } else {                            // if an encoding is specified, re-encode the macro's output                            if (encoding != ENCODE_NONE) {                                String output = buffer.substring(bufLength);                                buffer.setLength(bufLength);                                writeResponse(output, buffer, renderParams, false);                            } else {                                // insert prefix,                                if (renderParams.prefix != null) {                                    buffer.insert(bufLength, renderParams.prefix);                                }                                // append suffix                                if (renderParams.suffix != null) {                                    buffer.append(renderParams.suffix);                                }                            }                            // Append macro return value even if it wrote something to the response,                            // but don't render default value in case it returned nothing.                            // We do this for the sake of consistency.                            writeResponse(value, buffer, renderParams, false);                        }                    } else {                        // for unhandled global macros display error message,                        // otherwise try property lookup                        if (handlerObject == null) {                            String msg = "[Macro unhandled: " + fullName + "]";                            reval.getResponse().write(" " + msg + " ");                            app.logEvent(msg);                                                    } else {                            Object value = reval.scriptingEngine.get(handlerObject, name);                            writeResponse(value, reval.getResponse().getBuffer(), defaultRenderParams, true);                        }                    }                } else {                    String msg = "[Macro unhandled: " + fullName + "]";                    reval.getResponse().write(" " + msg + " ");                    app.logEvent(msg);                }            } catch (RedirectException redir) {                throw redir;            } catch (ConcurrencyException concur) {                throw concur;            } catch (TimeoutException timeout) {                throw timeout;            } catch (Exception x) {                // x.printStackTrace();                String msg = x.getMessage();                if ((msg == null) || (msg.length() < 10)) {                    msg = x.toString();                }                msg = "[Macro error in " + fullName + ": " + msg + "]";                reval.getResponse().write(" " + msg + " ");                app.logEvent(msg);            }        }