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>