Hi all, let me start with a short introduction of my company and what we have done so far. Before being founded on April 1, 2001 as BASF IT Services we were an integrated part of BASF Aktiengesellschaft in Ludwigshafen, Germany and BASF Computer Services in Europe. We focus on high-quality IT-Development and Services throughout Europe. E-Commerce is one of our businesses we have been working with since several years and where we are very experienced in developing successful solutions for BASF. End of 2000, BASF started their global E-Commerce initiative named "WorldAccount", focusing on a worldwide and integrated extranet platform for their customers (have a look at it: http://worldaccount.basf.com). To realize such a complex solution we had the idea to develop a publishing framework which should also cover issues like session management, multi-language support, layout and security. After evaluating Cocoon2 we decided to base on the concepts of Avalon and the basic interfaces of Cocoon2, but due to its pre-alpha version we needed to do some additional development (interpreted Sitemap, LayoutTransformer, RequestProcessor, ValidationEngine, ErrorHandler, simple module concept (like Blocks but really simple)......) One other example: instead of using XSP-Logicsheets we developed a tag-implementation similar to JSP-tags, but which uses a SAX-pipeline instead of an output stream. The tags are interpreted during run-time by the appropriate tag-transformer. We needed approx. half a year to develop this framework where then the WorldAccount functionalities could be placed on top and finally could go-live in the 3rd quarter of 2001. In the last few months we transferred our framework to Cocoon2 and would now like to present some of our solutions to the Open Source community, hoping we can help to become Cocoon2 even more powerful and successful than it already is. Ok, lets start with the Java-Code ;-) also part of the attachment. The Tag Interface: public interface Tag extends XMLPipe, Component { String ROLE = Tag.class.getName(); /** * Evaluate body content * Valid return value for doStartTag. */ int EVAL_BODY = 0; /** * Skip body evaluation. * Valid return value for doStartTag. */ int SKIP_BODY = 1; /** * Continue evaluating the page. * Valid return value for doEndTag(). */ int EVAL_PAGE = 2; /** * Process the end tag for this instance. * * @returns EVAL_PAGE. * @throws SAXException. */ int doEndTag(String namespaceURI, String localName, String qName) throws SAXException; /** * Process the start tag for this instance. * <p> * The doStartTag method assumes that parent have been set. * It also assumes that any properties exposed as * attributes have been set too. When this method is invoked, the body * has not yet been evaluated. * * @returns EVAL_BODY or SKIP_BODY. */ int doStartTag(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException; /** * Get the parent (closest enclosing tag handler) for this tag handler. * * @returns the current parent or null if none. */ Tag getParent(); /** * Set the <code>SourceResolver</code>, objectModel <code>Map</code> * and sitemap <code>Parameters</code> used to process the request. */ void setup(SourceResolver resolver, Map objectModel, Parameters parameters) throws SAXException, IOException; /** * Set the parent (closest enclosing tag handler) of this tag handler. * Invoked by the implementation object prior to doStartTag(). * * @param parent The parent tag or null. */ void setParent(Tag parent); } The Tag Implementation works like a JSP Tag but generate SAX output. Simple Tag Implementation: public class XMLDateTag extends AbstractTag { public int doStartTag(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { String date = new Date(System.currentTimeMillis()).toString(); characters(date.toCharArray(), 0, date.length()); return EVAL_BODY; } } In the current implementation the Tag's are configured in cocoon.xconf. All Tags are managed by a ComponentSelector and grouped by a namespace (name of the taglib Element). We are using URN's as namespace. The name of a tag is then mapped to it's implementation. Example configuration: <component role="org.apache.cocoon.xml.taglib.TagSelector" class="org.apache.cocoon.components.ExtendedComponentSelector"> <taglib name="urn:apache:taglib:general" class="org.apache.cocoon.components.ExtendedComponentSelector" logger="sitemap.tag"> <tag name="date" class="org.apache.cocoon.xml.taglib.general.XMLDateTag" logger="sitemap.tag.xmldate" /> <tag name="..." class="..." /> </taglib> <taglib name="urn:apache:taglib:... /> <tag ..... /> </taglib> </component> Simple example page: <page> <title xmlns:tag="urn:apache:taglib:general">Hello</title> <content> <para>This is my first Cocoon page!</para> <para>Today, <tag:date /></para> </content> </page> How does it work? In the pipeline you need to configure the TagTransformer and add it to your pipeline. Set the pool-min to "0" because of a bug in excalibur, instead you run in a endless loop. <map:transformer name="tag" src="org.apache.cocoon.transformation.TagTransformer" pool-max="64" pool-min="0" pool-grow="2" logger="sitemap.transformer.tag"> <transformer-hint>tag</transformer-hint> </map:transformer> The TagTransformer looks if the namespace of an element belongs to a configured taglib namespace and tag name (see startElement). If it founds a Tag, this Tag is dynamically inserted to the current SAX-Pipeline and the doStartTag method is called. If the Tag implements some "SAX Event handling" methods, the Tag is able to work like a Transformer. The default behavior is a XMLPipe. The doEndTag method is called if the endElement SAX Event is called (see endElement of TagTransformer) and the Tag is removed from the pipeline. In the doStartTag and/or in the doEndTag you can emit additional SAX events to the Pipeline (see XMLDateTag which only sends the current date). Tags can be nested and a inner Tag can get a reference to the parent Tag (getParent method). The TagTransformer can be configured with a "transformer-hint". If the TagTransformer add a Tag to the Pipeline the Transformer which belongs to this hint is also add to the pipeline (after the Tag). If this hint is the TagTransformer itself, a Tag can send out other Tags which are automatic interpreted again. Any comments ? If you find this usefull, is it possible that a committer put this to scratchpad ? Thanks Volker (See attached file: source.zip)
source.zip
Description: .ZIP File
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]