You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by di...@apache.org on 2001/04/18 18:57:01 UTC
cvs commit: xml-cocoon/src/org/apache/cocoon/reading AbstractReader.java ResourceReader.java
dims 01/04/18 09:57:00
Modified: src/org/apache/cocoon/caching Tag: xml-cocoon2
ComponentCacheKey.java
src/org/apache/cocoon/components/pipeline Tag: xml-cocoon2
CachingStreamPipeline.java
src/org/apache/cocoon/reading Tag: xml-cocoon2
AbstractReader.java ResourceReader.java
Log:
- Added Caching for Readers too.
Revision Changes Path
No revision
No revision
1.1.2.3 +2 -1 xml-cocoon/src/org/apache/cocoon/caching/Attic/ComponentCacheKey.java
Index: ComponentCacheKey.java
===================================================================
RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/caching/Attic/ComponentCacheKey.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- ComponentCacheKey.java 2001/04/17 10:32:52 1.1.2.2
+++ ComponentCacheKey.java 2001/04/18 16:56:43 1.1.2.3
@@ -16,13 +16,14 @@
* is unique inside the component space.
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
- * @version CVS $Revision: 1.1.2.2 $ $Date: 2001/04/17 10:32:52 $
+ * @version CVS $Revision: 1.1.2.3 $ $Date: 2001/04/18 16:56:43 $
*/
public final class ComponentCacheKey {
public static final int ComponentType_Generator = 1;
public static final int ComponentType_Transformer = 2;
public static final int ComponentType_Serializer = 3;
+ public static final int ComponentType_Reader = 4;
private String toStringValue;
No revision
No revision
1.1.2.3 +139 -1 xml-cocoon/src/org/apache/cocoon/components/pipeline/Attic/CachingStreamPipeline.java
Index: CachingStreamPipeline.java
===================================================================
RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/components/pipeline/Attic/CachingStreamPipeline.java,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- CachingStreamPipeline.java 2001/04/17 15:33:02 1.1.2.2
+++ CachingStreamPipeline.java 2001/04/18 16:56:49 1.1.2.3
@@ -13,6 +13,9 @@
import java.util.Iterator;
import java.util.Map;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.SAXException;
+
import org.apache.avalon.Component;
import org.apache.avalon.ComponentManager;
import org.apache.avalon.ComponentManagerException;
@@ -43,13 +46,16 @@
* </ul>
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
- * @version CVS $Revision: 1.1.2.2 $ $Date: 2001/04/17 15:33:02 $
+ * @version CVS $Revision: 1.1.2.3 $ $Date: 2001/04/18 16:56:49 $
*/
public final class CachingStreamPipeline extends AbstractStreamPipeline {
/** The role name of the serializer */
private String serializerRole;
+ /** The role name of the serializer */
+ private String readerRole;
+
/** The cache for the responses */
private StreamCache streamCache;
@@ -73,6 +79,137 @@
this.serializerRole = role;
}
+ /** Set the Reader.
+ */
+ public void setReader (String role, String source, Parameters param, String mimeType)
+ throws Exception {
+ super.setReader(role, source, param, mimeType);
+ this.readerRole = role;
+ }
+
+ /** Process the pipeline using a reader.
+ * @throws ProcessingException if
+ */
+ protected boolean processReader(Environment environment)
+ throws ProcessingException {
+
+ try
+ {
+ this.reader.setup((EntityResolver) environment,environment.getObjectModel(),readerSource,readerParam);
+ String mimeType = this.reader.getMimeType();
+
+ mimeType = this.reader.getMimeType();
+ if ( mimeType != null ) {
+ environment.setContentType(mimeType);
+ } else if ( readerMimeType != null ) {
+ environment.setContentType(this.readerMimeType);
+ } else {
+ environment.setContentType(this.sitemapReaderMimeType);
+ }
+ } catch (SAXException e){
+ getLogger().debug("SAXException in ProcessReader", e);
+
+ throw new ProcessingException(
+ "Failed to execute pipeline.",
+ e
+ );
+ } catch (IOException e){
+ getLogger().debug("IOException in ProcessReader", e);
+
+ throw new ProcessingException(
+ "Failed to execute pipeline.",
+ e
+ );
+ }
+
+ try {
+ boolean usedCache = false;
+ OutputStream outputStream;
+ PipelineCacheKey pcKey = null;
+ Map validityObjects = new HashMap();
+
+ outputStream = environment.getOutputStream();
+
+ // test if serializer and event pipeline are cacheable
+ long readerKey = 0;
+ CacheValidity readerValidity = null;
+ if (this.reader instanceof Cacheable
+ && (readerKey = ((Cacheable)this.reader).generateKey()) != 0
+ && (readerValidity = ((Cacheable)this.reader).generateValidity()) != null ){
+
+ // response is cacheable, build the key
+ ComponentCacheKey ccKey;
+ pcKey = new PipelineCacheKey();
+ ccKey = new ComponentCacheKey(ComponentCacheKey.ComponentType_Reader,
+ this.readerRole,
+ readerKey);
+ validityObjects.put(ccKey, readerValidity);
+ pcKey.addKey(ccKey);
+
+ // now we have the key to get the cached object
+ CachedStreamObject cachedObject = (CachedStreamObject)this.streamCache.get(pcKey);
+
+ if (cachedObject != null) {
+ getLogger().debug("Found cached response.");
+
+ Iterator validityIterator = validityObjects.keySet().iterator();
+ ComponentCacheKey validityKey;
+ boolean valid = true;
+ while (validityIterator.hasNext() == true && valid == true) {
+ validityKey = (ComponentCacheKey)validityIterator.next();
+ valid = cachedObject.isValid(validityKey, (CacheValidity)validityObjects.get(validityKey));
+ }
+ if (valid == true) {
+ getLogger().debug("Using valid cached content.");
+
+ usedCache = true;
+ byte[] response = cachedObject.getResponse();
+ outputStream.write(response);
+ if (response.length != 0) {
+ environment.setContentLength(response.length);
+ }
+ } else {
+ getLogger().debug("Cached content is invalid.");
+
+ // remove invalid cached object
+ this.streamCache.remove(pcKey);
+ cachedObject = null;
+ }
+ }
+ if (cachedObject == null) {
+ getLogger().debug("Caching content for further requests.");
+ outputStream = new CachingOutputStream(outputStream);
+ }
+ }
+
+ if (usedCache == false) {
+
+ this.reader.setOutputStream(outputStream);
+ int length = this.reader.generate();
+ if (length != 0) {
+ environment.setContentLength(length);
+ }
+
+ // store the response
+ if (pcKey != null) {
+ this.streamCache.store(pcKey,
+ new CachedStreamObject(validityObjects,
+ ((CachingOutputStream)outputStream).getContent()));
+ }
+ }
+
+ } catch ( Exception e ) {
+ getLogger().debug("IOException in ProcessReader", e);
+
+ throw new ProcessingException(
+ "Failed to execute pipeline.",
+ e
+ );
+ }
+
+ return true;
+ }
+
/**
* Process the request.
*/
@@ -170,6 +307,7 @@
}
} catch ( Exception e ) {
+ getLogger().debug("Exception in process", e);
throw new ProcessingException(
"Failed to execute pipeline.",
e
No revision
No revision
1.1.2.15 +7 -2 xml-cocoon/src/org/apache/cocoon/reading/Attic/AbstractReader.java
Index: AbstractReader.java
===================================================================
RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/reading/Attic/AbstractReader.java,v
retrieving revision 1.1.2.14
retrieving revision 1.1.2.15
diff -u -r1.1.2.14 -r1.1.2.15
--- AbstractReader.java 2001/04/18 12:06:01 1.1.2.14
+++ AbstractReader.java 2001/04/18 16:56:53 1.1.2.15
@@ -9,10 +9,14 @@
import java.io.OutputStream;
import java.io.BufferedOutputStream;
+import java.io.IOException;
import java.util.Map;
import org.xml.sax.EntityResolver;
+import org.xml.sax.SAXException;
+import org.apache.cocoon.ProcessingException;
+
import org.apache.avalon.configuration.Parameters;
import org.apache.avalon.AbstractLoggable;
import org.apache.avalon.Recyclable;
@@ -20,7 +24,7 @@
/**
*
* @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
- * @version CVS $Revision: 1.1.2.14 $ $Date: 2001/04/18 12:06:01 $
+ * @version CVS $Revision: 1.1.2.15 $ $Date: 2001/04/18 16:56:53 $
*/
public abstract class AbstractReader extends AbstractLoggable implements Reader, Recyclable {
/** The current <code>EntityResolver</code>. */
@@ -38,7 +42,8 @@
* Set the <code>EntityResolver</code> the object model <code>Map</code>,
* the source and sitemap <code>Parameters</code> used to process the request.
*/
- public void setup(EntityResolver resolver, Map objectModel, String src, Parameters par) {
+ public void setup(EntityResolver resolver, Map objectModel, String src, Parameters par)
+ throws ProcessingException, SAXException, IOException {
this.resolver=resolver;
this.objectModel=objectModel;
this.source=src;
1.1.2.28 +50 -2 xml-cocoon/src/org/apache/cocoon/reading/Attic/ResourceReader.java
Index: ResourceReader.java
===================================================================
RCS file: /home/cvs/xml-cocoon/src/org/apache/cocoon/reading/Attic/ResourceReader.java,v
retrieving revision 1.1.2.27
retrieving revision 1.1.2.28
diff -u -r1.1.2.27 -r1.1.2.28
--- ResourceReader.java 2001/04/18 12:06:02 1.1.2.27
+++ ResourceReader.java 2001/04/18 16:56:55 1.1.2.28
@@ -18,7 +18,11 @@
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Date;
+import java.util.Map;
+import org.apache.cocoon.caching.Cacheable;
+import org.apache.cocoon.caching.CacheValidity;
+import org.apache.cocoon.caching.TimeStampCacheValidity;
import org.apache.cocoon.Constants;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
@@ -27,17 +31,21 @@
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.Context;
+import org.apache.cocoon.util.HashUtil;
import org.apache.avalon.ComponentManager;
import org.apache.avalon.Composer;
import org.apache.avalon.Component;
+import org.apache.avalon.component.ComponentException;
+import org.apache.avalon.configuration.Parameters;
+import org.xml.sax.EntityResolver;
import org.xml.sax.SAXException;
/**
*
* @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
- * @version CVS $Revision: 1.1.2.27 $ $Date: 2001/04/18 12:06:02 $
+ * @version CVS $Revision: 1.1.2.28 $ $Date: 2001/04/18 16:56:55 $
*
* The <code>ResourceReader</code> component is used to serve binary data
* in a sitemap pipeline. It makes use of HTTP Headers to determine if
@@ -53,12 +61,52 @@
* </dd>
* </dl>
*/
-public class ResourceReader extends AbstractReader implements Composer {
+public class ResourceReader extends AbstractReader
+ implements Composer, Cacheable {
private ComponentManager manager;
+ /** The system ID of the input source */
+ private String systemID;
+
+ /**
+ * Setup the file generator.
+ */
+ public void setup(EntityResolver resolver, Map objectModel, String src, Parameters par)
+ throws ProcessingException, SAXException, IOException {
+ super.setup(resolver, objectModel, src, par);
+ this.systemID = resolver.resolveEntity(null, super.source).getSystemId();
+ }
+
public void compose (ComponentManager manager) {
this.manager = manager;
+ }
+
+ /**
+ * Generate the unique key.
+ * This key must be unique inside the space of this component.
+ *
+ * @return The generated key hashes the src
+ */
+ public long generateKey() {
+ if (this.systemID.startsWith("file:") == true) {
+ return HashUtil.hash(this.systemID);
+ }
+ return 0;
+ }
+
+ /**
+ * Generate the validity object.
+ *
+ * @return The generated validity object or <code>null</code> if the
+ * component is currently not cacheable.
+ */
+ public CacheValidity generateValidity() {
+ if (this.systemID.startsWith("file:") == true) {
+ File xmlFile = new File(this.systemID.substring("file:".length()));
+ return new TimeStampCacheValidity(xmlFile.lastModified());
+ }
+ return null;
}
/**
----------------------------------------------------------------------
In case of troubles, e-mail: webmaster@xml.apache.org
To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: cocoon-cvs-help@xml.apache.org