crafterm 2002/11/28 10:23:27
Modified: src/java/org/apache/cocoon/transformation
JPathTransformer.java
Log:
* Implemented <jpath:if/> element, many thanks to Wolfram Eisert for help
with the startRecording, endRecording feature of AbstractSAXTranformer.
* Various minor cleanups.
Revision Changes Path
1.3 +109 -22
xml-cocoon2/src/java/org/apache/cocoon/transformation/JPathTransformer.java
Index: JPathTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/JPathTransformer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- JPathTransformer.java 6 Nov 2002 17:52:51 -0000 1.2
+++ JPathTransformer.java 28 Nov 2002 18:23:27 -0000 1.3
@@ -81,6 +81,7 @@
* <ul>
* <li><jpath:value-of select=".."/> element.
* <li><jpath:continuation/> element.
+ * <li><jpath:if test="..">..</jpath:if> element.
* <li>jpath:action attribute on all elements that implicitly replaces any
* occurance of the string 'id' with the continuation id (useful when
* writing form action attributes). eg:
@@ -112,6 +113,12 @@
/** jpath:continuation select attribute constant */
public static final String JPATH_CONTINUATION_SELECT = "select";
+ /** jpath:if element constant */
+ public static final String JPATH_IF = "if";
+
+ /** jpath generic test attribute */
+ public static final String JPATH_TEST = "test";
+
// web contination
private WebContinuation m_kont;
@@ -199,6 +206,8 @@
doValueOf(attr);
} else if (JPATH_CONTINUATION.equals(name)) {
doContinuation(attr);
+ } else if (JPATH_IF.equals(name)) {
+ doIf(attr);
} else {
super.startTransformingElement(uri, name, raw, attr);
}
@@ -222,6 +231,8 @@
if (JPATH_VALUEOF.equals(name) ||
JPATH_CONTINUATION.equals(name)) {
return; // do nothing
+ } else if (JPATH_IF.equals(name)) {
+ finishIf();
} else {
super.endTransformingElement(uri, name, raw);
}
@@ -257,6 +268,35 @@
}
/**
+ * Helper method for obtaining the value of a particular variable.
+ *
+ * @param variable variable name
+ * @return variable value as an <code>Object</code>
+ */
+ private Object getValue(final String variable) {
+
+ Object value;
+
+ if (m_cache.containsKey(variable)) {
+ value = m_cache.get(variable);
+ } else {
+ value = m_jxpathContext.compile(variable).getValue(m_jxpathContext);
+
+ if (value == null) {
+ if (getLogger().isWarnEnabled()) {
+ final String msg =
+ "Value for jpath variable '" + variable + "' does not
exist";
+ getLogger().warn(msg);
+ }
+ }
+
+ m_cache.put(variable, value);
+ }
+
+ return value;
+ }
+
+ /**
* Helper method to process a <jpath:value-of select="."> tag
*
* @param a an {@link Attributes} instance
@@ -266,28 +306,11 @@
private void doValueOf(final Attributes a)
throws SAXException, ProcessingException {
- String select = a.getValue(JPATH_VALUEOF_SELECT);
- Object value;
+ final String select = a.getValue(JPATH_VALUEOF_SELECT);
if (null != select) {
- if (m_cache.containsKey(select)) {
- value = m_cache.get(select);
- } else {
- value = m_jxpathContext.compile(select).getValue(m_jxpathContext);
- m_cache.put(select, value);
- }
-
- if (value != null) {
- sendTextEvent((String)value);
- }
- else {
- throw new ProcessingException(
- "<jpath:" + JPATH_VALUEOF + " select=\"" + select +
- "\"/> yields a null value"
- );
- }
- }
- else {
+ sendTextEvent((String)getValue(select));
+ } else {
throw new ProcessingException(
"jpath:" + JPATH_VALUEOF + " specified without a select attribute"
);
@@ -295,7 +318,7 @@
}
/**
- * Helper method to process a <jpath:continuation select=""/> element
+ * Helper method to process a <jpath:continuation select=""/> element.
*
* @param a an <code>Attributes</code> value
* @exception SAXException if an error occurs
@@ -310,6 +333,70 @@
: m_kont.getContinuation(0).getId();
sendTextEvent(id);
+ }
+
+ /**
+ * Helper method to process a <jpath:if test="..."> element.
+ *
+ * @param a an <code>Attributes</code> value
+ * @exception SAXException if an error occurs
+ */
+ private void doIf(final Attributes a)
+ throws SAXException {
+
+ // handle nested jpath:if statements, if ignoreEventsCount is > 0, then
+ // we are processing a nested jpath:if statement for which the parent
+ // jpath:if test resulted in a false (ie. disallow subelements) result.
+
+ if (ignoreEventsCount > 0) {
+ ++ignoreEventsCount;
+ return;
+ }
+
+ // get the test variable
+ final Object value = getValue(a.getValue(JPATH_TEST));
+
+ final boolean isTrueBoolean =
+ value instanceof Boolean && ((Boolean)value).booleanValue() == true;
+ final boolean isNonNullNonBoolean =
+ value != null && !(value instanceof Boolean);
+
+ if (isTrueBoolean || isNonNullNonBoolean) {
+ // do nothing, allow all subelements
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("jpath:if results in allowing subelements");
+ }
+ } else {
+ // disallow all subelements
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("jpath:if results in disallowing subelements");
+ }
+ startRecording();
+ ++ignoreEventsCount;
+ }
+ }
+
+ /**
+ * Helper method to process a </jpath:if> element.
+ *
+ * @exception SAXException if an error occurs
+ */
+ private void finishIf()
+ throws SAXException {
+
+ // end recording (and dump resulting document fragment) if we've reached
+ // the closing jpath:if tag for which the recording was started.
+ if (ignoreEventsCount > 0) {
+ --ignoreEventsCount;
+
+ if (ignoreEventsCount == 0) {
+ endRecording();
+ }
+ }
+
+ if (getLogger().isDebugEnabled()) {
+ getLogger().debug("jpath:if closed");
+ }
}
/**
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]