cziegeler 2003/01/31 04:37:54 Modified: src/java/org/apache/cocoon/transformation Tag: cocoon_2_0_3_branch AbstractSAXTransformer.java CIncludeTransformer.java Log: Backporting session, authentication and portal framework Revision Changes Path No revision No revision 1.2.2.3 +19 -12 xml-cocoon2/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java Index: AbstractSAXTransformer.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java,v retrieving revision 1.2.2.2 retrieving revision 1.2.2.3 diff -u -r1.2.2.2 -r1.2.2.3 --- AbstractSAXTransformer.java 30 Jan 2003 16:20:14 -0000 1.2.2.2 +++ AbstractSAXTransformer.java 31 Jan 2003 12:37:54 -0000 1.2.2.3 @@ -99,7 +99,7 @@ * <li>Process the information</li> * <li>Create new events from the processed information</li> * </ul><p> - * For all these four purposes the AbstractSunshineTransformer offers some + * For all these four purposes the AbstractSAXTransformer offers some * powerful methods and hooks: * <p> * Namespace handling<p> @@ -163,7 +163,7 @@ /** * This is the default namespace used by the transformer. - * It should be set by in the constructor. + * It should be set in the constructor. */ protected String defaultNamespaceURI; @@ -192,6 +192,9 @@ /** The SourceResolver for this request */ protected SourceResolver resolver; + /** Are we already initialized for the current request? */ + private boolean isInitialized; + /** Empty attributes (for performance). This can be used * do create own attributes, but make sure to clean them * afterwords. @@ -241,6 +244,7 @@ this.resolver = resolver; this.parameters = par; this.source = src; + this.isInitialized = false; // get the current namespace this.namespaceURI = this.parameters.getParameter("namespaceURI", this.defaultNamespaceURI); @@ -287,12 +291,15 @@ */ public void startDocument() throws SAXException { + if ( !this.isInitialized ) { try { this.setupTransforming(); } catch (ProcessingException local) { throw new SAXException("ProcessingException: " + local, local); } catch (IOException ioe) { throw new SAXException("IOException: " + ioe, ioe); + } + this.isInitialized = true; } if (this.ignoreEventsCount == 0) super.startDocument(); } @@ -325,8 +332,8 @@ // this is our namespace: try { this.startTransformingElement(uri, name, raw, attr); - } catch (ProcessingException sunShineException) { - throw new SAXException("ProcessingException: " + sunShineException, sunShineException); + } catch (ProcessingException pException) { + throw new SAXException("ProcessingException: " + pException, pException); } catch (IOException ioe) { throw new SAXException("Exception occured during processing: " + ioe, ioe); } @@ -350,9 +357,9 @@ // this is our namespace: try { this.endTransformingElement(uri, name, raw); - } catch (ProcessingException sunShineException) { - throw new SAXException("ProcessingException: " + sunShineException, - sunShineException); + } catch (ProcessingException pException) { + throw new SAXException("ProcessingException: " + pException, + pException); } catch (IOException ioe) { throw new SAXException("Exception occured during processing: " + ioe, ioe); } @@ -431,7 +438,7 @@ /** * Start DocumentFragment recording. - * All invoming events are recorded and not forwarded. The resulting + * All invoking events are recorded and not forwarded. The resulting * DocumentFragment can be obtained by the matching endRecording() call. */ public void startRecording() @@ -442,7 +449,7 @@ DOMBuilder builder = new DOMBuilder(); this.addRecorder(builder); builder.startDocument(); - builder.startElement("", "sunShine", "sunShine", new AttributesImpl()); + builder.startElement("", "cocoon", "cocoon", new AttributesImpl()); this.sendStartPrefixMapping(); @@ -453,7 +460,7 @@ /** * Stop DocumentFragment recording. - * All invoming events are recorded and not forwarded. This method returns + * All invoking events are recorded and not forwarded. This method returns * the resulting DocumentFragment. */ public DocumentFragment endRecording() @@ -465,7 +472,7 @@ this.sendEndPrefixMapping(); DOMBuilder builder = (DOMBuilder)this.removeRecorder(); - builder.endElement("", "sunShine", "sunShine"); + builder.endElement("", "cocoon", "cocoon"); builder.endDocument(); // Create Document Fragment 1.6.2.1 +270 -37 xml-cocoon2/src/java/org/apache/cocoon/transformation/CIncludeTransformer.java Index: CIncludeTransformer.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/CIncludeTransformer.java,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -u -r1.6 -r1.6.2.1 --- CIncludeTransformer.java 22 Feb 2002 07:03:56 -0000 1.6 +++ CIncludeTransformer.java 31 Jan 2003 12:37:54 -0000 1.6.2.1 @@ -50,15 +50,27 @@ */ package org.apache.cocoon.transformation; -import org.apache.avalon.framework.component.ComponentManager; -import org.apache.avalon.framework.component.Composable; +import org.apache.avalon.excalibur.xml.xpath.XPathProcessor; +import org.apache.avalon.framework.component.Component; +import org.apache.avalon.framework.component.ComponentException; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.components.parser.Parser; +import org.apache.cocoon.components.source.SourceUtil; import org.apache.cocoon.environment.Source; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.xml.IncludeXMLConsumer; +import org.apache.cocoon.xml.XMLUtils; +import org.apache.excalibur.source.SourceException; +import org.apache.excalibur.source.SourceParameters; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.ext.LexicalHandler; import org.xml.sax.helpers.AttributesImpl; import java.io.IOException; @@ -73,39 +85,79 @@ * <code>prefix</code> it is possible to specify an element * which surrounds the included content. * + * This transformer also supports a more verbose but flexible version: + * <cinclude:includexml xmlns:cinclude="http://apache.org/cocoon/include/1.0" ignoreErrors="false"> + * <cinclude:src>THE SRC URI</cinclude:src> + * <!-- This is an optional configuration block --> + * <cinclude:configuration> + * <!-- For example if you want to make a HTTP POST --> + * <cinclude:parameter> + * <cinclude:name>method</cinclude:name> + * <cinclude:value>POST</cinclude:value> + * </cinclude:parameter> + * </cinclude:configuration> + * <!-- The following are optional parameters appended to the URI --> + * <cinclude:parameters> + * <cinclude:parameter> + * <cinclude:name>a name</cinclude:name> + * <cinclude:value>a value</cinclude:value> + * </cinclude:parameter> + * <!-- more can follow --> + * </cinclude:parameters> + * </cinclude:includexml> + * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> + * @author <a href="mailto:[EMAIL PROTECTED]">Andrew C. Oliver</a> * @version CVS $Id$ */ -public class CIncludeTransformer extends AbstractTransformer -implements Composable { +public class CIncludeTransformer +extends AbstractSAXTransformer { public static final String CINCLUDE_NAMESPACE_URI = "http://apache.org/cocoon/include/1.0"; public static final String CINCLUDE_INCLUDE_ELEMENT = "include"; public static final String CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE = "src"; public static final String CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE = "element"; + public static final String CINCLUDE_INCLUDE_ELEMENT_SELECT_ATTRIBUTE = "select"; public static final String CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE = "ns"; public static final String CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE = "prefix"; - /** The <code>SourceResolver</code> */ - protected SourceResolver sourceResolver; - - /** The current <code>ComponentManager</code>. */ - protected ComponentManager manager = null; - + public static final String CINCLUDE_INCLUDEXML_ELEMENT = "includexml"; + public static final String CINCLUDE_INCLUDEXML_ELEMENT_IGNORE_ERRORS_ATTRIBUTE = "ignoreErrors"; + public static final String CINCLUDE_SRC_ELEMENT = "src"; + public static final String CINCLUDE_CONFIGURATION_ELEMENT = "configuration"; + public static final String CINCLUDE_PARAMETERS_ELEMENT = "parameters"; + public static final String CINCLUDE_PARAMETER_ELEMENT = "parameter"; + public static final String CINCLUDE_NAME_ELEMENT = "name"; + public static final String CINCLUDE_VALUE_ELEMENT = "value"; + + private static final int STATE_OUTSIDE = 0; + private static final int STATE_INCLUDE = 1; + + /** The configuration of includexml */ + protected Parameters configurationParameters; + + /** The parameters for includexml */ + protected SourceParameters resourceParameters; + + /** The current state: STATE_ */ + protected int state; + + /** + * Constructor + * Set the namespace + */ + public CIncludeTransformer() { + this.namespaceURI = CINCLUDE_NAMESPACE_URI; + } + /** * Setup the component. */ public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws ProcessingException, SAXException, IOException { - this.sourceResolver = resolver; - } - - /** - * Composable Interface - */ - public final void compose(final ComponentManager manager) { - this.manager = manager; + super.setup(resolver, objectModel, source, parameters); + this.state = STATE_OUTSIDE; } /** @@ -113,45 +165,193 @@ */ public void recycle() { super.recycle(); - this.sourceResolver = null; + this.configurationParameters = null; + this.resourceParameters = null; } - public void startElement(String uri, String name, String raw, Attributes attr) - throws SAXException { - if (uri != null && name != null - && uri.equals(CINCLUDE_NAMESPACE_URI) - && name.equals(CINCLUDE_INCLUDE_ELEMENT)) { + public void startTransformingElement(String uri, String name, String raw, Attributes attr) + throws ProcessingException ,IOException, SAXException { + if (name.equals(CINCLUDE_INCLUDE_ELEMENT)) { this.processCIncludeElement(attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE), attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE), + attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_SELECT_ATTRIBUTE), attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE), attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE)); + // Element: include + } else if (name.equals(CINCLUDE_INCLUDEXML_ELEMENT) + && this.state == STATE_OUTSIDE) { + this.state = STATE_INCLUDE; + String ignoreErrors = attr.getValue("", CINCLUDE_INCLUDEXML_ELEMENT_IGNORE_ERRORS_ATTRIBUTE); + if (ignoreErrors == null || ignoreErrors.length() == 0) { + ignoreErrors = "false"; + } + this.stack.push(new Boolean(this.ignoreEmptyCharacters)); + this.stack.push(new Boolean(this.ignoreWhitespaces)); + this.stack.push(ignoreErrors); + + this.ignoreEmptyCharacters = false; + this.ignoreWhitespaces = true; + + // target + } else if (name.equals(CINCLUDE_SRC_ELEMENT) + && this.state == STATE_INCLUDE) { + this.startTextRecording(); + + // configparameters + } else if (name.equals(CINCLUDE_CONFIGURATION_ELEMENT) + && this.state == STATE_INCLUDE) { + stack.push("end"); + + // parameters + } else if (name.equals(CINCLUDE_PARAMETERS_ELEMENT) + && this.state == STATE_INCLUDE) { + stack.push("end"); + + // parameter + } else if (name.equals(CINCLUDE_PARAMETER_ELEMENT) + && this.state == STATE_INCLUDE) { + + // parameter name + } else if (name.equals(CINCLUDE_NAME_ELEMENT) + && this.state == STATE_INCLUDE) { + this.startTextRecording(); + + // parameter value + } else if (name.equals(CINCLUDE_VALUE_ELEMENT) + && this.state == STATE_INCLUDE) { + this.startSerializedXMLRecording(XMLUtils.defaultSerializeToXMLFormat(true)); + } else { - super.startElement(uri, name, raw, attr); + super.startTransformingElement(uri, name, raw, attr); } } - public void endElement(String uri, String name, String raw) throws SAXException { - if (uri != null && name != null - && uri.equals(CINCLUDE_NAMESPACE_URI) - && name.equals(CINCLUDE_INCLUDE_ELEMENT)) { + public void endTransformingElement(String uri, String name, String raw) + throws ProcessingException, IOException, SAXException { + if (name.equals(CINCLUDE_INCLUDE_ELEMENT)) { + // do nothing return; + + // Element: includexml + } else if (name.equals(CINCLUDE_INCLUDEXML_ELEMENT) + && this.state == STATE_INCLUDE) { + + this.state = STATE_OUTSIDE; + + final String resource = (String)stack.pop(); + + final boolean ignoreErrors = ((String)stack.pop()).equals("true"); + + if (this.getLogger().isDebugEnabled()) { + getLogger().debug("Processing CIncludexml element: src=" + resource + + ", ignoreErrors=" + ignoreErrors + + ", configuration=" + this.configurationParameters + + ", parameters=" + this.resourceParameters); + } + Source source = null; + try { + source = SourceUtil.getSource(resource, + this.configurationParameters, + this.resourceParameters, + this.resolver); + + SourceUtil.toSAX(source, this.xmlConsumer, manager, this.configurationParameters, true); + + } catch (SourceException se) { + if (!ignoreErrors) throw SourceUtil.handle(se); + } catch (SAXException se) { + if (!ignoreErrors) throw se; + } catch (IOException ioe) { + if (!ignoreErrors) throw ioe; + } catch (ProcessingException pe) { + if (!ignoreErrors) throw pe; + } finally { + if (source != null) source.recycle(); + } + + // restore values + this.ignoreWhitespaces = ((Boolean)stack.pop()).booleanValue(); + this.ignoreEmptyCharacters = ((Boolean)stack.pop()).booleanValue(); + + // src element + } else if (name.equals(CINCLUDE_SRC_ELEMENT) + && this.state == STATE_INCLUDE) { + + this.stack.push(this.endTextRecording()); + + } else if (name.equals(CINCLUDE_PARAMETERS_ELEMENT) + && this.state == STATE_INCLUDE) { + this.resourceParameters = new SourceParameters(); + // Now get the parameters off the stack + String label = (String)stack.pop(); + String key = null; + String value = null; + while (!label.equals("end")) { + if (label.equals("name")) key = (String)stack.pop(); + if (label.equals("value")) value = (String)stack.pop(); + if (key != null && value != null) { + this.resourceParameters.setParameter(key, value); + key = null; + value = null; + } + label = (String)stack.pop(); + } + + } else if (name.equals(CINCLUDE_CONFIGURATION_ELEMENT) == true + && this.state == STATE_INCLUDE) { + this.configurationParameters = new Parameters(); + // Now get the parameters off the stack + String label = (String)stack.pop(); + String key = null; + String value = null; + while (!label.equals("end")) { + if (label.equals("name")) key = (String)stack.pop(); + if (label.equals("value")) value = (String)stack.pop(); + if (key != null && value != null) { + this.configurationParameters.setParameter(key, value); + key = null; + value = null; + } + label = (String)stack.pop(); + } + + } else if (name.equals(CINCLUDE_PARAMETER_ELEMENT) == true + && this.state == STATE_INCLUDE) { + + } else if (name.equals(CINCLUDE_NAME_ELEMENT) == true + && this.state == STATE_INCLUDE) { + stack.push(this.endTextRecording()); + stack.push("name"); + + // parameter value + } else if (name.equals(CINCLUDE_VALUE_ELEMENT) == true + && this.state == STATE_INCLUDE) { + stack.push(this.endSerializedXMLRecording()); + stack.push("value"); + + } else { + super.endTransformingElement(uri, name, raw); } - super.endElement(uri, name, raw); } - protected void processCIncludeElement(String src, String element, String ns, String prefix) + protected void processCIncludeElement(String src, String element, + String select, String ns, String prefix) throws SAXException { if (element == null) element=""; + if (select == null) select=""; if (ns == null) ns=""; if (prefix == null) prefix=""; + if (this.getLogger().isDebugEnabled()) { getLogger().debug("Processing CInclude element: src=" + src + ", element=" + element + + ", select=" + select + ", ns=" + ns + ", prefix=" + prefix); + } IncludeXMLConsumer consumer = new IncludeXMLConsumer(this); @@ -168,16 +368,49 @@ Source source = null; try { - source = this.sourceResolver.resolve(src); - source.toSAX(consumer); + source = this.resolver.resolve(src); + + if (!"".equals(select)) { + + + Parser parser = null; + XPathProcessor processor = null; + + try { + parser = (Parser)this.manager.lookup(Parser.ROLE); + processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE); + + InputSource input = SourceUtil.getInputSource(source); + + Document document = parser.parseDocument(input); + NodeList list = processor.selectNodeList(document, select); + int length = list.getLength(); + for (int i=0; i<length; i++) { + IncludeXMLConsumer.includeNode((Node)list.item(i), + (ContentHandler)this, + (LexicalHandler)this); + } + } finally { + this.manager.release(parser); + this.manager.release((Component)processor); + } + } else { + String mimeType = null; + if ( null != this.configurationParameters ) { + mimeType = this.configurationParameters.getParameter("mime-type", mimeType); + } + SourceUtil.toSAX(source, mimeType, consumer, super.manager); + } + + } catch (IOException e) { - getLogger().error("CIncludeTransformer", e); throw new SAXException("CIncludeTransformer could not read resource", e); } catch (ProcessingException e){ - getLogger().error("Could not stream input", e); throw new SAXException("Exception in CIncludeTransformer",e); + } catch(ComponentException e) { + throw new SAXException(e); } finally { - source.recycle(); + if (source != null) source.recycle(); } if (!"".equals(element)) {
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]