vgritsenko 2002/07/29 18:17:49 Modified: . Tag: cocoon_2_0_3_branch changes.xml src/java/org/apache/cocoon/components/xscript Tag: cocoon_2_0_3_branch StringBufferContentHandler.java XScriptManager.java XScriptManagerImpl.java XScriptObjectFromURL.java XScriptObjectInlineXML.java XScriptVariableScope.java Added: src/webapp/docs/samples/xscript Tag: cocoon_2_0_3_branch test.xsp Log: XScript now has better variable management: variables of request, session, global, and page scope are stored not in the XScriptManager, but as request, session, context attributes, or as XSP page field (respectively). Chances of memory leaks are highly reduced. Revision Changes Path No revision No revision 1.138.2.38 +7 -1 xml-cocoon2/changes.xml Index: changes.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/changes.xml,v retrieving revision 1.138.2.37 retrieving revision 1.138.2.38 diff -u -r1.138.2.37 -r1.138.2.38 --- changes.xml 25 Jul 2002 14:00:31 -0000 1.138.2.37 +++ changes.xml 30 Jul 2002 01:17:48 -0000 1.138.2.38 @@ -39,6 +39,12 @@ </devs> <release version="@version@" date="@date@"> + <action dev="VG" type="update"> + XScript now has better variable management: variables of request, + session, global, and page scope are stored not in the XScriptManager, + but as request, session, context attributes, or as XSP page field + (respectively). Chances of memory leaks are highly reduced. + </action> <action dev="VG" type="fix"> Include all warnings and errors reported by the XSLT engine into the TransformerException if transformation fails or terminated by the No revision No revision 1.1.2.1 +151 -0 xml-cocoon2/src/webapp/docs/samples/xscript/Attic/test.xsp No revision No revision 1.4.2.3 +4 -9 xml-cocoon2/src/java/org/apache/cocoon/components/xscript/StringBufferContentHandler.java Index: StringBufferContentHandler.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xscript/StringBufferContentHandler.java,v retrieving revision 1.4.2.2 retrieving revision 1.4.2.3 diff -u -r1.4.2.2 -r1.4.2.3 --- StringBufferContentHandler.java 26 Jul 2002 04:40:49 -0000 1.4.2.2 +++ StringBufferContentHandler.java 30 Jul 2002 01:17:49 -0000 1.4.2.3 @@ -51,7 +51,6 @@ package org.apache.cocoon.components.xscript; import org.xml.sax.Attributes; -import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; @@ -68,17 +67,13 @@ * @since August 30, 2001 */ public class StringBufferContentHandler extends DefaultHandler { + private static Object marker = new Object(); + private Stack namespaces = new Stack(); - ContentHandler contentHandler; - StringBuffer stringBuffer; - static Object marker = new Object(); + private StringBuffer stringBuffer; public StringBufferContentHandler(StringBuffer stringBuffer) { this.stringBuffer = stringBuffer; - } - - public void setNextContentHandler(ContentHandler handler) { - this.contentHandler = handler; } public void startPrefixMapping(String prefix, String uri) 1.4.2.2 +42 -26 xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptManager.java Index: XScriptManager.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptManager.java,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -r1.4.2.1 -r1.4.2.2 --- XScriptManager.java 26 Jul 2002 04:40:49 -0000 1.4.2.1 +++ XScriptManager.java 30 Jul 2002 01:17:49 -0000 1.4.2.2 @@ -50,6 +50,7 @@ */ package org.apache.cocoon.components.xscript; +import java.util.Map; /** * <code>XScriptManager</code> is the public interface used to @@ -57,10 +58,12 @@ * supporting code for the XScript language. * * @author <a href="mailto:[EMAIL PROTECTED]">Ovidiu Predescu</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a> * @version CVS $Id$ * @since August 4, 2001 */ -public interface XScriptManager { +public interface XScriptManager +{ String ROLE = "org.apache.cocoon.components.xscript.XScriptManager"; String XSCRIPT_NS = "http://apache.org/xsp/xscript/1.0"; @@ -70,6 +73,7 @@ * global scope for variables. */ int GLOBAL_SCOPE = 1; + /** * The session scope. This scope is specific to a particular * activation of an XSP page, which is usually identified by the @@ -90,6 +94,13 @@ int PAGE_SCOPE = 3; /** + * The request scope. This is scope specific to request, and + * defines variables visible only within the context of that + * request. Once request is processed, these variables are lost. + */ + int REQUEST_SCOPE = 5; + + /** * Search for a variable in all the accessible scopes. The variable * is first searched in the current session scope. If no variable is * found here, the current page scope is searched next. If nothing @@ -119,14 +130,15 @@ * * </ul> * + * @param objectModel an instance of Cocoon object model used to obtain context * @param name a <code>String</code> value * @param scope an <code>int</code> value - * @param context a <code>String</code> value whose interpretation - * depends on <code>scope</code> * @return a <code>{@link XScriptObject}</code> value */ - XScriptObject get(String name, int scope, String context) - throws IllegalArgumentException; + XScriptObject get(XScriptVariableScope pageScope, + Map objectModel, + String name, + int scope) throws IllegalArgumentException; /** * Search for the first occurence of the variable @@ -142,54 +154,58 @@ * returned if a variable is found in one of the scopes, otherwise * an exception is thrown. * + * @param objectModel an instance of Cocoon object model used to obtain context * @param name a <code>String</code> value - * @param sessionContext a <code>String</code> value - * @param pageContext a <code>String</code> value * @return a <code>XScriptObject</code> value * @exception IllegalArgumentException if an error occurs */ - XScriptObject getFirst(String name, - String sessionContext, - String pageContext) - throws IllegalArgumentException; + XScriptObject getFirst(XScriptVariableScope pageScope, + Map objectModel, + String name) throws IllegalArgumentException; /** * Defines or overwrites the value of variable * <code>name</code> in <code>scope</code>. The <code>context</code> - * argument is interpreted as described in {@link #get(String, int, - * String)}. + * argument is interpreted as described in + * {@link #get(XScriptVariableScope, Map, String, int)}. * + * @param objectModel an instance of Cocoon object model used to obtain context * @param name a <code>String</code> value * @param value a <code>XScriptObject</code> value * @param scope an <code>int</code> value - * @param context a <code>String</code> value whose interpretation - * depends on <code>scope</code> */ - void put(String name, XScriptObject value, int scope, String context) - throws IllegalArgumentException; + void put(XScriptVariableScope pageScope, + Map objectModel, + String name, + XScriptObject value, + int scope) throws IllegalArgumentException; /** * Removes a variable previously declared in <code>scope</code> * within <code>context</code>. Such a variable could be declared - * using the {@link #put(String, XScriptObject, int, String)} + * using the {@link #put(XScriptVariableScope, Map, String, XScriptObject, int)} * method. * + * @param objectModel an instance of Cocoon object model used to obtain context * @param name a <code>String</code> value * @param scope an <code>int</code> value - * @param context a <code>String</code> value + * @exception IllegalArgumentException if an error occurs */ - void remove(String name, int scope, String context); + XScriptObject remove(XScriptVariableScope pageScope, + Map objectModel, + String name, + int scope) throws IllegalArgumentException; /** * Remove the first appearance of <code>name</code> in the all the * currently accessible scopes. The search happens as described in - * {@link #getFirst(String,String,String)}. + * {@link #getFirst(XScriptVariableScope, Map, String)}. * + * @param objectModel an instance of Cocoon object model used to obtain context * @param name a <code>String</code> value - * @param sessionContext a <code>String</code> value - * @param pageContext a <code>String</code> value * @exception IllegalArgumentException if an error occurs */ - void removeFirst(String name, String sessionContext, String pageContext) - throws IllegalArgumentException; + XScriptObject removeFirst(XScriptVariableScope pageScope, + Map objectModel, + String name) throws IllegalArgumentException; } 1.6.2.3 +188 -128 xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptManagerImpl.java Index: XScriptManagerImpl.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptManagerImpl.java,v retrieving revision 1.6.2.2 retrieving revision 1.6.2.3 diff -u -r1.6.2.2 -r1.6.2.3 --- XScriptManagerImpl.java 26 Jul 2002 04:40:49 -0000 1.6.2.2 +++ XScriptManagerImpl.java 30 Jul 2002 01:17:49 -0000 1.6.2.3 @@ -59,8 +59,16 @@ import org.apache.avalon.framework.parameters.Parameterizable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.avalon.framework.context.Contextualizable; +import org.apache.avalon.framework.context.ContextException; -import java.util.HashMap; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.environment.ObjectModelHelper; +import org.apache.cocoon.environment.Context; +import org.apache.cocoon.environment.Session; +import org.apache.cocoon.Constants; + +import java.util.Map; /** * The actual implementation of the <code>XScriptManager</code> interface. @@ -71,57 +79,57 @@ */ public class XScriptManagerImpl extends AbstractLoggable - implements XScriptManager, Composable, Component, Parameterizable, ThreadSafe { - /** - * The global scope. All the global variables are indexed in this - * space by their name. - */ - XScriptVariableScope globalScope = new XScriptVariableScope(); + implements XScriptManager, Composable, Component, Parameterizable, Contextualizable, ThreadSafe +{ + public static final String CONTEXT = "org.apache.cocoon.components.xscript.scope"; /** - * The session scope. The key in this hash table is the session - * identifier, which should be a <code>String</code> object. The - * value is an {@link XScriptVariableScope} instance which holds the - * variables in a session scope. + * The <code>ComponentManager</code> instance. */ - HashMap sessionScope = new HashMap(); + protected ComponentManager manager = null; /** - * Page specific variables. The key in the hash map is an identifier - * for the page, usually the full path name to the page. The value - * is an {@link XScriptVariableScope} instance which holds the - * variables in a page scope. + * The <code>Context</code> instance. */ - HashMap pageScope = new HashMap(); + protected Context context = null; - /** - * The <code>ComponentManager</code> instance. - */ - protected ComponentManager manager = null; - public void compose(ComponentManager manager) throws ComponentException { + public void contextualize(org.apache.avalon.framework.context.Context context) + throws ContextException + { + this.context = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT); + } + + public void compose(ComponentManager manager) + throws ComponentException + { this.manager = manager; - getLogger().debug("XScriptManager component initialized."); } public void register(XScriptObject object) { try { object.compose(manager); - } catch (ComponentException ex) { - } + } catch (ComponentException ignored) { } } - public void parameterize(Parameters params) throws ParameterException { + public void parameterize(Parameters params) + throws ParameterException + { String[] names = params.getNames(); + + XScriptVariableScope s = new XScriptVariableScope(); + context.setAttribute(CONTEXT, s); + for (int i = 0; i < names.length; i++) { String resourceString = params.getParameter(names[i]); XScriptObject resource = new XScriptObjectFromURL(this, resourceString); - globalScope.put(names[i], resource); + s.put(names[i], resource); } } private IllegalArgumentException - createAccessException(String msg, String name, int scope, String context) { + createAccessException(String msg, String name, int scope) + { StringBuffer message = new StringBuffer("Cannot ").append(msg) .append(" variable named '").append(name) .append("' in "); @@ -132,147 +140,199 @@ message.append("session scope"); else if (scope == XScriptManager.PAGE_SCOPE) message.append("page scope"); + else if (scope == XScriptManager.REQUEST_SCOPE) + message.append("request scope"); + else if (scope == XScriptManager.ALL_SCOPES) + message.append("any scope"); else message.append("unknown scope (").append(scope).append(")"); - message.append(" with context '").append(context).append("'"); return new IllegalArgumentException(message.toString()); } - public XScriptObject get(String name, int scope, String context) - throws IllegalArgumentException { + public XScriptObject get(XScriptVariableScope pageScope, + Map objectModel, + String name, + int scope) + throws IllegalArgumentException + { + XScriptObject o; + XScriptVariableScope s = null; + if (scope == XScriptManager.GLOBAL_SCOPE) { - return globalScope.get(name); + s = (XScriptVariableScope) ObjectModelHelper.getContext(objectModel).getAttribute(CONTEXT); } else if (scope == XScriptManager.SESSION_SCOPE) { - XScriptVariableScope s = (XScriptVariableScope) sessionScope.get(context); - if (s != null) - return s.get(name); + Request request = ObjectModelHelper.getRequest(objectModel); + s = (XScriptVariableScope) request.getSession().getAttribute(CONTEXT); + } else if (scope == XScriptManager.REQUEST_SCOPE) { + Request request = ObjectModelHelper.getRequest(objectModel); + s = (XScriptVariableScope) request.getAttribute(CONTEXT); } else if (scope == XScriptManager.PAGE_SCOPE) { - XScriptVariableScope s = (XScriptVariableScope) pageScope.get(context); - if (s != null) - return s.get(name); - } - - throw createAccessException("find", name, scope, context); - } + s = pageScope; + } else if (scope == XScriptManager.ALL_SCOPES) { + Request request = ObjectModelHelper.getRequest(objectModel); - public XScriptObject getFirst(String name, - String sessionContext, - String pageContext) - throws IllegalArgumentException { - XScriptVariableScope scope; - - // Lookup in the session scope first. - scope = (XScriptVariableScope) sessionScope.get(sessionContext); - if (scope != null) { - synchronized (scope) { - if (scope.defines(name)) { - return scope.get(name); + // Lookup in the request scope first. + s = (XScriptVariableScope) request.getAttribute(CONTEXT); + if (s != null) { + o = s.get(name); + if (o != null) { + return o; } } - } - - // No luck finding `name' in session scope, try in page scope. - scope = (XScriptVariableScope) pageScope.get(pageContext); - if (scope != null) { - synchronized (scope) { - if (scope.defines(name)) { - return scope.get(name); + // No luck finding `name' in request scope, try in session scope. + s = (XScriptVariableScope) request.getSession().getAttribute(CONTEXT); + if (s != null) { + o = s.get(name); + if (o != null) { + return o; + } + } + // No luck finding `name' in session scope, try in page scope. + o = pageScope.get(name); + if (o != null) { + return o; + } + // No luck finding `name' in the page scope, try the global scope. + s = (XScriptVariableScope) ObjectModelHelper.getContext(objectModel).getAttribute(CONTEXT); + if (s != null) { + o = s.get(name); + if (o != null) { + return o; } } + // Not found, throw exception + s = null; } - // No luck finding `name' in the page scope, try the global scope. - synchronized (globalScope) { - if (globalScope.defines(name)) { - return globalScope.get(name); + if (s != null) { + o = s.get(name); + if (o != null) { + return o; } } - // No variable `name' found, throw an exception. - throw new IllegalArgumentException("getFirst: no variable '" + name - + "' accessible from this scope!"); + throw createAccessException("find", name, scope); } - public void put(String name, XScriptObject value, int scope, String context) { + public XScriptObject getFirst(XScriptVariableScope pageScope, + Map objectModel, + String name) + throws IllegalArgumentException + { + return get(pageScope, objectModel, name, ALL_SCOPES); + } + + public void put(XScriptVariableScope pageScope, + Map objectModel, + String name, + XScriptObject value, + int scope) + { + XScriptVariableScope s; + if (scope == XScriptManager.GLOBAL_SCOPE) { - globalScope.put(name, value); + Context context = ObjectModelHelper.getContext(objectModel); + synchronized (context) { + s = (XScriptVariableScope) context.getAttribute(CONTEXT); + if (s == null) { + context.setAttribute(CONTEXT, s = new XScriptVariableScope()); + } + } } else if (scope == XScriptManager.SESSION_SCOPE) { - XScriptVariableScope s = (XScriptVariableScope) sessionScope.get(context); - if (s == null) { - s = new XScriptVariableScope(); - sessionScope.put(context, s); + Session session = ObjectModelHelper.getRequest(objectModel).getSession(); + synchronized (session) { + s = (XScriptVariableScope) session.getAttribute(CONTEXT); + if (s == null) { + session.setAttribute(CONTEXT, s = new XScriptVariableScope()); + } } - s.put(name, value); - } else if (scope == XScriptManager.PAGE_SCOPE) { - XScriptVariableScope s = (XScriptVariableScope) pageScope.get(context); - if (s == null) { - s = new XScriptVariableScope(); - pageScope.put(context, s); + } else if (scope == XScriptManager.REQUEST_SCOPE) { + Request request = ObjectModelHelper.getRequest(objectModel); + synchronized (request) { + s = (XScriptVariableScope) request.getAttribute(CONTEXT); + if (s == null) { + request.setAttribute(CONTEXT, s = new XScriptVariableScope()); + } } - s.put(name, value); + } else if (scope == XScriptManager.PAGE_SCOPE) { + s = pageScope; } else { - throw createAccessException("create", name, scope, context); + throw createAccessException("create", name, scope); } + + s.put(name, value); } - public void remove(String name, int scope, String context) - throws IllegalArgumentException { + public XScriptObject remove(XScriptVariableScope pageScope, + Map objectModel, + String name, + int scope) + throws IllegalArgumentException + { + XScriptObject o; + XScriptVariableScope s = null; + if (scope == XScriptManager.GLOBAL_SCOPE) { - globalScope.remove(name); + s = (XScriptVariableScope) ObjectModelHelper.getContext(objectModel).getAttribute(CONTEXT); } else if (scope == XScriptManager.SESSION_SCOPE) { - XScriptVariableScope s = (XScriptVariableScope) sessionScope.get(context); - if (s != null) { - s.remove(name); - } + Request request = ObjectModelHelper.getRequest(objectModel); + s = (XScriptVariableScope) request.getSession().getAttribute(CONTEXT); + } else if (scope == XScriptManager.REQUEST_SCOPE) { + Request request = ObjectModelHelper.getRequest(objectModel); + s = (XScriptVariableScope) request.getAttribute(CONTEXT); } else if (scope == XScriptManager.PAGE_SCOPE) { - XScriptVariableScope s = (XScriptVariableScope) pageScope.get(context); + s = pageScope; + } else if (scope == XScriptManager.ALL_SCOPES) { + Request request = ObjectModelHelper.getRequest(objectModel); + + // Lookup in the request scope first. + s = (XScriptVariableScope) request.getAttribute(CONTEXT); if (s != null) { - s.remove(name); + o = s.remove(name); + if (o != null) { + return o; + } } - } else { - throw createAccessException("remove", name, scope, context); - } - } - - public void removeFirst(String name, - String sessionContext, - String pageContext) - throws IllegalArgumentException { - XScriptVariableScope scope; - - // Lookup in the session scope first. - scope = (XScriptVariableScope) sessionScope.get(sessionContext); - if (scope != null) { - synchronized (scope) { - if (scope.defines(name)) { - scope.remove(name); - return; + // No luck finding `name' in request scope, try in session scope. + s = (XScriptVariableScope) request.getSession().getAttribute(CONTEXT); + if (s != null) { + o = s.remove(name); + if (o != null) { + return o; } } - } - - // No luck finding `name' in session scope, try in page scope. - scope = (XScriptVariableScope) pageScope.get(pageContext); - if (scope != null) { - synchronized (scope) { - if (scope.defines(name)) { - scope.remove(name); - return; + // No luck finding `name' in session scope, try in page scope. + o = pageScope.remove(name); + if (o != null) { + return o; + } + // No luck finding `name' in the page scope, try the global scope. + s = (XScriptVariableScope) ObjectModelHelper.getContext(objectModel).getAttribute(CONTEXT); + if (s != null) { + o = s.remove(name); + if (o != null) { + return o; } } + // Not found, throw exception + s = null; } - // No luck finding `name' in the page scope, try the global scope. - synchronized (globalScope) { - if (globalScope.defines(name)) { - globalScope.remove(name); - return; + if (s != null) { + o = s.remove(name); + if (o != null) { + return o; } } - // No variable `name' found, throw an exception. - throw new IllegalArgumentException("removeFirst: no variable '" + name - + "' accessible from this scope!"); + throw createAccessException("remove", name, scope); + } + + public XScriptObject removeFirst(XScriptVariableScope pageScope, Map objectModel, + String name) + throws IllegalArgumentException + { + return remove(pageScope, objectModel, name, ALL_SCOPES); } } 1.5.2.3 +5 -4 xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptObjectFromURL.java Index: XScriptObjectFromURL.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptObjectFromURL.java,v retrieving revision 1.5.2.2 retrieving revision 1.5.2.3 diff -u -r1.5.2.2 -r1.5.2.3 --- XScriptObjectFromURL.java 26 Jul 2002 04:40:49 -0000 1.5.2.2 +++ XScriptObjectFromURL.java 30 Jul 2002 01:17:49 -0000 1.5.2.3 @@ -91,17 +91,18 @@ public InputStream getInputStream() throws ProcessingException, IOException { + URLFactory urlFactory = null; try { - URLFactory urlFactory = (URLFactory) componentManager.lookup(URLFactory.ROLE); + urlFactory = (URLFactory) componentManager.lookup(URLFactory.ROLE); URL url = urlFactory.getURL(systemId); URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream(); contentLength = conn.getContentLength(); - componentManager.release(urlFactory); - return is; } catch (ComponentException ex) { throw new ProcessingException(ex); + } finally { + componentManager.release(urlFactory); } } 1.4.2.4 +1 -5 xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptObjectInlineXML.java Index: XScriptObjectInlineXML.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptObjectInlineXML.java,v retrieving revision 1.4.2.3 retrieving revision 1.4.2.4 diff -u -r1.4.2.3 -r1.4.2.4 --- XScriptObjectInlineXML.java 26 Jul 2002 04:40:49 -0000 1.4.2.3 +++ XScriptObjectInlineXML.java 30 Jul 2002 01:17:49 -0000 1.4.2.4 @@ -110,10 +110,6 @@ return streamHandler; } - public void setNextContentHandler(ContentHandler handler) { - streamHandler.setNextContentHandler(handler); - } - public String toString() { return stringBuffer.toString(); } 1.4.2.2 +4 -8 xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptVariableScope.java Index: XScriptVariableScope.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/xscript/XScriptVariableScope.java,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -u -r1.4.2.1 -r1.4.2.2 --- XScriptVariableScope.java 26 Jul 2002 04:40:49 -0000 1.4.2.1 +++ XScriptVariableScope.java 30 Jul 2002 01:17:49 -0000 1.4.2.2 @@ -86,11 +86,7 @@ * @param name a <code>String</code> value * @return a <code>{@link XScriptObject}</code> value */ - public synchronized XScriptObject get(String name) - throws IllegalArgumentException { - if (!variables.containsKey(name)) - throw new IllegalArgumentException("Cannot find variable '" - + name + "'!"); + public synchronized XScriptObject get(String name) { return (XScriptObject) variables.get(name); } @@ -100,8 +96,8 @@ * * @param name a <code>String</code> value */ - public synchronized void remove(String name) { - variables.remove(name); + public synchronized XScriptObject remove(String name) { + return (XScriptObject) variables.remove(name); } public synchronized boolean defines(String name) {
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]