coliver 2003/04/12 17:24:46
Modified: src/scratchpad/src/org/apache/cocoon/transformation
JXPathTransformer.java JexlTransformer.java
Log:
added <set> and <remove> tags to JXPathTransformer and JexlTransformer: these can
only be used to create local aliases of existing objects, but cannot be used to modify
existing objects
Revision Changes Path
1.9 +67 -10
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.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- JXPathTransformer.java 12 Apr 2003 23:35:29 -0000 1.8
+++ JXPathTransformer.java 13 Apr 2003 00:24:45 -0000 1.9
@@ -57,6 +57,7 @@
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
+import java.util.HashMap;
import java.util.Stack;
import org.apache.avalon.framework.activity.Initializable;
@@ -78,6 +79,7 @@
import org.apache.excalibur.source.SourceException;
import org.w3c.dom.DocumentFragment;
import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.AttributesImpl;
@@ -111,11 +113,16 @@
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_VALUEOF_DEFAULT = "default";
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_SET = "set";
+ public static final String JXPATH_REMOVE = "remove";
+ public static final String JXPATH_SET_REMOVE_VARNAME = "var";
+ public static final String JXPATH_SET_VALUE = "value";
// web contination
private WebContinuation kont;
@@ -156,6 +163,11 @@
// Run as a generator for debugging: to get line numbers in error messages
private Source inputSource;
+ private Locator locator = null;
+
+ public void setDocumentLocator(Locator loc) {
+ this.locator = loc;
+ }
public void generate()
throws IOException, SAXException, ProcessingException {
@@ -285,8 +297,11 @@
if (c == '}') {
String str = expr.toString();
expr.setLength(0);
- str = String.valueOf(getValue(str));
- out.write(str);
+ Object val = getValue(str);
+ if (val == null) {
+ val = "";
+ }
+ out.write(String.valueOf(val));
inExpr = false;
} else if (c == '\\') {
ch = in.read();
@@ -338,7 +353,8 @@
try {
substitute(reader, writer);
} catch (Exception exc) {
- throw new SAXException(exc.getMessage(), exc);
+ throw new SAXParseException(exc.getMessage(),
+ locator, exc);
}
impl.setValue(i, writer.toString());
}
@@ -377,6 +393,14 @@
if (ignoreEventsCount == 0) {
doContinuation(attr);
}
+ } else if (JXPATH_SET.equals(name)) {
+ if (ignoreEventsCount == 0) {
+ doSet(attr);
+ }
+ } else if (JXPATH_REMOVE.equals(name)) {
+ if (ignoreEventsCount == 0) {
+ doRemove(attr);
+ }
} else if (JXPATH_IF.equals(name)) {
doIf(attr);
} else if (JXPATH_FOR_EACH.equals(name)) {
@@ -387,16 +411,17 @@
return;
} else if (JXPATH_WHEN.equals(name)) {
if (!inChoose) {
- throw new ProcessingException("<when> must be contained in
<choose>");
+ throw new SAXParseException("<when> must be contained in <choose>",
locator, null);
}
doWhen(attr);
} else if (JXPATH_OTHERWISE.equals(name)) {
if (!inChoose) {
- throw new ProcessingException("<otherwise> must be contained in
<choose>");
+ throw new SAXParseException("<otherwise> must be contained in
<choose>", locator, null);
}
doOtherwise(attr);
} else {
- throw new ProcessingException("unknown jxpath element: " + name);
+ throw new SAXParseException("unknown tag: " + name,
+ locator, null);
}
inChoose = false;
}
@@ -446,6 +471,8 @@
static class MyVariables implements Variables {
+ Map myVariables = new HashMap();
+
static final String[] VARIABLES = new String[] {
"continuation",
"flowContext",
@@ -478,7 +505,7 @@
return true;
}
}
- return false;
+ return myVariables.containsKey(varName);
}
public Object getVariable(String varName) {
@@ -497,13 +524,15 @@
} else if (varName.equals("parameters")) {
return parameters;
}
- return null;
+ return myVariables.get(varName);
}
public void declareVariable(String varName, Object value) {
+ myVariables.put(varName, value);
}
public void undeclareVariable(String varName) {
+ myVariables.remove(varName);
}
}
@@ -549,15 +578,20 @@
throws SAXException, ProcessingException {
final String select = a.getValue(JXPATH_VALUEOF_SELECT);
+ final String def = a.getValue(JXPATH_VALUEOF_DEFAULT);
if (null != select) {
Object value = getValue(getExpr(select));
if (value == null) {
- value = "";
+ value = def;
+ if (value == null) {
+ value = "";
+ }
}
sendTextEvent(value.toString());
} else {
- throw new ProcessingException("jxpath: " + JXPATH_VALUEOF + " specified
without a "+JXPATH_VALUEOF_SELECT+" attribute");
+ throw new SAXParseException("value-of: \"select\" is required",
+ locator, null);
}
}
@@ -577,6 +611,29 @@
: kont.getContinuation(0).getId();
sendTextEvent(id);
+ }
+
+
+ private void doSet(final Attributes a)
+ throws SAXException {
+
+ final String varName = a.getValue(JXPATH_SET_REMOVE_VARNAME);
+ if (varName == null) {
+ throw new SAXParseException("set: \"var\" is required",
+ locator, null);
+ }
+ final String value = a.getValue(JXPATH_SET_VALUE);
+ variables.declareVariable(varName, getValue(getExpr(value)));
+ }
+
+ private void doRemove(final Attributes a)
+ throws SAXException {
+ final String varName = a.getValue(JXPATH_SET_REMOVE_VARNAME);
+ if (varName == null) {
+ throw new SAXParseException("set: \"var\" is required",
+ locator, null);
+ }
+ variables.undeclareVariable(varName);
}
/**
1.6 +48 -6
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.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- JexlTransformer.java 12 Apr 2003 23:35:29 -0000 1.5
+++ JexlTransformer.java 13 Apr 2003 00:24:45 -0000 1.6
@@ -431,6 +431,10 @@
public static final String JEXL_FOREACH_VAR = "var";
public static final String JEXL_FOREACH_VAR_STATUS = "varStatus";
public static final String JEXL_FOREACH_SELECT = "select";
+ public static final String JEXL_SET = "set";
+ public static final String JEXL_REMOVE = "remove";
+ public static final String JEXL_SET_REMOVE_VAR = "var";
+ public static final String JEXL_SET_VALUE = "value";
static {
// Hack: there's no _nice_ way to add my introspector to Jexl right now
@@ -575,6 +579,7 @@
private Object eval(String inStr, boolean iterate) throws SAXException {
try {
+ if (inStr == null) return null;
StringReader in = new StringReader(inStr.trim());
int ch;
StringBuffer expr = new StringBuffer();
@@ -641,8 +646,11 @@
if (c == '}') {
String str = expr.toString();
expr.setLength(0);
- str = String.valueOf(getValue(str, xpath, false));
- out.write(str);
+ Object val = getValue(str, xpath, false);
+ if (val == null) {
+ val = "";
+ }
+ out.write(String.valueOf(val));
inExpr = false;
xpath = false;
} else if (c == '\\') {
@@ -738,6 +746,10 @@
}
} else if (JEXL_IF.equals(name)) {
doIf(attr);
+ } else if (JEXL_SET.equals(name)) {
+ doSet(attr);
+ } else if (JEXL_REMOVE.equals(name)) {
+ doRemove(attr);
} else if (JEXL_FOREACH.equals(name)) {
doForEach(attr);
} else if (JEXL_CHOOSE.equals(name)) {
@@ -806,6 +818,8 @@
static class MyVariables implements Variables {
+ Map myVariables = new HashMap();
+
static final String[] VARIABLES = new String[] {
"continuation",
"flowContext",
@@ -838,7 +852,7 @@
return true;
}
}
- return false;
+ return myVariables.containsKey(varName);
}
public Object getVariable(String varName) {
@@ -857,13 +871,15 @@
} else if (varName.equals("parameters")) {
return parameters;
}
- return null;
+ return myVariables.get(varName);
}
public void declareVariable(String varName, Object value) {
+ myVariables.put(varName, value);
}
public void undeclareVariable(String varName) {
+ myVariables.remove(varName);
}
}
@@ -1026,7 +1042,8 @@
// get the test variable
String expr = a.getValue(JEXL_IF_TEST);
if (expr == null) {
- throw new SAXParseException("if: \"test\" is required", locator, null);
+ throw new SAXParseException("if: \"test\" is required",
+ locator, null);
}
final Object value = eval(expr);
final boolean isTrueBoolean =
@@ -1046,6 +1063,31 @@
}
}
+ private void doSet(final Attributes a)
+ throws SAXException {
+
+ final String varName = a.getValue(JEXL_SET_REMOVE_VAR);
+ if (varName == null) {
+ throw new SAXParseException("set: \"var\" is required",
+ locator, null);
+ }
+ final String value = a.getValue(JEXL_SET_VALUE);
+ Object result = eval(value);
+ variables.declareVariable(varName, result);
+ getJexlContext().getVars().put(varName, result);
+ }
+
+ private void doRemove(final Attributes a)
+ throws SAXException {
+
+ final String varName = a.getValue(JEXL_SET_REMOVE_VAR);
+ if (varName == null) {
+ throw new SAXParseException("remove: \"var\" is required",
+ locator, null);
+ }
+ variables.undeclareVariable(varName);
+ getJexlContext().getVars().remove(varName);
+ }
/**
* Helper method to process a <jexl-transformer:if test="..."> element.