Return-Path: Mailing-List: contact cocoon-users-help@xml.apache.org; run by ezmlm Delivered-To: mailing list cocoon-users@xml.apache.org Received: (qmail 72317 invoked from network); 15 Mar 2000 00:56:00 -0000 Received: from shaggy-s1.lineone.net (HELO shaggy.lineone.net) (194.75.152.225) by locus.apache.org with SMTP; 15 Mar 2000 00:56:00 -0000 Received: from eddie (host212-140-2-74.btinternet.com [212.140.2.74]) by shaggy.lineone.net (8.9.3/8.8.8) with SMTP id NAA10178 for ; Tue, 14 Mar 2000 13:48:58 GMT Message-ID: <003201bf8dbc$1963c440$2a01a8c0@eddie> From: "Ross Burton" To: "Cocoon Users" Subject: AbstractProcessor Date: Tue, 14 Mar 2000 13:48:35 -0000 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_002F_01BF8DBB.FE4070A0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.00.2314.1300 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 X-Spam-Rating: locus.apache.org 1.6.2 0/1000/N ------=_NextPart_000_002F_01BF8DBB.FE4070A0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Hi, This morning I started to write another Cocoon processor (which generates directory listings basically) and realised that I was writing the same code again and again and.... All of my processors have been modelled after the process() method in the SQL and LDAP processors supplied with Cocoon, after some dumbing-down as what I've been writing has been fairly simple (the most useful was a bridge to a XQL engine). I decided to create an AbstractProcessor class which does this for you - it will take all instances of a specified node, create a Dictionary of the attributes, override this with parameters in the request URL, and get the text contained within the nodes. This is passed to an abstract method which returns a DocumentFragment, which is then replaced for the original node. Also attached is a test processor, basically it will take all this is a test nodes and replace them with tset a si siht. Comments, critism, flames and proposals all welcome (yes, when Cocoon 2 comes out I'll probably rework it in SAX) Regards, Ross Burton ------=_NextPart_000_002F_01BF8DBB.FE4070A0 Content-Type: application/octet-stream; name="DummyProcessor.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="DummyProcessor.java" package burton.cocoon; import java.util.*; import javax.servlet.http.HttpServletRequest; import org.w3c.dom.*; import org.apache.cocoon.processor.*; /** * This is a dummy processor using AbstractProcessor, which simply = reverses the * text in all nodes. * @author Ross Burton */ public class DummyProcessor extends AbstractProcessor { =20 protected DocumentFragment processQuery(String data, Properties = props, Document doc) throws Exception { DocumentFragment d =3D doc.createDocumentFragment(); Element e =3D doc.createElement("dummy"); data =3D new StringBuffer(data).reverse().toString(); Text t =3D doc.createTextNode(data); e.appendChild(t); d.appendChild(e); return d; } /** * The status string of the procesor, displayed in /Cocoon.xml */ public String getStatus() { return "Dummy Processor"; } /** * The name of the tag to work on, in this case it's all = tags */ protected String getTagName() { return "dummy"; } } ------=_NextPart_000_002F_01BF8DBB.FE4070A0 Content-Type: application/octet-stream; name="AbstractProcessor.java" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="AbstractProcessor.java" package burton.cocoon; import java.util.*; import javax.servlet.http.HttpServletRequest; import org.w3c.dom.*; import org.apache.cocoon.framework.*; import org.apache.cocoon.processor.*; /** * An abstract Processor class. This class will help you if the = processor you * are writing follows this model: * + you are looking for a tag to work upon, and replace it's contents = entirely * + The tag looks like this: long = parameter, like a a query * + You want arguments in the tag to be overridden by request-time = parameters if they are present * * Thanks to Donald Ball for this SQLProcessor, which this code was = inspired by. * @author Ross Burton */ public abstract class AbstractProcessor extends AbstractActor implements = Processor, Status { /** * This is the entry point for Cocoon. We take parameters from the = tag and * the request, merge them and present them to the processor. */ public Document process(Document doc, Dictionary parameters) throws = Exception { // Get all nodes with the correct tag NodeList processorNodes =3D = doc.getElementsByTagName(getTagName()); =09 // Iterate over every node we've found for (int i =3D 0; i < processorNodes.getLength(); ++i) { Node processorNode =3D processorNodes.item(i); // If this node is not an Element, go to the next node if (processorNode.getNodeType() !=3D Node.ELEMENT_NODE) { continue; } Element processorElement =3D (Element)processorNode; Properties props =3D new Properties(); StringBuffer processorData =3D new StringBuffer(); // Get the attributes of this node NamedNodeMap processorAttributes =3D = processorElement.getAttributes(); for (int j =3D 0; j < processorAttributes.getLength(); ++j) { Node processorAttribute =3D processorAttributes.item(j); props.put(processorAttribute.getNodeName(), = processorAttribute.getNodeValue()); } // Now override this with request time options HttpServletRequest request =3D = (HttpServletRequest)parameters.get("request"); for (Enumeration e =3D request.getParameterNames(); = e.hasMoreElements(); ) { String paramName =3D (String)e.nextElement(); String paramValue =3D request.getParameter(paramName); props.put(paramName, paramValue); } // Get the text nodes as the processor data NodeList processorTextNodes =3D processorElement.getChildNodes(); for (int k =3D 0; k < processorTextNodes.getLength(); ++k) { Node processorTextNode =3D processorTextNodes.item(k); if (processorTextNode.getNodeType() =3D=3D Node.TEXT_NODE) { processorData.append(processorTextNode.getNodeValue()); } } DocumentFragment resultFragment =3D = processQuery(processorData.toString(), props, doc); // Replace nodes, unless returned null if (resultFragment!=3D null) { processorElement.getParentNode().replaceChild(resultFragment, = processorElement); } } return doc; } /** * This is the entry point as far as processors are concerned. * @param data The text between the opening and closing elements * @param props Properties for this processor, from the tag and = request * @param doc The Document object, to examine or create nodes from */ abstract protected DocumentFragment processQuery(String data, = Properties props, Document doc) throws Exception ; =20 /** * The status string for this processor - displayed in /Cocoon.xml */ abstract public String getStatus(); /** * The tag name which this processor works upon */ abstract protected String getTagName(); /** * Is the transformation I'm about to apply changed since it last = happened? */ public boolean hasChanged(Object context) { return true; } } ------=_NextPart_000_002F_01BF8DBB.FE4070A0--