unico       2004/03/23 08:28:54

  Modified:    
src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl
                        CachingSourceFactory.java CachingSource.java
                        TraversableCachingSource.java UpdateTarget.java
                        DelayRefresher.java
               src/blocks/scratchpad/conf delay-refresher.xconf
  Log:
  factor common code used by updater, fix asynchronic update for traversables
  
  Revision  Changes    Path
  1.7       +6 -12     
cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachingSourceFactory.java
  
  Index: CachingSourceFactory.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachingSourceFactory.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CachingSourceFactory.java 23 Mar 2004 12:47:22 -0000      1.6
  +++ CachingSourceFactory.java 23 Mar 2004 16:28:54 -0000      1.7
  @@ -271,7 +271,7 @@
               while (names.hasNext()) {
                   String name = (String) names.next();
                   if (name.startsWith("cocoon:")) {
  -                    
params.setParameter(name.substring("cocoon:".length()),sp.getParameter(name));
  +                    params.setParameter(name.substring("cocoon:".length()), 
sp.getParameter(name));
                       sp.removeParameter(name);
                   }
               }
  @@ -281,12 +281,12 @@
               }
           }
           
  -        final String cacheName = params.getParameter("cache-name", null);
           int expires = params.getParameterAsInteger("cache-expires", -1);
           if (expires == -1) {
               expires = this.defaultExpires;
               params.setParameter("cache-expires", 
String.valueOf(this.defaultExpires));
           }
  +        params.setParameter("cache-role", this.cacheRole);
           
           final Source wrappedSource = this.resolver.resolveURI(uri);
           CachingSource source;
  @@ -294,29 +294,23 @@
               source = new TraversableCachingSource(scheme,
                                                     location,
                                                     (TraversableSource) 
wrappedSource,
  -                                                  cacheName,
  +                                                  params,
                                                     expires,
  -                                                  parameters,
                                                     this.async);
           }
           else {
               source = new CachingSource(scheme,
                                          location,
                                          wrappedSource,
  -                                       cacheName,
  +                                       params,
                                          expires,
  -                                       parameters,
                                          this.async);
           }
   
  -        if (this.async) {
  -            // schedule it with the refresher
  -            this.refresher.refresh(source.getCacheKey(), uri, 
this.cacheRole, params);
  -        }
  -
           // set the required components directly for speed
           source.cache = this.cache;
           source.resolver = this.resolver;
  +        source.refresher = this.refresher;
   
           ContainerUtil.enableLogging(source, this.getLogger());
           try {
  
  
  
  1.8       +115 -81   
cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachingSource.java
  
  Index: CachingSource.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachingSource.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- CachingSource.java        22 Mar 2004 17:38:25 -0000      1.7
  +++ CachingSource.java        23 Mar 2004 16:28:54 -0000      1.8
  @@ -20,11 +20,12 @@
   import java.io.IOException;
   import java.io.InputStream;
   import java.io.Serializable;
  -import java.net.MalformedURLException;
  -import java.util.Map;
  +import java.util.Collection;
  +import java.util.Iterator;
   
   import org.apache.avalon.framework.activity.Initializable;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
  +import org.apache.avalon.framework.parameters.Parameters;
   import org.apache.avalon.framework.service.ServiceException;
   import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.avalon.framework.service.Serviceable;
  @@ -41,6 +42,7 @@
   import org.apache.excalibur.source.SourceNotFoundException;
   import org.apache.excalibur.source.SourceResolver;
   import org.apache.excalibur.source.SourceValidity;
  +import org.apache.excalibur.source.TraversableSource;
   import org.apache.excalibur.source.impl.validity.ExpiresValidity;
   import org.apache.excalibur.source.impl.validity.TimeStampValidity;
   import org.apache.excalibur.xml.sax.XMLizable;
  @@ -83,6 +85,9 @@
       /** The current cache */
       protected Cache cache;
       
  +    /** The refresher for asynchronous updates */
  +    protected Refresher refresher;
  +    
       /** The source object for the real content */
       protected Source source;
       
  @@ -95,9 +100,6 @@
       /** The full location string */
       final protected String uri;
       
  -    /** The wrapped source uri */
  -    final protected String sourceURI;
  -    
       /** The used protocol */
       final protected String protocol;
       
  @@ -107,11 +109,8 @@
       /** number of seconds before cached object becomes invalid */
       final protected int expires;
       
  -    /** key name extension */
  -    final protected String cacheName;
  -    
  -    /** additional source parameters */
  -    final protected Map parameters;
  +    /** Parameters */
  +    final protected Parameters parameters;
       
       /** asynchronic refresh strategy ? */
       final protected boolean async;
  @@ -122,39 +121,24 @@
       public CachingSource(final String protocol,
                            final String uri,
                            final Source source,
  -                         final String cacheName,
  -                         final int expires,
  -                         final Map parameters,
  -                         final boolean async) {
  -        this(protocol, uri, source.getURI(), cacheName, expires, parameters, 
async);
  -        this.source = source;
  -    }
  -    
  -    /**
  -     * Construct a new object.
  -     */
  -    public CachingSource(final String protocol,
  -                         final String uri,
  -                         final String sourceURI,
  -                         final String cacheName,
  +                         final Parameters parameters,
                            final int expires,
  -                         final Map parameters,
                            final boolean async) {
           this.protocol = protocol;
           this.uri = uri;
  -        this.sourceURI = sourceURI;
  -        this.cacheName = cacheName;
  +        this.source = source;
           this.expires = expires;
  -        this.parameters = parameters;
           this.async = async;
  +        this.parameters = parameters;
           
  -        String key = "source:" + sourceURI;
  +        String key = "source:" + source.getURI();
  +        String cacheName = parameters.getParameter("cache-name", null);
           if (cacheName != null) {
               key += ":" + cacheName;
           }
           this.cacheKey = new SimpleCacheKey(key, false);
       }
  -    
  +        
       /**
        * Set the ServiceManager.
        */
  @@ -181,6 +165,13 @@
                   }
               }
           }
  +        if (this.async && expires > 0) {
  +            // schedule it with the refresher
  +            this.refresher.refresh(this.cacheKey,
  +                                   getSourceURI(),
  +                                   
this.parameters.getParameter("cache-role", null),
  +                                   this.parameters);
  +        }
       }
       
       /**
  @@ -210,7 +201,7 @@
               storeResponse = true;
           }
           if (response.getExtra() == null || refresh) {
  -            response.setExtra(readMeta());
  +            response.setExtra(readMeta(this.source));
               this.freshMeta = true;
           }
           if (storeResponse) {
  @@ -239,10 +230,10 @@
               storeResponse = true;
           }
           if (response.getBinaryResponse() == null || refresh) {
  -            response.setBinaryResponse(readBinaryResponse());
  +            response.setBinaryResponse(readBinaryResponse(this.source));
               if (!this.freshMeta) {
                   /* always refresh meta in this case */
  -                response.setExtra(readMeta());
  +                response.setExtra(readMeta(this.source));
               }
           }
           if (storeResponse) {
  @@ -273,10 +264,11 @@
               storeResponse = true;
           }
           if (response.getXMLResponse() == null || refresh) {
  -            response.setXMLResponse(readXMLResponse());
  +            byte[] binary = response.getBinaryResponse();
  +            response.setXMLResponse(readXMLResponse(this.source, binary, 
this.manager));
               if (!this.freshMeta) {
                   /* always refresh meta in this case */
  -                response.setExtra(readMeta());
  +                response.setExtra(readMeta(this.source));
               }
           }
           if (storeResponse) {
  @@ -358,12 +350,7 @@
        * @see org.apache.excalibur.source.Source#exists()
        */
       public boolean exists() {
  -     try {
  -                     return this.getSource().exists();
  -     }
  -     catch (IOException e) {
  -             return true;
  -     }
  +             return this.source.exists();
       }
       
       /**
  @@ -386,11 +373,7 @@
        */
       public void refresh() {
           this.response = null;
  -        try {
  -            getSource().refresh();
  -        }
  -        catch (IOException ignore) {
  -        }
  +        this.source.refresh();
       }
       
       // ---------------------------------------------------- XMLizable 
implementation
  @@ -426,17 +409,7 @@
        * Return the uri of the cached source.
        */
       protected String getSourceURI() {
  -        return this.sourceURI;
  -    }
  -
  -    /**
  -     * Return the cached source itself.
  -     */
  -    protected Source getSource() throws MalformedURLException, IOException {
  -        if (this.source == null) {
  -            this.source = resolver.resolveURI(sourceURI, null, parameters);
  -        }
  -        return this.source;
  +        return this.source.getURI();
       }
       
       /**
  @@ -461,25 +434,22 @@
         * @throws IOException
         * @throws CascadingIOException
         */
  -     protected byte[] readXMLResponse() throws SAXException, IOException, 
CascadingIOException {
  +     protected static byte[] readXMLResponse(Source source, byte[] binary, 
ServiceManager manager) 
  +    throws SAXException, IOException, CascadingIOException {
           XMLSerializer serializer = null;
           XMLizer xmlizer = null;
           byte[] result = null;
                try {
  -                 serializer = (XMLSerializer) 
this.manager.lookup(XMLSerializer.ROLE);
  +                 serializer = (XMLSerializer) 
manager.lookup(XMLSerializer.ROLE);
               
  -            if (this.source instanceof XMLizable) {
  -                ((XMLizable) this.source).toSAX(serializer);
  +            if (source instanceof XMLizable) {
  +                ((XMLizable) source).toSAX(serializer);
               }
               else {
  -                             byte[] binary = null;
  -             if (this.response != null) {
  -                     binary = this.response.getBinaryResponse();
  -             }
                   if (binary == null) {
  -                    binary = readBinaryResponse();
  +                    binary = readBinaryResponse(source);
                   }
  -                final String mimeType = this.source.getMimeType();
  +                final String mimeType = source.getMimeType();
                   if (mimeType != null) {
                       xmlizer = (XMLizer) manager.lookup(XMLizer.ROLE);
                       xmlizer.toSAX(new ByteArrayInputStream(binary),
  @@ -490,10 +460,10 @@
               }
                    result = (byte[]) serializer.getSAXFragment();
                } catch (ServiceException se) {
  -                 throw new CascadingIOException("Missing service 
dependencyj.", se);
  +                 throw new CascadingIOException("Missing service 
dependency.", se);
                } finally {
  -            this.manager.release(xmlizer);
  -                 this.manager.release(serializer);
  +            manager.release(xmlizer);
  +                 manager.release(serializer);
                }
                return result;
        }
  @@ -505,10 +475,11 @@
         * @throws IOException
         * @throws SourceNotFoundException
         */
  -     protected byte[] readBinaryResponse() throws IOException, 
SourceNotFoundException {
  +     protected static byte[] readBinaryResponse(Source source) 
  +    throws IOException, SourceNotFoundException {
           final ByteArrayOutputStream baos = new ByteArrayOutputStream();
                final byte[] buffer = new byte[2048];
  -             final InputStream inputStream = this.source.getInputStream();
  +             final InputStream inputStream = source.getInputStream();
                int length;
                while ((length = inputStream.read(buffer)) > -1) {
                    baos.write(buffer, 0, length);
  @@ -524,14 +495,47 @@
        * @return source meta data
        * @throws IOException
        */
  -    protected SourceMeta readMeta() throws IOException {
  -        SourceMeta meta = new SourceMeta();
  -        long lastModified = getSource().getLastModified();
  -        if (lastModified <= 0) {
  -            lastModified = System.currentTimeMillis();
  +    protected static SourceMeta readMeta(Source source) throws IOException {
  +        SourceMeta meta;
  +        
  +        if (source instanceof TraversableSource) {
  +            
  +            final TraversableSourceMeta tmeta = new TraversableSourceMeta();
  +            final TraversableSource tsource = (TraversableSource) source;
  +            
  +            tmeta.setName(tsource.getName());
  +            tmeta.setIsCollection(tsource.isCollection());
  +            
  +            if (tmeta.isCollection()) {
  +                final Collection children = tsource.getChildren();
  +                if (children != null) {
  +                    final String[] names = new String[children.size()];
  +                    final Iterator iter = children.iterator();
  +                    int count = 0;
  +                    while(iter.hasNext()) {
  +                        TraversableSource child = (TraversableSource) 
iter.next();
  +                        names[count] = child.getName();
  +                        count++;
  +                    }
  +                    tmeta.setChildren(names);
  +                }
  +            }
  +            
  +            meta = tmeta;
           }
  -        meta.setLastModified(lastModified);
  -        meta.setMimeType(getSource().getMimeType());
  +        else {
  +            meta = new SourceMeta();
  +        }
  +        
  +        final long lastModified = source.getLastModified();
  +        if (lastModified > 0) {
  +            meta.setLastModified(lastModified);
  +        }
  +        else {
  +            meta.setLastModified(System.currentTimeMillis());
  +        }
  +        meta.setMimeType(source.getMimeType());
  +        
           return meta;
       }
       
  @@ -568,6 +572,36 @@
               m_exists = exists;
           }
           
  +    }
  +    
  +    protected static class TraversableSourceMeta extends SourceMeta {
  +        private String   m_name;
  +        private boolean  m_isCollection;
  +        private String[] m_children;
  +        
  +        protected String getName() {
  +            return m_name;
  +        }
  +        
  +        protected void setName(String name) {
  +            m_name = name;
  +        }
  +        
  +        protected boolean isCollection() {
  +            return m_isCollection;
  +        }
  +        
  +        protected void setIsCollection(boolean isCollection) {
  +            m_isCollection = isCollection;
  +        }
  +        
  +        protected String[] getChildren() {
  +            return m_children;
  +        }
  +        
  +        protected void setChildren(String[] children) {
  +            m_children = children;
  +        }
       }
   
   }
  
  
  
  1.3       +26 -140   
cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/TraversableCachingSource.java
  
  Index: TraversableCachingSource.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/TraversableCachingSource.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TraversableCachingSource.java     23 Mar 2004 12:46:38 -0000      1.2
  +++ TraversableCachingSource.java     23 Mar 2004 16:28:54 -0000      1.3
  @@ -16,13 +16,11 @@
   package org.apache.cocoon.components.source.impl;
   
   import java.io.IOException;
  -import java.net.MalformedURLException;
   import java.util.ArrayList;
   import java.util.Collection;
  -import java.util.Iterator;
  -import java.util.Map;
   
   import org.apache.avalon.framework.container.ContainerUtil;
  +import org.apache.avalon.framework.parameters.Parameters;
   import org.apache.excalibur.source.Source;
   import org.apache.excalibur.source.SourceException;
   import org.apache.excalibur.source.TraversableSource;
  @@ -31,33 +29,17 @@
    * Traversable version of [EMAIL PROTECTED] 
org.apache.cocoon.components.source.impl.CachingSource}.
    */
   public class TraversableCachingSource extends CachingSource implements 
TraversableSource {
  -
  -     // the Source children in case of a collection
  -    private TraversableSource[] m_children;
       
  -    public TraversableCachingSource(String protocol,
  -                                    String uri,
  -                                    String sourceURI,
  -                                    String cacheName,
  -                                    int expires,
  -                                    Map parameters,
  -                                    boolean async) {
  -        super(protocol, uri, sourceURI, cacheName, expires, parameters, 
async);
  -    }
  +    private TraversableSource tsource;
       
       public TraversableCachingSource(String protocol,
                                       String location,
                                       TraversableSource source,
  -                                    String cacheName,
  +                                    Parameters params,
                                       int expires,
  -                                    Map parameters,
                                       boolean async) {
  -        super(protocol, location, source, cacheName, expires, parameters, 
async);
  -    }
  -    
  -    public void dispose() {
  -             super.dispose();
  -             m_children = null;
  +        super(protocol, location, source, params, expires, async);
  +        this.tsource = source;
       }
       
       // ---------------------------------------------------- 
TraversableSource implementation
  @@ -94,8 +76,10 @@
   
       public Source getChild(String name) throws SourceException {
           
  +        Source child;
           try {
               initMetaResponse(false);
  +            child = this.tsource.getChild(name);
           }
           catch (SourceException e) {
               throw e;
  @@ -108,7 +92,7 @@
               throw new SourceException("Source is not a collection");
           }
           
  -        return createChildSource(name);
  +        return createSource(getChildURI(super.uri, name), child);
       }
   
       public Collection getChildren() throws SourceException {
  @@ -126,18 +110,19 @@
           if (!isCollection()) {
               throw new SourceException("Source is not a collection");
           }
  -
  +        
           final Collection result = new ArrayList();
  -        if (m_children != null) {
  -            for (int i = 0; i < m_children.length; i++) {
  -                result.add(createChildSource(m_children[i]));
  +        final TraversableSourceMeta meta = (TraversableSourceMeta) 
super.response.getExtra();
  +        final String[] children = meta.getChildren();
  +        for (int i = 0; i < children.length; i++) {
  +            Source child;
  +            try {
  +                child = this.tsource.getChild(children[i]);
               }
  -        }
  -        else {
  -            final String[] children = ((TraversableSourceMeta) 
super.response.getExtra()).getChildren();
  -            for (int i = 0; i < children.length; i++) {
  -                result.add(createChildSource(children[i]));
  +            catch (IOException e) {
  +                throw new SourceException("Failure getting child", e);
               }
  +            result.add(createSource(getChildURI(super.uri, children[i]), 
child));
           }
           
           return result;
  @@ -145,104 +130,36 @@
   
       public Source getParent() throws SourceException {
           
  +        Source parent;
           try {
               initMetaResponse(false);
  +            parent = this.tsource.getParent();
           }
           catch (SourceException e) {
               throw e;
           }
           catch (IOException e) {
  -            throw new SourceException("Failure getting child", e);
  +            throw new SourceException("Failure getting parent", e);
           }
           
  -        return createSource(getParentURI(super.uri), 
getParentURI(super.sourceURI));
  +        return createSource(getParentURI(super.uri), parent);
       }
   
   
       // ---------------------------------------------------- helper methods
  -    
  -    protected SourceMeta readMeta() throws IOException {
  -        final TraversableSourceMeta meta = new TraversableSourceMeta();
  -        
  -        final long lastModified = getTraversableSource().getLastModified();
  -        if (lastModified > 0) {
  -            meta.setLastModified(lastModified);
  -        }
  -        else {
  -            meta.setLastModified(System.currentTimeMillis());
  -        }
  -        meta.setMimeType(getTraversableSource().getMimeType());
  -        
  -        meta.setName(getTraversableSource().getName());
  -        meta.setIsCollection(getTraversableSource().isCollection());
  -        
  -        if (meta.isCollection()) {
  -            final Collection children = getTraversableSource().getChildren();
  -            if (children != null) {
  -                m_children = new TraversableSource[children.size()];
  -                final String[] names = new String[children.size()];
  -                final Iterator iter = children.iterator();
  -                int count = 0;
  -                while(iter.hasNext()) {
  -                    TraversableSource child = (TraversableSource) 
iter.next();
  -                    m_children[count] = child;
  -                    names[count] = child.getName();
  -                    count++;
  -                }
  -                meta.setChildren(names);
  -            }
  -        }
  -        return meta;
  -    }
  -    
  -    protected TraversableSource getTraversableSource() throws 
MalformedURLException, IOException {
  -        return (TraversableSource) getSource();
  -    }
  -    
  -    private TraversableCachingSource createChildSource(TraversableSource 
childSource)
  -    throws SourceException {
  -        return createSource(childSource, getChildURI(super.uri, 
childSource.getName()));
  -    }
  -
  -    private TraversableCachingSource createSource(TraversableSource 
wrappedSource, String sourceURI)
  -    throws SourceException {
  -        final TraversableCachingSource child = 
  -            new TraversableCachingSource(super.protocol,
  -                                         sourceURI,
  -                                         wrappedSource,
  -                                         super.cacheName,
  -                                         super.expires,
  -                                         super.parameters,
  -                                         super.async);
  -        child.cache = super.cache;
  -        child.resolver = super.resolver;
  -        ContainerUtil.enableLogging(child,getLogger());
  -        try {
  -            ContainerUtil.service(child,super.manager);
  -            ContainerUtil.initialize(child);
  -        } catch (Exception e) {
  -            throw new SourceException("Unable to initialize source.", e);
  -        }
  -        return child;
  -    }
  -    
  -    private TraversableCachingSource createChildSource(String childName) 
  -    throws SourceException {
  -        return createSource(getChildURI(super.uri, childName), 
getChildURI(super.sourceURI, childName));
  -    }
   
  -    private TraversableCachingSource createSource(String uri, String 
sourceURI) 
  +    private TraversableCachingSource createSource(String uri, Source 
wrapped) 
       throws SourceException {
           final TraversableCachingSource source = 
               new TraversableCachingSource(super.protocol,
                                            uri,
  -                                         sourceURI,
  -                                         super.cacheName,
  -                                         super.expires,
  +                                         (TraversableSource) wrapped,
                                            super.parameters,
  +                                         super.expires,
                                            super.async);
           source.cache = super.cache;
           source.resolver = super.resolver;
  +        source.refresher = super.refresher;
           ContainerUtil.enableLogging(source, getLogger());
           try {
               ContainerUtil.service(source, super.manager);
  @@ -313,35 +230,4 @@
           return parentUri + qs;
       }
   
  -    protected static class TraversableSourceMeta extends SourceMeta {
  -        
  -        private String   m_name;
  -        private boolean  m_isCollection;
  -        private String[] m_children;
  -        
  -        protected String getName() {
  -            return m_name;
  -        }
  -        
  -        protected void setName(String name) {
  -            m_name = name;
  -        }
  -        
  -        protected boolean isCollection() {
  -            return m_isCollection;
  -        }
  -        
  -        protected void setIsCollection(boolean isCollection) {
  -            m_isCollection = isCollection;
  -        }
  -        
  -        protected String[] getChildren() {
  -            return m_children;
  -        }
  -        
  -        protected void setChildren(String[] children) {
  -            m_children = children;
  -        }
  -        
  -    }
   }
  
  
  
  1.4       +102 -99   
cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/UpdateTarget.java
  
  Index: UpdateTarget.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/UpdateTarget.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- UpdateTarget.java 5 Mar 2004 10:07:25 -0000       1.3
  +++ UpdateTarget.java 23 Mar 2004 16:28:54 -0000      1.4
  @@ -15,155 +15,158 @@
    */
   package org.apache.cocoon.components.source.impl;
   
  -import java.io.ByteArrayInputStream;
  -import java.io.ByteArrayOutputStream;
  -import java.io.InputStream;
   import java.util.Map;
   
  -import org.apache.avalon.excalibur.pool.Recyclable;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.parameters.Parameters;
   import org.apache.avalon.framework.service.ServiceException;
   import org.apache.avalon.framework.service.ServiceManager;
   import org.apache.avalon.framework.service.Serviceable;
   import org.apache.cocoon.caching.Cache;
  -import org.apache.cocoon.caching.ExtendedCachedResponse;
   import org.apache.cocoon.caching.SimpleCacheKey;
   import org.apache.cocoon.components.cron.ConfigurableCronJob;
  -import org.apache.cocoon.components.sax.XMLSerializer;
   import org.apache.excalibur.source.Source;
   import org.apache.excalibur.source.SourceResolver;
  -import org.apache.excalibur.source.SourceValidity;
   import org.apache.excalibur.source.impl.validity.ExpiresValidity;
  -import org.apache.excalibur.xml.sax.SAXParser;
  -import org.apache.excalibur.xml.sax.XMLizable;
  -import org.xml.sax.InputSource;
   
   /**
    * A target updating a cache entry.
    *
    * This target requires several parameters:
  - * - uri (String): The uri to cache, every valid protocol can be used, 
except the Cocoon protocol!
  - * - cacheRole (String): The role of the cache component to store the content
  - * - expires (long): The time in seconds the cached content is valid
  - * - cacheKey (SimpleCacheKey) : The key used to cache the content
  + * <ul>
  + * <li>
  + *   <code>uri (String)</code>: 
  + *   The uri to cache, every valid protocol can be used, except the Cocoon 
protocol!
  + * </li>
  + * <li>
  + *  <code>cache-role (String)</code>: 
  + *  The role of the cache component to store the content
  + * </li>
  + * <li>
  + *  <code>cache-expires (long)</code>: 
  + *  The time in seconds the cached content is valid
  + * </li>
  + * <li>
  + *  <code>fail-safe (boolean)</code>
  + *  Whether to invalidate the cached response when updating it failed.
  + * </li>
  + * <li>
  + *  <code>cache-key (SimpleCacheKey)</code>: 
  + *  The key used to cache the content
  + * </li>
  + * </ul>
    *  
    * @since 2.1.1
    * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
    * @version CVS $Id$
    */
  -public class UpdateTarget 
  -    extends AbstractLogEnabled
  -    implements Recyclable, Serviceable, ConfigurableCronJob {
  +public class UpdateTarget extends AbstractLogEnabled
  +implements Serviceable, ConfigurableCronJob {
       
  -    protected String uri;
  +    // service dependencies
  +    protected ServiceManager manager;
  +    protected SourceResolver resolver;
       
  +    // configuration
  +    protected String uri;
       protected String cacheRole;
  +    protected int expires;
  +    protected boolean failSafe;
       
  -    protected long expires;
  +    // the key under which to store the CachedResponse in the Cache
  +    protected SimpleCacheKey cacheKey;
       
  -    protected ServiceManager manager;
  +        
  +    // ---------------------------------------------------- Lifecycle
       
  -    protected SourceResolver resolver;
  +    public UpdateTarget() {
  +    }
       
  -    protected SimpleCacheKey cacheKey;
  +    /* (non-Javadoc)
  +     * @see 
org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
  +     */
  +    public void service(ServiceManager manager) throws ServiceException {
  +        this.manager = manager;
  +        this.resolver = (SourceResolver) 
this.manager.lookup(SourceResolver.ROLE);
  +    }
  +    
  +    /* (non-Javadoc)
  +     * @see 
org.apache.cocoon.components.scheduler.ConfigurableTarget#setup(org.apache.avalon.framework.parameters.Parameters,
 java.util.Map)
  +     */
  +    public void setup(Parameters pars, Map objects) {
  +        this.uri = pars.getParameter("uri", null);
  +        this.cacheRole = pars.getParameter("cache-role", Cache.ROLE);
  +        this.expires = pars.getParameterAsInteger("cache-expires", 60);
  +        this.failSafe = pars.getParameterAsBoolean("fail-safe", true);
  +        this.cacheKey = (SimpleCacheKey) objects.get("cache-key");
  +    }
  +    
  +    
  +    // ---------------------------------------------------- CronJob 
implementation
       
       /* (non-Javadoc)
        * @see 
org.apache.avalon.cornerstone.services.scheduler.Target#targetTriggered(java.lang.String)
        */
       public void execute(String name) {
  -        if ( this.uri != null ) {
  -            if ( this.getLogger().isInfoEnabled()) {
  +        if (this.uri != null) {
  +            if (this.getLogger().isInfoEnabled()) {
                   this.getLogger().info("Refreshing " + this.uri);
               }
  -
  +            
               Source source = null;
               Cache cache = null;
               try {
  -                cache = (Cache)this.manager.lookup(this.cacheRole);
  -                // the content expires, so remove it                
  -                cache.remove(cacheKey);
                   
  +                cache = (Cache) this.manager.lookup(this.cacheRole);
                   source = this.resolver.resolveURI(this.uri);
  -
  -                XMLSerializer serializer = null;
  -                SAXParser parser = null;
  -                byte[] cachedResponse;
  -                byte[] content = null;
                   
  -                try {
  -                    serializer = 
(XMLSerializer)this.manager.lookup(XMLSerializer.ROLE);
  -                    if ( source instanceof XMLizable ) {
  -                        ((XMLizable)source).toSAX(serializer);
  -                    } else {
  -                        // resd the content
  -                        final ByteArrayOutputStream baos = new 
ByteArrayOutputStream();
  -                        final byte[] buffer = new byte[2048];
  -                        final InputStream inputStream = 
source.getInputStream();
  -                        int length;
  -        
  -                        while ((length = inputStream.read(buffer)) > -1) {
  -                            baos.write(buffer, 0, length);
  -                        }
  -                        baos.flush();
  -                        inputStream.close();
  -                        
  -                        content = baos.toByteArray();
  -                        
  -                        parser = 
(SAXParser)this.manager.lookup(SAXParser.ROLE);
  +                CachedSourceResponse response = (CachedSourceResponse) 
cache.get(this.cacheKey);
  +                
  +                if (source.exists()) {
  +                    
  +                    // what is in the cached response?
  +                    byte[] binary = null;
  +                    byte[] xml = null;
  +                    if (response != null) {
  +                        binary = response.getBinaryResponse();
  +                        xml = response.getXMLResponse();
  +                    }
                       
  -                        final InputSource inputSource = new InputSource(new 
ByteArrayInputStream(content));
  -                        inputSource.setSystemId(source.getURI());
  +                    // create a new cached response
  +                    response = new CachedSourceResponse(new 
ExpiresValidity(this.expires * 1000));
                       
  -                        parser.parse( inputSource, serializer );
  +                    // only create objects that have previously been used
  +                    if (binary != null) {
  +                        binary = CachingSource.readBinaryResponse(source);
  +                        response.setBinaryResponse(binary);
  +                    }
  +                    if (xml != null) {
  +                        xml = CachingSource.readXMLResponse(source, binary, 
this.manager);
  +                        response.setXMLResponse(xml);
                       }
  -                    cachedResponse = (byte[])serializer.getSAXFragment();
  -                } finally {
  -                    this.manager.release(parser);
  -                    this.manager.release(serializer);
  +                    // meta info is always set
  +                    response.setExtra(CachingSource.readMeta(source));
  +                    
  +                    cache.store(this.cacheKey, response);
  +                }
  +                else if (response != null) {
  +                    cache.remove(this.cacheKey);
  +                }
  +            } catch (Exception e) {
  +                if (!failSafe) {
  +                    // the content expires, so remove it
  +                    cache.remove(cacheKey);
  +                    getLogger().warn("Exception during updating " + 
this.uri, e);
  +                }
  +                else {
  +                    getLogger().warn("Updating of source " + this.uri + " 
failed. " +
  +                        "Cached response (if any) will be stale.", e);
                   }
  -                
  -                SourceValidity val = new ExpiresValidity(this.expires);
  -                ExtendedCachedResponse response = new 
ExtendedCachedResponse(val, content);
  -                response.setAlternativeResponse(cachedResponse);
  -                cache.store(cacheKey, response);
  -            
  -            } catch (Exception ignore) {
  -                this.getLogger().error("Exception during updating " 
+this.uri, ignore);
               } finally {
                   this.resolver.release(source);
  -                this.manager.release( cache );
  +                this.manager.release(cache);
               }
  -
           }
  -    }
  -
  -    /* (non-Javadoc)
  -     * @see 
org.apache.cocoon.components.scheduler.ConfigurableTarget#setup(org.apache.avalon.framework.parameters.Parameters,
 java.util.Map)
  -     */
  -    public void setup(Parameters pars, Map objects) {
  -        this.uri = pars.getParameter("uri", null);
  -        this.cacheRole = pars.getParameter("cache-role", Cache.ROLE);
  -        this.expires = pars.getParameterAsLong("cache-expires", 1800);
  -        this.cacheKey = (SimpleCacheKey) objects.get("cache-key");
  -    }
  -
  -    /* (non-Javadoc)
  -     * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
  -     */
  -    public void recycle() {
  -        this.uri = null;
  -        this.cacheKey = null;
  -        this.expires = 0;
  -        this.cacheRole = null;
  -    }
  -
  -    /* (non-Javadoc)
  -     * @see 
org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
  -     */
  -    public void service(ServiceManager manager) throws ServiceException {
  -        this.manager = manager;
  -        this.resolver = (SourceResolver) 
this.manager.lookup(SourceResolver.ROLE);
       }
   
   }
  
  
  
  1.2       +14 -14    
cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/DelayRefresher.java
  
  Index: DelayRefresher.java
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/DelayRefresher.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DelayRefresher.java       22 Mar 2004 17:38:25 -0000      1.1
  +++ DelayRefresher.java       23 Mar 2004 16:28:54 -0000      1.2
  @@ -62,21 +62,21 @@
   public class DelayRefresher extends AbstractLogEnabled
   implements Contextualizable, Serviceable, Parameterizable, Disposable, 
ThreadSafe, Refresher, CronJob {
       
  -    private static final String PARAM_CACHE_ROLE     = "cache-role";
  -    private static final String PARAM_CACHE_EXPIRES  = "cache-expires";
  -    private static final String PARAM_UPDATE_TARGET  = "update-target";
  -    private static final String PARAM_WRITE_INTERVAL = "write-interval";
  -     private static final String PARAM_WRITE_FILE   = "write-file";
  +    private static final String PARAM_CACHE_ROLE          = "cache-role";
  +    private static final String PARAM_CACHE_EXPIRES       = "cache-expires";
  +    private static final String PARAM_UPDATE_TARGET_ROLE  = 
"update-target-role";
  +    private static final String PARAM_WRITE_INTERVAL      = "write-interval";
  +     private static final String PARAM_WRITE_FILE          = "write-file";
        
  -     private static final String DEFAULT_WRITE_FILE = 
"refresher-targets.xml";
  +     private static final String DEFAULT_WRITE_FILE        = 
"refresher-targets.xml";
        
  -    private static final String CACHE_KEY = "cache-key";
  +    private static final String CACHE_KEY                 = "cache-key";
        
  -    private static final String TAGNAME_TARGET = "target";
  -     private static final String ATTR_CACHE = "cache";
  -     private static final String ATTR_EXPIRES = "expires";
  -    private static final String ATTR_KEY = "key";
  -     private static final String ATTR_URI = "uri";
  +    private static final String TAGNAME_TARGET            = "target";
  +     private static final String ATTR_CACHE                = "cache";
  +     private static final String ATTR_EXPIRES              = "expires";
  +    private static final String ATTR_KEY                  = "key";
  +     private static final String ATTR_URI                  = "uri";
       
       // service dependencies
       protected ServiceManager manager;
  @@ -124,7 +124,7 @@
        * @see 
org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
        */
       public void parameterize(Parameters parameters) throws 
ParameterException {
  -        this.updateTarget = parameters.getParameter(PARAM_UPDATE_TARGET, 
CronJob.ROLE + "/UpdateTarget");
  +        this.updateTarget = 
parameters.getParameter(PARAM_UPDATE_TARGET_ROLE, CronJob.ROLE + 
"/UpdateTarget");
           int writeInterval = 
parameters.getParameterAsInteger(PARAM_WRITE_INTERVAL, 0);
           if (writeInterval > 0) {
               this.setupRefreshJobSource(parameters);
  
  
  
  1.2       +11 -0     
cocoon-2.1/src/blocks/scratchpad/conf/delay-refresher.xconf
  
  Index: delay-refresher.xconf
  ===================================================================
  RCS file: 
/home/cvs/cocoon-2.1/src/blocks/scratchpad/conf/delay-refresher.xconf,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- delay-refresher.xconf     22 Mar 2004 17:38:25 -0000      1.1
  +++ delay-refresher.xconf     23 Mar 2004 16:28:54 -0000      1.2
  @@ -33,6 +33,8 @@
         |   more than one DelayRefreshers. It represents the file name, 
relative to
         |   the cocoon working directory of the file the refresher writes its 
list
         |   of registered target configurations to.
  +      | - 'update-target-role' 
(org.apache.cocoon.components.cron.CronJob/UpdateTarget)
  +      |   The role name of the CronJob to use for updating the Sources.
         +-->
     <component role="org.apache.cocoon.components.source.impl.Refresher/Delay"
                class="org.apache.cocoon.components.source.impl.DelayRefresher"
  @@ -40,7 +42,16 @@
       <!--
       <parameter name="write-interval" value="0"/>
       <parameter name="write-file" value="refresher-targets.xml"/>
  +    <parameter name="update-target-role" 
value="org.apache.cocoon.components.cron.CronJob/UpdateTarget"/>
       -->
     </component>
  +  
  +  <!-- This is the default CronJob for updating the Source files 
  +       used by the DelayRefresher.
  +  -->
  +  <component role="org.apache.cocoon.components.cron.CronJob/UpdateTarget"
  +             class="org.apache.cocoon.components.source.impl.UpdateTarget"
  +             logger="core.refresher.update"
  +  />
     
   </xconf>
  
  
  

Reply via email to