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]