Reinhard Pötz wrote:
<dream-mode>
I would like to use this Avalon component mentioned above and
the Flow interpreter takes care of releasing (and providing)
stateful components within my scripts. So I would have to
lookup the Hibernate Session at the beginning(2) and until I finally release(8) it I don't have to take care for it.
1 function xxx() { 2 var hibS = cocoon.getComponent( "hibernateSession" ); 3 var custBean = hibS.blablabla // get your beans with hibernate 4 sendPageAndWait( "bla", {customer : custBean} ); 5 // do something (updates, reads, whatever) 6 var someDifferentBean = hibS.blalbalba 7 sendPageAndWait( "bla", {diff : someDifferentBean } ); 8 sendPageAndRelease( "thankYou", {} ); 9 }
This would be IMO a very elegant way and IIU the recent discussion correctly possible from a technical point of view. Maybe Chris can comment on this :-)
Thoughts?
</dream-mode>
Cheers, Reinhard
/*
============================================================================ The Apache Software License, Version 1.1 ============================================================================ Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved. Redistribution and use in source and binary forms, with or without modifica- tion, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by the Apache Software Foundation (http://www.apache.org/)." Alternately, this acknowledgment may appear in the software itself, if and wherever such third-party acknowledgments normally appear. 4. The names "Apache Cocoon" and "Apache Software Foundation" must not be used to endorse or promote products derived from this software without prior written permission. For written permission, please contact [EMAIL PROTECTED] 5. Products derived from this software may not be called "Apache", nor may "Apache" appear in their name, without prior written permission of the Apache Software Foundation. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions made by many individuals on behalf of the Apache Software Foundation and was originally created by Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache Software Foundation, please see <http://www.apache.org/>. */ package org.apache.cocoon.components.flow.javascript.fom; import java.io.OutputStream; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.HashSet; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.logger.Logger; import org.apache.cocoon.components.flow.ContinuationsManager; import org.apache.cocoon.components.flow.WebContinuation; import org.apache.cocoon.environment.Cookie; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Response; import org.apache.cocoon.environment.Session; import org.mozilla.javascript.*; import org.mozilla.javascript.continuations.Continuation; /** * Implementation of FOM (Flow Object Model). * * @since 2.1 * @author <a href="mailto:coliver.at.apache.org">Christopher Oliver</a> * @author <a href="mailto:reinhard.at.apache.org">Reinhard Pötz</a> * @version CVS $Id: FOM_Cocoon.java,v 1.3 2003/07/10 11:40:57 cziegeler Exp $ */ public class FOM_Cocoon extends ScriptableObject { private FOM_JavaScriptInterpreter interpreter; private Environment environment; private ComponentManager componentManager; private Logger logger; private FOM_Request request; private FOM_Response response; private FOM_Session session; private FOM_Context context; private Scriptable parameters; private FOM_Log log; private WebContinuation lastContinuation; private Set components = new HashSet(); public String getClassName() { return "FOM_Cocoon"; } // Called by FOM_JavaScriptInterpreter static void init(Scriptable scope) throws Exception { defineClass(scope, FOM_Cocoon.class); defineClass(scope, FOM_Request.class); defineClass(scope, FOM_Response.class); defineClass(scope, FOM_Cookie.class); defineClass(scope, FOM_Session.class); defineClass(scope, FOM_Context.class); defineClass(scope, FOM_Log.class); defineClass(scope, FOM_WebContinuation.class); } void setup(FOM_JavaScriptInterpreter interp, Environment env, ComponentManager manager, Logger logger) { this.interpreter = interp; this.environment = env; this.componentManager = manager; this.logger = logger; } public void invalidate() { this.request = null; this.response = null; this.session = null; this.context = null; this.environment = null; this.log = null; this.parameters = null; this.interpreter = null; synchronized (components) { Iterator iter = components.iterator(); while (iter.hasNext()) { ComponentWrapper c = (ComponentWrapper)iter.next(); c.invalidate(); } } } void addComponent(ComponentWrapper c) { synchronized (components) { components.add(c); } } void releaseComponent(ComponentWrapper c) { synchronized (components) { components.remove(c); } } /** * JS Wrapper for Avalon components: underlying component is * automagically released when a continuation is captured * and reacquired on demand. * */ static class ComponentWrapper extends ScriptableObject { FOM_Cocoon cocoon; String id; Scriptable wrapper; public String getClassName() { return "Component"; } public ComponentWrapper(FOM_Cocoon cocoon, String id) { this.cocoon = cocoon; this.id = id; } private Scriptable getWrapper() { if (wrapper == null) { if (cocoon.componentManager != null) { try { wrapper = Context.toObject(cocoon.componentManager.lookup(id), getTopLevelScope(this)); } catch (Exception exc) { throw Context.reportRuntimeError(exc.getMessage()); } } } return wrapper; } private static Object wrap(final Scriptable wrapper, final Scriptable wrapped, Object obj) { if (obj instanceof Function) { return wrap(wrapper, wrapped, (Function)obj); } return obj; } private static Function wrap(final Scriptable wrapper, final Scriptable wrapped, final Function fun) { return new Function() { public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) throws JavaScriptException { if (thisObj == wrapper) { thisObj = wrapped; } return fun.call(cx, scope, thisObj, args); } public Scriptable construct(Context cx, Scriptable scope, Object[] args) throws JavaScriptException { return fun.construct(cx, scope, args); } public String getClassName() { return fun.getClassName(); } public Object get(String name, Scriptable start) { return fun.get(name, fun); } public Object get(int index, Scriptable start) { return fun.get(index, fun); } public boolean has(String name, Scriptable start) { return fun.has(name, start); } public boolean has(int index, Scriptable start) { return fun.has(index, start); } public void put(String name, Scriptable start, Object value) { fun.put(name, start, value); } public void put(int index, Scriptable start, Object value) { fun.put(index, start, value); } public void delete(String name) { fun.delete(name); } public void delete(int index) { fun.delete(index); } public Scriptable getPrototype() { return fun.getPrototype(); } public void setPrototype(Scriptable prototype) { } public Scriptable getParentScope() { return fun.getParentScope(); } public void setParentScope(Scriptable parent) { } public Object[] getIds() { return fun.getIds(); } public Object getDefaultValue(Class hint) { return fun.getDefaultValue(hint); } public boolean hasInstance(Scriptable instance) { return fun.hasInstance(instance); } }; } public Object get(String name, Scriptable start) { Scriptable wrapper = getWrapper(); if (wrapper != null) { Object result = wrapper.get(name, wrapper); if (result != NOT_FOUND) { return wrap(this, wrapper, result); } } return super.get(name, start); } public boolean has(String name, Scriptable start) { Scriptable wrapper = getWrapper(); if (wrapper != null) { if (wrapper.has(name, wrapper)) { return true; } } return super.has(name, start); } public boolean has(int index, Scriptable start) { Scriptable wrapper = getWrapper(); if (wrapper != null) { if (wrapper.has(index, start)) { return true; } } return super.has(index, start); } public Object get(int index, Scriptable start) { Scriptable wrapper = getWrapper(); if (wrapper != null) { Object result = wrapper.get(index, start); if (result != NOT_FOUND) { return wrap(this, wrapper, result); } } return super.get(index, start); } public void put(String name, Scriptable start, Object value) { Scriptable wrapper = getWrapper(); if (wrapper != null) { wrapper.put(name, wrapper, value); return; } super.put(name, start, value); } public boolean hasInstance(Scriptable instance) { Scriptable wrapper = getWrapper(); if (wrapper != null) { return wrapper.hasInstance(instance); } return super.hasInstance(instance); } public Object getDefaultValue(Class hint) { Scriptable wrapper = getWrapper(); if (wrapper != null) { return wrapper.getDefaultValue(hint); } return super.getDefaultValue(hint); } public void release() { invalidate(); if (cocoon != null) { cocoon.releaseComponent(this); cocoon = null; } } void invalidate() { if (wrapper != null) { cocoon.componentManager.release((Component)unwrap(wrapper)); wrapper = null; } } protected void finalize() { cocoon.releaseComponent(this); } // Any JS methods you add here will be common to all components } public Object jsFunction_getComponent(String id) throws Exception { ComponentWrapper wrapper = new ComponentWrapper(this, id); wrapper.setPrototype(getClassPrototype(this, "Component")); wrapper.setParentScope(getParentScope()); addComponent(wrapper); return wrapper; } public void jsFunction_releaseComponent(Object c) { ComponentWrapper wrapper = (ComponentWrapper)c; wrapper.release(); } private FOM_WebContinuation forwardTo(String uri, Object bizData, Continuation continuation) throws Exception { WebContinuation wk = null; if (continuation != null) { ContinuationsManager contMgr = (ContinuationsManager) componentManager.lookup(ContinuationsManager.ROLE); wk = lastContinuation = contMgr.createWebContinuation(continuation, lastContinuation, 0); } String redUri = uri; if(! uri.startsWith( "cocoon://" ) ) { redUri = "cocoon://" + this.environment.getURIPrefix() + uri; } interpreter.forwardTo(getParentScope(), this, redUri, bizData, wk, environment); FOM_WebContinuation result = null; if (wk != null) { result = new FOM_WebContinuation(wk); result.setParentScope(getParentScope()); result.setPrototype(getClassPrototype(getParentScope(), result.getClassName())); } return result; } public FOM_WebContinuation jsFunction_sendPage(String uri, Object obj, Object continuation) throws Exception { return forwardTo(uri, obj, (Continuation)unwrap(continuation)); } public void jsFunction_processPipelineTo(String uri, Object map, Object outputStream) throws Exception { if (!(unwrap(outputStream) instanceof OutputStream)) { throw new JavaScriptException("expected a java.io.OutputStream instead of " + outputStream); } interpreter.process(getParentScope(), this, uri, map, (OutputStream)unwrap(outputStream), environment); } public void jsFunction_redirectTo(String uri) throws Exception { environment.redirect(false, uri); } /* NOTE (SM): These are the hooks to the future FOM Event Model that will be designed in the future. It has been postponed because we think there are more important things to do at the moment, but these are left here to indicate that they are planned. public void jsFunction_addEventListener(String eventName, Object function) { // what is this? } public void jsFunction_removeEventListener(String eventName, Object function) { // what is this? } */ /** * Load the script file specified as argument. * * @param filename a <code>String</code> value * @return an <code>Object</code> value * @exception JavaScriptException if an error occurs */ public Object jsFunction_load( String filename ) throws Exception { org.mozilla.javascript.Context cx = org.mozilla.javascript.Context.getCurrentContext(); Scriptable scope = getParentScope(); Script script = interpreter.compileScript( cx, environment, filename ); return script.exec( cx, scope ); } public static class FOM_Request extends ScriptableObject { Request request; public FOM_Request() { // prototype ctor } public FOM_Request(Object request) { this.request = (Request)unwrap(request); } public String getClassName() { return "FOM_Request"; } public Object jsFunction_get(String name) { return request.get(name); } public Object jsFunction_getAttribute(String name) { return request.getAttribute(name); } public String jsFunction_getRemoteUser() { return request.getRemoteUser(); } public void jsFunction_removeAttribute(String name) { request.removeAttribute(name); } public void jsFunction_setAttribute(String name, Object value) { request.setAttribute(name, unwrap(value)); } public Object get(String name, Scriptable start) { Object result = super.get(name, start); if (result == NOT_FOUND && request != null) { result = request.getParameter(name); if (result == null) { result = NOT_FOUND; } } return result; } public Object[] getIds() { if (request != null) { List list = new LinkedList(); Enumeration e = request.getAttributeNames(); while (e.hasMoreElements()) { list.add(e.nextElement()); } Object[] result = new Object[list.size()]; list.toArray(result); return result; } return super.getIds(); } public String jsFunction_getCharacterEncoding() { return request.getCharacterEncoding(); } public void jsFunction_setCharacterEncoding(String value) throws Exception { request.setCharacterEncoding(value); } public int jsFunction_getContentLength() { return request.getContentLength(); } public String jsFunction_getContentType() { return request.getContentType(); } public String jsFunction_getParameter(String name) { return request.getParameter(name); } public Object jsFunction_getParameterValues(String name) { return request.getParameterValues(name); } public Object jsFunction_getParameterNames() { return request.getParameterNames(); } public String jsFunction_getAuthType() { return request.getAuthType(); } public String jsFunction_getProtocol() { return request.getProtocol(); } } public static class FOM_Cookie extends ScriptableObject { Cookie cookie; public FOM_Cookie() { // prototype ctor } public FOM_Cookie(Object cookie) { this.cookie = (Cookie)unwrap(cookie); } public String getClassName() { return "FOM_Cookie"; } public String jsGet_name() { return cookie.getName(); } public int jsGet_version() { return cookie.getVersion(); } public void jsSet_version(int value) { cookie.setVersion(value); } public String jsGet_value() { return cookie.getValue(); } public void jsSet_value(String value) { cookie.setValue(value); } public void jsSet_comment(String purpose) { cookie.setComment(purpose); } public String jsGet_comment() { return cookie.getComment(); } public void jsSet_domain(String pattern) { cookie.setDomain(pattern); } public String jsGet_domain() { return cookie.getDomain(); } public void jsSet_maxAge(int value) { cookie.setMaxAge(value); } public int jsGet_maxAge() { return cookie.getMaxAge(); } public void jsSet_path(String value) { cookie.setPath(value); } public String jsGet_path() { return cookie.getPath(); } public void jsSet_secure(boolean value) { cookie.setSecure(value); } public boolean jsGet_secure() { return cookie.getSecure(); } } public static class FOM_Response extends ScriptableObject { Response response; public FOM_Response() { // prototype ctor } public FOM_Response(Object response) { this.response = (Response)unwrap(response); } public String getClassName() { return "FOM_Response"; } public Object jsFunction_createCookie(String name, String value) { FOM_Cookie result = new FOM_Cookie(response.createCookie(name, value)); result.setParentScope(getParentScope()); result.setPrototype(getClassPrototype(this, "FOM_Cookie")); return result; } public void jsFunction_addCookie(Object cookie) throws JavaScriptException { if (!(cookie instanceof FOM_Cookie)) { throw new JavaScriptException("expected a Cookie instead of " + cookie); } FOM_Cookie fom_cookie = (FOM_Cookie)cookie; response.addCookie(fom_cookie.cookie); } public boolean jsFunction_containsHeader(String name) { return response.containsHeader(name); } public void jsFunction_setHeader(String name, String value) { response.setHeader(name, value); } public void jsFunction_addHeader(String name, String value) { response.addHeader(name, value); } } public static class FOM_Session extends ScriptableObject { Session session; public FOM_Session() { // prototype ctor } public FOM_Session(Object session) { this.session = (Session)unwrap(session); } public String getClassName() { return "FOM_Session"; } public Object[] getIds() { if (session != null) { List list = new LinkedList(); Enumeration e = session.getAttributeNames(); while (e.hasMoreElements()) { list.add(e.nextElement()); } Object[] result = new Object[list.size()]; list.toArray(result); return result; } return super.getIds(); } public Object get(String name, Scriptable start) { Object result = super.get(name, start); if (result == NOT_FOUND && session != null) { result = session.getAttribute(name); if (result == null) { result = NOT_FOUND; } } return result; } public Object jsFunction_getAttribute(String name) { return session.getAttribute(name); } public void jsFunction_setAttribute(String name, Object value) { session.setAttribute(name, value); } public void jsFunction_removeAttribute(String name) { session.removeAttribute(name); } public Object jsFunction_getAttributeNames() { return session.getAttributeNames(); } public void jsFunction_invalidate() { session.invalidate(); } public boolean jsFunction_isNew() { return session.isNew(); } public String jsFunction_getId() { return session.getId(); } public long jsFunction_getCreationTime() { return session.getCreationTime(); } public long jsFunction_getLastAccessedTime() { return session.getLastAccessedTime(); } public void jsFunction_setMaxInactiveInterval(int interval) { session.setMaxInactiveInterval(interval); } public int jsFunction_getMaxInactiveInterval() { return session.getMaxInactiveInterval(); } } public static class FOM_Context extends ScriptableObject { org.apache.cocoon.environment.Context context; public FOM_Context() { // prototype ctor } public FOM_Context(Object context) { this.context = (org.apache.cocoon.environment.Context)unwrap(context); } public String getClassName() { return "FOM_Context"; } public Object jsFunction_getAttribute(String name) { return context.getAttribute(name); } public void jsFunction_setAttribute(String name, Object value) { context.setAttribute(name, unwrap(value)); } public void jsFunction_removeAttribute(String name) { context.removeAttribute(name); } public Object jsFunction_getAttributeNames() { return context.getAttributeNames(); } public Object jsFunction_getInitParameter(String name) { return context.getInitParameter(name); } public Object[] getIds() { if (context != null) { List list = new LinkedList(); Enumeration e = context.getAttributeNames(); while (e.hasMoreElements()) { list.add(e.nextElement()); } Object[] result = new Object[list.size()]; list.toArray(result); return result; } return super.getIds(); } public Object get(String name, Scriptable start) { Object value = super.get(name, start); if (value == NOT_FOUND && context != null) { value = context.getAttribute(name); if (value == null) { value = NOT_FOUND; } } return value; } } public static class FOM_Log extends ScriptableObject { private Logger logger; public FOM_Log() { } public FOM_Log(Object logger) { this.logger = (Logger)unwrap(logger); } public String getClassName() { return "FOM_Log"; } public void jsFunction_debug(String message) { logger.debug(message); } public void jsFunction_info(String message) { logger.info(message); } public void jsFunction_warn(String message) { logger.warn(message); } public void jsFunction_error(String message) { logger.error(message); } public boolean jsFunction_isDebugEnabled() { return logger.isDebugEnabled(); } public boolean jsFunction_isInfoEnabled() { return logger.isInfoEnabled(); } public boolean jsFunction_isWarnEnabled() { return logger.isWarnEnabled(); } public boolean jsFunction_isErrorEnabled() { return logger.isErrorEnabled(); } } public static class FOM_WebContinuation extends ScriptableObject { WebContinuation wk; public FOM_WebContinuation() { } public FOM_WebContinuation(Object wk) { this.wk = (WebContinuation)unwrap(wk); } public String getClassName() { return "FOM_WebContinuation"; } public String jsGet_id() { return wk.getId(); } public FOM_WebContinuation jsFunction_getParent() { WebContinuation parent = wk.getParentContinuation(); if (parent == null) return null; FOM_WebContinuation pwk = new FOM_WebContinuation(parent); pwk.setParentScope(getParentScope()); pwk.setPrototype(getClassPrototype(getParentScope(), pwk.getClassName())); return pwk; } public NativeArray jsFunction_getChildren() throws Exception { List list = wk.getChildren(); NativeArray arr = (NativeArray)org.mozilla.javascript.Context.getCurrentContext().newObject(getParentScope(), "Array", new Object[]{new Integer(list.size())}); Iterator iter = list.iterator(); for (int i = 0; iter.hasNext(); i++) { WebContinuation child = (WebContinuation)iter.next(); FOM_WebContinuation cwk = new FOM_WebContinuation(child); cwk.setParentScope(getParentScope()); cwk.setPrototype(getClassPrototype(getParentScope(), cwk.getClassName())); arr.put(i, arr, cwk); } return arr; } public void jsFunction_invalidate() throws Exception { ContinuationsManager contMgr = null; FOM_Cocoon cocoon = (FOM_Cocoon)getProperty(getTopLevelScope(this), "cocoon"); ComponentManager componentManager = cocoon.getComponentManager(); contMgr = (ContinuationsManager) componentManager.lookup(ContinuationsManager.ROLE); contMgr.invalidateWebContinuation(wk); } public WebContinuation getWebContinuation() { return wk; } } public FOM_Request jsGet_request() { if (request != null) { return request; } if (environment == null) { // context has been invalidated return null; } Map objectModel = environment.getObjectModel(); request = new FOM_Request(ObjectModelHelper.getRequest(objectModel)); request.setParentScope(getParentScope()); request.setPrototype(getClassPrototype(getParentScope(), "FOM_Request")); return request; } public FOM_Response jsGet_response() { if (response != null) { return response; } if (environment == null) { // context has been invalidated return null; } Map objectModel = environment.getObjectModel(); response = new FOM_Response(ObjectModelHelper.getResponse(objectModel)); response.setParentScope(getParentScope()); response.setPrototype(getClassPrototype(this, "FOM_Response")); return response; } public FOM_Log jsGet_log() { if (log != null) { return log; } log = new FOM_Log(logger); log.setParentScope(getParentScope()); log.setPrototype(getClassPrototype(this, "FOM_Log")); return log; } public FOM_Context jsGet_context() { if (context != null) { return context; } Map objectModel = environment.getObjectModel(); context = new FOM_Context(ObjectModelHelper.getContext(objectModel)); context.setParentScope(getParentScope()); context.setPrototype(getClassPrototype(this, "FOM_Context")); return context; } public FOM_Session jsGet_session() { if (session != null) { return session; } if (environment == null) { // session has been invalidated return null; } Map objectModel = environment.getObjectModel(); session = new FOM_Session(ObjectModelHelper.getRequest(objectModel).getSession(true)); session.setParentScope(getParentScope()); session.setPrototype(getClassPrototype(this, "FOM_Session")); return session; } /** * Get Sitemap parameters * * @return a <code>Scriptable</code> value whose properties represent * the Sitemap parameters from <map:call> */ public Scriptable jsGet_parameters() { return parameters; } void setParameters(Scriptable value) { parameters = value; } // unwrap Wrapper's and convert undefined to null private static Object unwrap(Object obj) { if (obj instanceof Wrapper) { obj = ((Wrapper)obj).unwrap(); } else if (obj == Undefined.instance) { obj = null; } return obj; } // Make everything available to JavaScript objects implemented in Java: public Request getRequest() { return jsGet_request().request; } public Session getSession() { return jsGet_session().session; } public Response getResponse() { return jsGet_response().response; } public org.apache.cocoon.environment.Context getContext() { return jsGet_context().context; } public Environment getEnvironment() { return environment; } public ComponentManager getComponentManager() { return componentManager; } public FOM_JavaScriptInterpreter getInterpreter() { return interpreter; } public FOM_WebContinuation makeWebContinuation(WebContinuation wk) { if (wk == null) return null; FOM_WebContinuation result = new FOM_WebContinuation(wk); result.setParentScope(getParentScope()); result.setPrototype(getClassPrototype(getParentScope(), result.getClassName())); return result; } }