You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by re...@apache.org on 2008/06/13 16:23:14 UTC
svn commit: r667553 - in /cocoon/whiteboard/corona/trunk:
corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/
corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/
corona-pipeline/src/main/java/org/apache/cocoon/corona...
Author: reinhard
Date: Fri Jun 13 07:23:14 2008
New Revision: 667553
URL: http://svn.apache.org/viewvc?rev=667553&view=rev
Log:
. add a simple implementation of an include transformer (no caching, no parallel processing etc)
. reuse IncludeXMLConsumer from trunk
Added:
cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java (with props)
cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java (with props)
cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java (with props)
Modified:
cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/GenerateNode.java
cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/TransformNode.java
cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/resources/META-INF/cocoon/spring/corona-pipeline-component.xml
Added: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java?rev=667553&view=auto
==============================================================================
--- cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java (added)
+++ cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java Fri Jun 13 07:23:14 2008
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.corona.pipeline;
+
+/**
+ * Exception that indicates that there was a problem while processing a pipeline.
+ */
+public class ProcessingException extends RuntimeException {
+
+ public ProcessingException() {
+ super();
+ }
+
+ public ProcessingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ProcessingException(String message) {
+ super(message);
+ }
+
+ public ProcessingException(Throwable cause) {
+ super(cause);
+ }
+}
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/ProcessingException.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java?rev=667553&view=auto
==============================================================================
--- cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java (added)
+++ cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java Fri Jun 13 07:23:14 2008
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.corona.pipeline.component;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.apache.cocoon.corona.pipeline.ProcessingException;
+import org.apache.cocoon.corona.pipeline.util.IncludeXMLConsumer;
+import org.apache.cocoon.corona.pipeline.util.StringRepresentation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+public class IncludeTransformer extends AbstractTransformer {
+
+ private final Log logger = LogFactory.getLog(this.getClass());
+
+ private static final String INCLUDE_NS = "http://apache.org/cocoon/corona/include/1.0";
+
+ private static final String INCLUDE_EL = "include";
+
+ private static final String SRC_ATTR = "src";
+
+ private URL baseUrl;
+
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
+ if (INCLUDE_NS.equals(uri) && INCLUDE_EL.equals(localName)) {
+ String sourceAtt = atts.getValue(SRC_ATTR);
+
+ if (null != sourceAtt && !"".equals(sourceAtt)) {
+ try {
+ URL source = this.createSource(sourceAtt);
+
+ XMLReader xmlReader = XMLReaderFactory.createXMLReader();
+ xmlReader.setContentHandler(this.getXMLConsumer());
+ IncludeXMLConsumer includeXMLConsumer = new IncludeXMLConsumer(this.getXMLConsumer());
+ xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", includeXMLConsumer);
+
+ BufferedInputStream inputStream = new BufferedInputStream(source.openStream());
+ xmlReader.parse(new InputSource(inputStream));
+
+ return;
+ } catch (IOException e) {
+ String message = "Can't read from URL " + sourceAtt;
+ this.logger.error(message, e);
+ throw new ProcessingException(message, e);
+ }
+ } else {
+ String message = "The <include> element must contain a 'src' attribute that contains a URL.";
+ this.logger.error(message);
+ throw new ProcessingException(message);
+ }
+ } else {
+ super.startElement(uri, localName, name, atts);
+ }
+ }
+
+ private URL createSource(String sourceAtt) {
+ try {
+ URL source = null;
+ if (sourceAtt.contains(":")) {
+ source = new URL(sourceAtt);
+ } else {
+ source = new URL(this.baseUrl, sourceAtt);
+ }
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Including source: " + source);
+ }
+
+ return source;
+ } catch (MalformedURLException e) {
+ String message = "Can't parse URL " + sourceAtt;
+ this.logger.error(message, e);
+ throw new ProcessingException(message, e);
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ if (INCLUDE_NS.equals(uri) && INCLUDE_EL.equals(localName)) {
+ return;
+ }
+ super.endElement(uri, localName, name);
+ }
+
+ @Override
+ public void setConfiguration(Map<String, ? extends Object> parameters) {
+ this.setBaseUrl((URL) parameters.get("baseUrl"));
+ }
+
+ public void setBaseUrl(URL baseUrl) {
+ this.baseUrl = baseUrl;
+ }
+
+ @Override
+ public String toString() {
+ return StringRepresentation.buildString(this, "baseUrl=" + this.baseUrl);
+ }
+}
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/component/IncludeTransformer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java?rev=667553&view=auto
==============================================================================
--- cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java (added)
+++ cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java Fri Jun 13 07:23:14 2008
@@ -0,0 +1,198 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.corona.pipeline.util;
+
+import org.apache.cocoon.corona.pipeline.component.XMLConsumer;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * A special purpose <code>XMLConsumer</code> which can:
+ * <ul>
+ * <li>Trim empty characters if {@link #setIgnoreEmptyCharacters(boolean) ignoreEmptyCharacters} is set.
+ * <li>Ignore root element if {@link #setIgnoreRootElement(boolean) ignoreRootElement} is set.
+ * <li>Ignore startDocument, endDocument events.
+ * <li>Ignore startDTD, endDTD, and all comments within DTD.
+ * </ul>
+ *
+ * <p>
+ * It is more complicated version of {@link EmbeddedXMLPipe} which, except being used to include other files into the
+ * SAX events stream, can perform optional operations described above.
+ * </p>
+ *
+ * @see EmbeddedXMLPipe
+ * @version $Id$
+ */
+public class IncludeXMLConsumer implements XMLConsumer {
+
+ private final ContentHandler contentHandler;
+ private final LexicalHandler lexicalHandler;
+
+ private boolean ignoreEmptyCharacters;
+ private boolean ignoreRootElement;
+ private int ignoreRootElementCount;
+ private boolean inDTD;
+
+ /**
+ * Constructor
+ */
+ public IncludeXMLConsumer(XMLConsumer consumer) {
+ this(consumer, consumer);
+ }
+
+ /**
+ * Constructor
+ */
+ public IncludeXMLConsumer(ContentHandler contentHandler) {
+ this(contentHandler, contentHandler instanceof LexicalHandler ? (LexicalHandler) contentHandler : null);
+ }
+
+ /**
+ * Constructor
+ */
+ public IncludeXMLConsumer(ContentHandler contentHandler, LexicalHandler lexicalHandler) {
+ this.contentHandler = contentHandler;
+ this.lexicalHandler = lexicalHandler;
+ }
+
+ /**
+ * Control SAX event handling. If set to <code>true</code> all empty characters events are ignored. The default is
+ * <code>false</code>.
+ */
+ public void setIgnoreEmptyCharacters(boolean value) {
+ this.ignoreEmptyCharacters = value;
+ }
+
+ /**
+ * Control SAX event handling. If set to <code>true</code> the root element is ignored. The default is
+ * <code>false</code>.
+ */
+ public void setIgnoreRootElement(boolean value) {
+ this.ignoreRootElement = value;
+ this.ignoreRootElementCount = 0;
+ }
+
+ //
+ // ContentHandler interface
+ //
+
+ public void setDocumentLocator(Locator loc) {
+ this.contentHandler.setDocumentLocator(loc);
+ }
+
+ public void startDocument() throws SAXException {
+ // Ignored
+ }
+
+ public void endDocument() throws SAXException {
+ // Ignored
+ }
+
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ this.contentHandler.startPrefixMapping(prefix, uri);
+ }
+
+ public void endPrefixMapping(String prefix) throws SAXException {
+ this.contentHandler.endPrefixMapping(prefix);
+ }
+
+ public void startElement(String uri, String local, String qName, Attributes attr) throws SAXException {
+ if (this.ignoreRootElement == false || this.ignoreRootElementCount > 0) {
+ this.contentHandler.startElement(uri, local, qName, attr);
+ }
+ this.ignoreRootElementCount++;
+ }
+
+ public void endElement(String uri, String local, String qName) throws SAXException {
+ this.ignoreRootElementCount--;
+ if (!this.ignoreRootElement || this.ignoreRootElementCount > 0) {
+ this.contentHandler.endElement(uri, local, qName);
+ }
+ }
+
+ public void characters(char[] ch, int start, int end) throws SAXException {
+ if (this.ignoreEmptyCharacters) {
+ String text = new String(ch, start, end).trim();
+ if (text.length() > 0) {
+ this.contentHandler.characters(text.toCharArray(), 0, text.length());
+ }
+ } else {
+ this.contentHandler.characters(ch, start, end);
+ }
+ }
+
+ public void ignorableWhitespace(char[] ch, int start, int end) throws SAXException {
+ if (!this.ignoreEmptyCharacters) {
+ this.contentHandler.ignorableWhitespace(ch, start, end);
+ }
+ }
+
+ public void processingInstruction(String name, String value) throws SAXException {
+ this.contentHandler.processingInstruction(name, value);
+ }
+
+ public void skippedEntity(String ent) throws SAXException {
+ this.contentHandler.skippedEntity(ent);
+ }
+
+ //
+ // LexicalHandler interface
+ //
+
+ public void startDTD(String name, String public_id, String system_id) throws SAXException {
+ // Ignored
+ this.inDTD = true;
+ }
+
+ public void endDTD() throws SAXException {
+ // Ignored
+ this.inDTD = false;
+ }
+
+ public void startEntity(String name) throws SAXException {
+ if (this.lexicalHandler != null) {
+ this.lexicalHandler.startEntity(name);
+ }
+ }
+
+ public void endEntity(String name) throws SAXException {
+ if (this.lexicalHandler != null) {
+ this.lexicalHandler.endEntity(name);
+ }
+ }
+
+ public void startCDATA() throws SAXException {
+ if (this.lexicalHandler != null) {
+ this.lexicalHandler.startCDATA();
+ }
+ }
+
+ public void endCDATA() throws SAXException {
+ if (this.lexicalHandler != null) {
+ this.lexicalHandler.endCDATA();
+ }
+ }
+
+ public void comment(char ary[], int start, int length) throws SAXException {
+ if (!this.inDTD && this.lexicalHandler != null) {
+ this.lexicalHandler.comment(ary, start, length);
+ }
+ }
+}
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/whiteboard/corona/trunk/corona-pipeline/src/main/java/org/apache/cocoon/corona/pipeline/util/IncludeXMLConsumer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/GenerateNode.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/GenerateNode.java?rev=667553&r1=667552&r2=667553&view=diff
==============================================================================
--- cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/GenerateNode.java (original)
+++ cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/GenerateNode.java Fri Jun 13 07:23:14 2008
@@ -30,14 +30,14 @@
private static final String GENERATOR_CATEGORY = "generator:";
@Parameter
- private String type = "file"; // "file" is the default type
+ private final String type = "file"; // "file" is the default type
@Parameter
private String src;
/**
* {@inheritDoc}
- *
+ *
* @see org.apache.cocoon.corona.sitemap.node.AbstractSitemapNode#invoke(org.apache.cocoon.corona.sitemap.Invocation)
*/
@Override
@@ -48,6 +48,9 @@
parameters.put("source", invocation.resolve(resolvedSource));
}
+ // set the baseUrl
+ parameters.put("baseUrl", invocation.resolve(""));
+
// install the component
invocation.installComponent(GENERATOR_CATEGORY + this.type, parameters);
@@ -57,7 +60,7 @@
/**
* {@inheritDoc}
- *
+ *
* @see org.apache.cocoon.corona.sitemap.node.AbstractSitemapNode#toString()
*/
@Override
Modified: cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/TransformNode.java
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/TransformNode.java?rev=667553&r1=667552&r2=667553&view=diff
==============================================================================
--- cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/TransformNode.java (original)
+++ cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/java/org/apache/cocoon/corona/sitemap/node/TransformNode.java Fri Jun 13 07:23:14 2008
@@ -42,10 +42,14 @@
*/
@Override
public InvocationResult invoke(final Invocation invocation) {
- Map<String, Object> parameters = new HashMap<String, Object>(this.getParameters());
+ final Map<String, Object> parameters = new HashMap<String, Object>(this.getParameters());
if (this.src != null) {
parameters.put("source", invocation.resolve(this.src));
}
+
+ // set the baseUrl
+ parameters.put("baseUrl", invocation.resolve(""));
+
// install the component
invocation.installComponent(TRANSFORMER_CATEGORY + this.type, parameters);
Modified: cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/resources/META-INF/cocoon/spring/corona-pipeline-component.xml
URL: http://svn.apache.org/viewvc/cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/resources/META-INF/cocoon/spring/corona-pipeline-component.xml?rev=667553&r1=667552&r2=667553&view=diff
==============================================================================
--- cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/resources/META-INF/cocoon/spring/corona-pipeline-component.xml (original)
+++ cocoon/whiteboard/corona/trunk/corona-sitemap/src/main/resources/META-INF/cocoon/spring/corona-pipeline-component.xml Fri Jun 13 07:23:14 2008
@@ -55,6 +55,8 @@
<bean name="transformer:xslt" class="org.apache.cocoon.corona.pipeline.component.XSLTTransformer" scope="prototype" />
+ <bean name="transformer:include" class="org.apache.cocoon.corona.pipeline.component.IncludeTransformer" scope="prototype" />
+
<bean name="transformer:cleaning" class="org.apache.cocoon.corona.pipeline.component.CleaningTransformer" scope="prototype" />
</beans>