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