coliver 2003/04/12 16:35:30
Modified: src/scratchpad/src/org/apache/cocoon/transformation JXPathTransformer.java JexlTransformer.java Log: added object model objects: request, response, session, context to JXPath and Jexl contexts: so these are now consistent with FlowVelocityGenerator Revision Changes Path 1.8 +88 -26 cocoon-2.1/src/scratchpad/src/org/apache/cocoon/transformation/JXPathTransformer.java Index: JXPathTransformer.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/scratchpad/src/org/apache/cocoon/transformation/JXPathTransformer.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- JXPathTransformer.java 6 Apr 2003 17:14:57 -0000 1.7 +++ JXPathTransformer.java 12 Apr 2003 23:35:29 -0000 1.8 @@ -65,7 +65,10 @@ import org.apache.cocoon.components.flow.WebContinuation; import org.apache.cocoon.components.source.SourceUtil; import org.apache.cocoon.environment.Environment; +import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.SourceResolver; +import org.apache.cocoon.environment.Request; +import org.apache.cocoon.environment.Response; import org.apache.cocoon.generation.Generator; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.JXPathContextFactory; @@ -86,7 +89,8 @@ * </p> * <p> * Provides a tag library and embedded XPath expression substitution - * to access data sent by the Cocoon flow layer + * to access data sent by Cocoon flowscripts + * * </p> * * @@ -101,23 +105,26 @@ public static final String JXPATH_NAMESPACE_URI = "http://cocoon.apache.org/transformation/jxpath/1.0"; - public static final String JXPATH_FOR_EACH = "for-each"; + public static final String JXPATH_FOR_EACH = "for-each"; public static final String JXPATH_CHOOSE = "choose"; - public static final String JXPATH_WHEN = "when"; - public static final String JXPATH_OTHERWISE = "otherwise"; + public static final String JXPATH_WHEN = "when"; + public static final String JXPATH_OTHERWISE = "otherwise"; public static final String JXPATH_VALUEOF = "value-of"; public static final String JXPATH_VALUEOF_SELECT = "select"; public static final String JXPATH_CONTINUATION = "continuation"; public static final String JXPATH_CONTINUATION_SELECT = "select"; public static final String JXPATH_IF = "if"; - public static final String JXPATH_IF_TEST = "test"; - public static final String JXPATH_WHEN_TEST = "test"; + public static final String JXPATH_IF_TEST = "test"; + public static final String JXPATH_WHEN_TEST = "test"; // web contination private WebContinuation kont; + // XPath variables + private MyVariables variables; + // TBD: Don't really need stacks for these in current implementation of for-each - private Stack foreachStack = new Stack(); + private Stack foreachStack; // Stack of JXPathContext's private Stack contextStack; @@ -217,6 +224,13 @@ chooseStack = new Stack(); ifStack = new Stack(); inChoose = false; + variables = new MyVariables(bean, + kont, + ObjectModelHelper.getRequest(objectModel), + ObjectModelHelper.getResponse(objectModel), + ObjectModelHelper.getContext(objectModel), + parameters); + pushContext(bean); } @@ -429,6 +443,71 @@ return (JXPathContext)contextStack.peek(); } + + static class MyVariables implements Variables { + + static final String[] VARIABLES = new String[] { + "continuation", + "flowContext", + "request", + "response", + "context", + "session", + "parameters" + }; + + Object bean, kont, request, response, + session, context, parameters; + + MyVariables(Object bean, WebContinuation kont, + Request request, Response response, + org.apache.cocoon.environment.Context context, + Parameters parameters) { + this.bean = bean; + this.kont = kont; + this.request = request; + this.session = request.getSession(false); + this.response = response; + this.context = context; + this.parameters = parameters; + } + + public boolean isDeclaredVariable(String varName) { + for (int i = 0; i < VARIABLES.length; i++) { + if (varName.equals(VARIABLES[i])) { + return true; + } + } + return false; + } + + public Object getVariable(String varName) { + if (varName.equals("continuation")) { + return kont; + } else if (varName.equals("flowContext")) { + return bean; + } else if (varName.equals("request")) { + return request; + } else if (varName.equals("response")) { + return response; + } else if (varName.equals("session")) { + return session; + } else if (varName.equals("context")) { + return context; + } else if (varName.equals("parameters")) { + return parameters; + } + return null; + } + + public void declareVariable(String varName, Object value) { + } + + public void undeclareVariable(String varName) { + } + } + + private void pushContext(Object contextObject) { JXPathContext ctx = jxpathContextFactory.newContext(null, contextObject); @@ -441,25 +520,7 @@ // // <form action="kont/{getContinuation($continuation, 1)/id}" ... // - ctx.setVariables(new Variables() { - - public boolean isDeclaredVariable(String varName) { - return varName.equals("continuation"); - } - - public Object getVariable(String varName) { - if (varName.equals("continuation")) { - return kont; - } - return null; - } - - public void declareVariable(String varName, Object value) { - } - - public void undeclareVariable(String varName) { - } - }); + ctx.setVariables(variables); contextStack.push(ctx); } @@ -679,5 +740,6 @@ foreachStack = null; chooseStack = null; ifStack = null; + variables = null; } } 1.5 +114 -39 cocoon-2.1/src/scratchpad/src/org/apache/cocoon/transformation/JexlTransformer.java Index: JexlTransformer.java =================================================================== RCS file: /home/cvs/cocoon-2.1/src/scratchpad/src/org/apache/cocoon/transformation/JexlTransformer.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- JexlTransformer.java 6 Apr 2003 17:14:57 -0000 1.4 +++ JexlTransformer.java 12 Apr 2003 23:35:29 -0000 1.5 @@ -71,6 +71,10 @@ import org.apache.cocoon.components.source.SourceUtil; import org.apache.cocoon.environment.Environment; import org.apache.cocoon.environment.SourceResolver; +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.apache.cocoon.generation.Generator; import org.apache.commons.jexl.Expression; import org.apache.commons.jexl.ExpressionFactory; @@ -105,6 +109,7 @@ import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.AttributesImpl; + /** * Jexl Transformer. * @@ -443,15 +448,18 @@ // web contination private WebContinuation kont; - JexlContext jexlContext; - Stack jxpathContextStack; + private JexlContext jexlContext; + private Stack jxpathContextStack; + + private Iterator foreachIter; + private boolean foreachXPath; + private String foreachVar; + private int foreachBegin; + private int foreachEnd; + private int foreachStep; - Iterator foreachIter; - boolean foreachXPath; - String foreachVar; - int foreachBegin; - int foreachEnd; - int foreachStep; + // XPath variables + private MyVariables variables; // // Contains a stack of Boolean values: @@ -475,12 +483,12 @@ // Each time we enter an <if> we push the test condition on this stack and // pop it when we reach </if>, where it is checked to see if ignoreEventsCount // should be updated - Stack ifStack; + private Stack ifStack; // Run as a generator for debugging: to get line numbers in error messages private Source inputSource; - Locator locator = null; + private Locator locator = null; public void setDocumentLocator(Locator loc) { this.locator = loc; @@ -542,20 +550,23 @@ throw SourceUtil.handle("Error during resolving of '" + src + "'.", se); } } + // Fix me: when we decide the proper way to pass bean-dict and kont Object bean = ((Environment)resolver).getAttribute("bean-dict"); kont = (WebContinuation)((Environment)resolver).getAttribute("kont"); chooseStack = new Stack(); ifStack = new Stack(); jxpathContextStack = new Stack(); jexlContext = JexlHelper.createContext(); - setContexts(bean); - getJexlContext().getVars().put("this", bean); - getJexlContext().getVars().put("continuation", kont); + setContexts(bean, kont, + ObjectModelHelper.getRequest(objectModel), + ObjectModelHelper.getResponse(objectModel), + ObjectModelHelper.getContext(objectModel), + parameters); } /** - * Evaluate a Jexl expr contained in ${} but don't do substitution: - * just return its value + * Evaluate a single Jexl expr (contained in ${}) or XPath expression + * (contained in {}) but don't do substitution: just return its value */ private Object eval(String inStr) throws SAXException { @@ -633,6 +644,7 @@ str = String.valueOf(getValue(str, xpath, false)); out.write(str); inExpr = false; + xpath = false; } else if (c == '\\') { ch = in.read(); if (ch == -1) { @@ -675,8 +687,7 @@ } } } catch (IOException e) { - throw new CascadingRuntimeException(e.getMessage(), - e); + throw new CascadingRuntimeException(e.getMessage(), e); } } @@ -699,6 +710,7 @@ } super.startElement(uri, name, raw, attr); } + /** * Entry method for all elements in our namespace * @@ -791,29 +803,74 @@ private JXPathContext getJXPathContext() { return (JXPathContext)jxpathContextStack.peek(); } + + static class MyVariables implements Variables { + + static final String[] VARIABLES = new String[] { + "continuation", + "flowContext", + "request", + "response", + "context", + "session", + "parameters" + }; + + Object bean, kont, request, response, + session, context, parameters; + + MyVariables(Object bean, WebContinuation kont, + Request request, Response response, + org.apache.cocoon.environment.Context context, + Parameters parameters) { + this.bean = bean; + this.kont = kont; + this.request = request; + this.session = request.getSession(false); + this.response = response; + this.context = context; + this.parameters = parameters; + } + + public boolean isDeclaredVariable(String varName) { + for (int i = 0; i < VARIABLES.length; i++) { + if (varName.equals(VARIABLES[i])) { + return true; + } + } + return false; + } + + public Object getVariable(String varName) { + if (varName.equals("continuation")) { + return kont; + } else if (varName.equals("flowContext")) { + return bean; + } else if (varName.equals("request")) { + return request; + } else if (varName.equals("response")) { + return response; + } else if (varName.equals("session")) { + return session; + } else if (varName.equals("context")) { + return context; + } else if (varName.equals("parameters")) { + return parameters; + } + return null; + } + + public void declareVariable(String varName, Object value) { + } + + public void undeclareVariable(String varName) { + } + } private void pushJXPathContext(Object contextObject) { JXPathContext jxpathContext = jxpathContextFactory.newContext(null, contextObject); - jxpathContext.setVariables(new Variables() { - - public boolean isDeclaredVariable(String varName) { - return varName.equals("continuation"); - } - - public Object getVariable(String varName) { - if (varName.equals("continuation")) { - return kont; - } - return null; - } - - public void declareVariable(String varName, Object value) { - } - - public void undeclareVariable(String varName) { - } - }); + jxpathContext.setVariables(variables); jxpathContextStack.push(jxpathContext); } @@ -821,8 +878,20 @@ jxpathContextStack.pop(); } - - private void setContexts(Object contextObject) { + private void setContexts(Object contextObject, + WebContinuation kont, + Request request, + Response response, + org.apache.cocoon.environment.Context app, + Parameters parameters) { + if (variables == null) { + variables = new MyVariables(contextObject, + kont, + request, + response, + app, + parameters); + } Map map; if (contextObject instanceof Map) { map = (Map)contextObject; @@ -864,6 +933,12 @@ } pushJXPathContext(contextObject); jexlContext.setVars(map); + map = jexlContext.getVars(); + map.put("flowContext", contextObject); + map.put("request", request); + map.put("response", response); + map.put("context", app); + map.put("session", request.getSession(false)); } /**