Author: lgawron Date: Tue Apr 19 07:11:15 2005 New Revision: 161892 URL: http://svn.apache.org/viewcvs?view=rev&rev=161892 Log: initial implementation of jx:attribute. No namespace support Probably buggy error reporting. Check test/org/apache/cocoon/template/jxtg/jxAttribute.xml for examples.
Added: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/instruction/StartAttribute.java cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumer.java cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumerImpl.java cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute-output.xml cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute.xml Modified: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/JXTemplateGenerator.java cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/environment/JXCacheKey.java cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/script/Parser.java cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/JXTemplateGeneratorTestCase.java Modified: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/JXTemplateGenerator.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/JXTemplateGenerator.java?view=diff&r1=161891&r2=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/JXTemplateGenerator.java (original) +++ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/JXTemplateGenerator.java Tue Apr 19 07:11:15 2005 @@ -37,6 +37,7 @@ import org.apache.cocoon.template.jxtg.script.ScriptManager; import org.apache.cocoon.template.jxtg.script.event.Event; import org.apache.cocoon.template.jxtg.script.event.StartDocument; +import org.apache.cocoon.xml.AttributeAwareXMLConsumerImpl; import org.apache.cocoon.xml.RedundantNamespacesFilter; import org.apache.cocoon.xml.XMLConsumer; import org.apache.excalibur.source.SourceValidity; @@ -95,8 +96,8 @@ if (src != null) startDocument = scriptManager.resolveTemplate(src); - this.expressionContext = - FlowObjectModelHelper.getFOMExpressionContext(objectModel, parameters); + this.expressionContext = FlowObjectModelHelper.getFOMExpressionContext( + objectModel, parameters); this.definitions = new HashMap(); } @@ -108,20 +109,21 @@ this.startDocument = null; } - public void performGeneration(Event startEvent, Event endEvent) throws SAXException { - XMLConsumer consumer = new RedundantNamespacesFilter(this.xmlConsumer); + public void performGeneration(Event startEvent, Event endEvent) + throws SAXException { + XMLConsumer consumer = new AttributeAwareXMLConsumerImpl( + new RedundantNamespacesFilter(this.xmlConsumer)); ((Map) expressionContext.get("cocoon")).put("consumer", consumer); - Invoker.execute(consumer, this.expressionContext, - new ExecutionContext(this.definitions, this.scriptManager), - null, startEvent, null); + Invoker.execute(consumer, this.expressionContext, new ExecutionContext( + this.definitions, this.scriptManager), null, startEvent, null); } public Serializable getKey() { JXTExpression cacheKeyExpr = (JXTExpression) this.startDocument .getTemplateProperty(JXTemplateGenerator.CACHE_KEY); try { - final Serializable templateKey = - (Serializable) cacheKeyExpr.getValue(this.expressionContext); + final Serializable templateKey = (Serializable) cacheKeyExpr + .getValue(this.expressionContext); if (templateKey != null) { return new JXCacheKey(this.startDocument.getUri(), templateKey); } @@ -135,10 +137,10 @@ JXTExpression validityExpr = (JXTExpression) this.startDocument .getTemplateProperty(JXTemplateGenerator.VALIDITY); try { - final SourceValidity sourceValidity = - this.startDocument.getSourceValidity(); - final SourceValidity templateValidity = - (SourceValidity) validityExpr.getValue(this.expressionContext); + final SourceValidity sourceValidity = this.startDocument + .getSourceValidity(); + final SourceValidity templateValidity = (SourceValidity) validityExpr + .getValue(this.expressionContext); if (sourceValidity != null && templateValidity != null) { return new JXSourceValidity(sourceValidity, templateValidity); } Modified: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/environment/JXCacheKey.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/environment/JXCacheKey.java?view=diff&r1=161891&r2=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/environment/JXCacheKey.java (original) +++ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/environment/JXCacheKey.java Tue Apr 19 07:11:15 2005 @@ -31,7 +31,7 @@ } public String toString() { - return "TK:" + templateUri + "_" + templateKey; + return "jxtg:" + templateUri + "_" + templateKey; } public boolean equals(Object o) { Added: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/instruction/StartAttribute.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/instruction/StartAttribute.java?view=auto&rev=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/instruction/StartAttribute.java (added) +++ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/instruction/StartAttribute.java Tue Apr 19 07:11:15 2005 @@ -0,0 +1,70 @@ +/* + * Created on 2005-04-19 + */ +package org.apache.cocoon.template.jxtg.instruction; + +import java.util.Stack; + +import org.apache.cocoon.components.expression.ExpressionContext; +import org.apache.cocoon.template.jxtg.environment.ExecutionContext; +import org.apache.cocoon.template.jxtg.expression.JXTExpression; +import org.apache.cocoon.template.jxtg.script.event.Event; +import org.apache.cocoon.template.jxtg.script.event.StartElement; +import org.apache.cocoon.template.jxtg.script.event.StartInstruction; +import org.apache.cocoon.xml.AttributeAwareXMLConsumer; +import org.apache.cocoon.xml.XMLConsumer; +import org.xml.sax.Attributes; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +public class StartAttribute extends StartInstruction { + private JXTExpression name; + private JXTExpression value; + + public StartAttribute(StartElement raw, Attributes attrs, Stack stack) + throws SAXException { + super(raw); + + Locator locator = getLocation(); + String name = attrs.getValue("name"); + if (name == null) { + throw new SAXParseException("parameter: \"name\" is required", + locator, null); + } + this.name = JXTExpression.compileExpr(name, "parameter: \"name\": ", + locator); + + String value = attrs.getValue("value"); + if (value == null) + throw new SAXParseException("parameter: \"value\" is required", + locator, null); + + this.value = JXTExpression.compileExpr(value, "parameter: \"value\": ", + locator); + } + + public Event execute(final XMLConsumer consumer, + ExpressionContext expressionContext, + ExecutionContext executionContext, MacroContext macroContext, + Event startEvent, Event endEvent) throws SAXException { + + String nameStr = null; + String valueStr = ""; + try { + nameStr = this.name.getStringValue(expressionContext); + valueStr = this.value.getStringValue(expressionContext); + } catch (Exception exc) { + throw new SAXParseException(exc.getMessage(), getLocation(), exc); + } + if (consumer instanceof AttributeAwareXMLConsumer) { + AttributeAwareXMLConsumer c = (AttributeAwareXMLConsumer) consumer; + c.attribute("", nameStr, nameStr, "CDATA", valueStr == null ? "" + : valueStr); + } else + throw new SAXParseException("consumer is not attribute aware", + getLocation()); + return getEndInstruction().getNext(); + } + +} Modified: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/script/Parser.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/script/Parser.java?view=diff&r1=161891&r2=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/script/Parser.java (original) +++ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/template/jxtg/script/Parser.java Tue Apr 19 07:11:15 2005 @@ -70,6 +70,7 @@ registerInstruction("comment", StartComment.class.getName()); registerInstruction("call", StartCall.class.getName()); registerInstruction("withParam", StartParameterInstance.class.getName()); + registerInstruction("attribute", StartAttribute.class.getName()); } catch (Exception e) { // we'll do something more professional with that when the configuration moves // to the sitemap Added: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumer.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumer.java?view=auto&rev=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumer.java (added) +++ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumer.java Tue Apr 19 07:11:15 2005 @@ -0,0 +1,11 @@ +/* + * Created on 2005-04-16 + */ +package org.apache.cocoon.xml; + +import org.xml.sax.SAXException; + +public interface AttributeAwareXMLConsumer extends XMLConsumer { + public void attribute(String uri, String localName, String qName, + String type, String value) throws SAXException; +} Added: cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumerImpl.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumerImpl.java?view=auto&rev=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumerImpl.java (added) +++ cocoon/blocks/unsupported/template/trunk/java/org/apache/cocoon/xml/AttributeAwareXMLConsumerImpl.java Tue Apr 19 07:11:15 2005 @@ -0,0 +1,207 @@ +/* + * Created on 2005-04-16 + */ +package org.apache.cocoon.xml; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.AttributesImpl; + +public class AttributeAwareXMLConsumerImpl implements AttributeAwareXMLConsumer { + private StartElement currentElement; + private List saxbits; + private Locator locator; + + private XMLConsumer delegate; + + public AttributeAwareXMLConsumerImpl(XMLConsumer consumer) { + this.delegate = consumer; + this.saxbits = new ArrayList(); + } + + public void setDocumentLocator(Locator locator) { + this.locator = locator; + delegate.setDocumentLocator(locator); + } + + public void startDocument() throws SAXException { + delegate.startDocument(); + } + + public void endDocument() throws SAXException { + playCache(); + delegate.endDocument(); + } + + public void startPrefixMapping(String prefix, String uri) + throws SAXException { + playCache(); + delegate.startPrefixMapping(prefix, uri); + } + + public void endPrefixMapping(String prefix) throws SAXException { + playCache(); + delegate.endPrefixMapping(prefix); + } + + public void startElement(String namespaceURI, String localName, + String qName, Attributes attrs) throws SAXException { + playCache(); + this.currentElement = new StartElement(namespaceURI, localName, qName, attrs); + } + + public void endElement(String namespaceURI, String localName, String qName) + throws SAXException { + playCache(); + delegate.endElement(namespaceURI, localName, qName); + } + + public void characters(char[] ch, int start, int length) + throws SAXException { + if (this.currentElement != null) + this.saxbits.add(new Characters(ch, start, length)); + else + delegate.characters(ch, start, length); + + } + + public void ignorableWhitespace(char[] ch, int start, int length) + throws SAXException { + if (this.currentElement != null) + this.saxbits.add(new IgnorableWhitespace(ch, start, length)); + else + delegate.ignorableWhitespace(ch, start, length); + } + + public void processingInstruction(String target, String data) + throws SAXException { + playCache(); + delegate.processingInstruction(target, data); + } + + public void skippedEntity(String name) throws SAXException { + playCache(); + delegate.skippedEntity(name); + } + + public void startDTD(String name, String publicId, String systemId) + throws SAXException { + playCache(); + delegate.startDTD(name, publicId, systemId); + } + + public void endDTD() throws SAXException { + playCache(); + delegate.endDTD(); + } + + public void startEntity(String name) throws SAXException { + playCache(); + delegate.startEntity(name); + } + + public void endEntity(String name) throws SAXException { + playCache(); + delegate.endEntity(name); + } + + public void startCDATA() throws SAXException { + playCache(); + delegate.startCDATA(); + } + + public void endCDATA() throws SAXException { + playCache(); + delegate.endCDATA(); + } + + public void comment(char[] ch, int start, int length) throws SAXException { + playCache(); + delegate.comment(ch, start, length); + } + + public void attribute(String uri, String localName, String qName, + String type, String value) throws SAXException { + if (this.currentElement == null) + throw new SAXParseException("attribute event not allowed here", + this.locator); + else + this.currentElement.attribute(uri, localName, qName, type, value); + } + + interface SaxBit { + public void send(ContentHandler contentHandler) throws SAXException; + } + + private class StartElement implements SaxBit { + private String namespaceURI; + private String localName; + private String qName; + private AttributesImpl attrs; + + public StartElement(String namespaceURI, String localName, + String qName, Attributes attrs) { + this.namespaceURI = namespaceURI; + this.localName = localName; + this.qName = qName; + this.attrs = new AttributesImpl(attrs); + } + + public void send(ContentHandler contentHandler) throws SAXException { + contentHandler.startElement(this.namespaceURI, this.localName, + this.qName, this.attrs); + } + + public void attribute(String uri, String localName, String qName, + String type, String value) { + this.attrs.addAttribute(uri, localName, qName, type, value); + } + } + + public final static class Characters implements SaxBit { + public final char[] ch; + + public Characters(char[] ch, int start, int length) { + this.ch = new char[length]; + System.arraycopy(ch, start, this.ch, 0, length); + } + + public void send(ContentHandler contentHandler) throws SAXException { + contentHandler.characters(ch, 0, ch.length); + } + } + + public final static class IgnorableWhitespace implements SaxBit { + public final char[] ch; + + public IgnorableWhitespace(char[] ch, int start, int length) { + this.ch = new char[length]; + System.arraycopy(ch, start, this.ch, 0, length); + } + + public void send(ContentHandler contentHandler) throws SAXException { + contentHandler.ignorableWhitespace(ch, 0, ch.length); + } + } + + public void playCache() throws SAXException { + if (this.currentElement != null) { + this.currentElement.send(delegate); + this.currentElement = null; + } + + Iterator it = this.saxbits.iterator(); + while (it.hasNext()) { + SaxBit saxBit = (SaxBit) it.next(); + saxBit.send(delegate); + } + this.saxbits.clear(); + } +} Modified: cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/JXTemplateGeneratorTestCase.java URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/JXTemplateGeneratorTestCase.java?view=diff&r1=161891&r2=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/JXTemplateGeneratorTestCase.java (original) +++ cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/JXTemplateGeneratorTestCase.java Tue Apr 19 07:11:15 2005 @@ -23,6 +23,7 @@ import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.SitemapComponentTestCase; import org.apache.cocoon.components.flow.FlowHelper; +import org.w3c.dom.Document; public class JXTemplateGeneratorTestCase extends SitemapComponentTestCase { private Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_WARN); @@ -119,6 +120,13 @@ public void testJXSet() throws Exception { String inputURI = docBase + "jxSet.xml"; String outputURI = docBase + "jxSet-output.xml"; + + assertEqual(load(outputURI), generate(JX, inputURI, EMPTY_PARAMS)); + } + + public void testAttribute() throws Exception { + String inputURI = docBase + "jxAttribute.xml"; + String outputURI = docBase + "jxAttribute-output.xml"; assertEqual(load(outputURI), generate(JX, inputURI, EMPTY_PARAMS)); } Added: cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute-output.xml URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute-output.xml?view=auto&rev=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute-output.xml (added) +++ cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute-output.xml Tue Apr 19 07:11:15 2005 @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<root xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"> + <one foo="bar"> + </one> + <two second="twoAttr"> + xyz + </two> + <three foo="bar" foo2="bar2" dd="dd"> + <abc>def</abc> + </three> +</root> Added: cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute.xml URL: http://svn.apache.org/viewcvs/cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute.xml?view=auto&rev=161892 ============================================================================== --- cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute.xml (added) +++ cocoon/blocks/unsupported/template/trunk/test/org/apache/cocoon/template/jxtg/jxAttribute.xml Tue Apr 19 07:11:15 2005 @@ -0,0 +1,16 @@ +<?xml version="1.0"?> +<root xmlns:jx="http://apache.org/cocoon/templates/jx/1.0"> + <one> + <jx:attribute name="foo" value="bar"/> + </one> + <jx:set var="a" value="dd"/> + <two> + <jx:if test="${a == 'dd'}"> + <jx:attribute name="second" value="twoAttr"/> + </jx:if> xyz </two> + <three foo="bar"> + <jx:attribute name="foo2" value="bar2"/> + <jx:attribute name="${a}" value="${a}"/> + <abc>def</abc> + </three> +</root>