You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2001/07/09 14:42:22 UTC
cvs commit: xml-cocoon2/src/org/apache/cocoon/transformation CachingCIncludeTransformer.java
cziegeler 01/07/09 05:42:21
Added: src/org/apache/cocoon/caching IncludeCacheValidity.java
src/org/apache/cocoon/transformation
CachingCIncludeTransformer.java
Log:
Added CachingCIncludeTransformer
Submitted by: Maciek Kaminski (maciejka@tiger.com.pl)
Revision Changes Path
1.1 xml-cocoon2/src/org/apache/cocoon/caching/IncludeCacheValidity.java
Index: IncludeCacheValidity.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.cocoon.caching;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.cocoon.environment.SourceResolver;
/**
* A validation object used in CachingCIncludeTransformer
*
* @author <a href="mailto:maciejka@tiger.com.pl">Maciek Kaminski</a>
*/
public final class IncludeCacheValidity implements CacheValidity {
private List sources;
private List timeStamps;
private boolean isNew;
private SourceResolver resolver;
public IncludeCacheValidity(SourceResolver resolver) {
this.resolver = resolver;
sources = new ArrayList();
timeStamps = new ArrayList();
isNew = true;
}
public boolean isNew() {
return isNew;
}
public void setIsNew2False() {
isNew = false;
resolver = null;
}
public void add(String source, long timeStamp) {
this.sources.add(source);
this.timeStamps.add(new Long(timeStamp));
}
public boolean isValid(CacheValidity validity) {
if (validity instanceof IncludeCacheValidity) {
SourceResolver otherResolver = ((IncludeCacheValidity) validity).resolver;
for(Iterator i = sources.iterator(), j = timeStamps.iterator(); i.hasNext();) {
String src = ((String)i.next());
long timeStamp = ((Long)j.next()).longValue();
try {
if( otherResolver.resolve(src).getLastModified() != timeStamp ||
timeStamp == 0)
return false;
} catch (Exception e) {
return false;
}
}
return true;
}
return false;
}
public String toString() {
StringBuffer b = new StringBuffer("IncludeCacheValidity: " );
for(Iterator i = sources.iterator(), j = timeStamps.iterator(); i.hasNext();) {
b.append("[");
b.append(i.next());
b.append(" - ");
b.append(j.next());
b.append("]");
if(i.hasNext()) b.append(", ");
}
return b.toString();
}
}
1.1 xml-cocoon2/src/org/apache/cocoon/transformation/CachingCIncludeTransformer.java
Index: CachingCIncludeTransformer.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.cocoon.transformation;
import java.io.IOException;
import java.util.Map;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.Roles;
import org.apache.cocoon.caching.EventCache;
import org.apache.cocoon.caching.Cacheable;
import org.apache.cocoon.caching.CacheValidity;
import org.apache.cocoon.caching.IncludeCacheValidity;
import org.apache.cocoon.caching.TimeStampCacheValidity;
import org.apache.cocoon.components.parser.Parser;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.xml.IncludeXMLConsumer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.cocoon.util.HashUtil;
/**
* <p>This transformer triggers for the element <code>include</code> in the
* namespace "http://apache.org/cocoon/include/1.0".
* The <code>src></code> attribute contains the url which points to
* an xml resource which is include instead of the element.
* With the attributes <code>element</code>, <code>ns</code> and
* <code>prefix</code> it is possible to specify an element
* which surrounds the included content.</p>
*
* <p>Validity of cached pipelines is calculated not by comparing old and new
* IncludeCacheValidity objects (as in AggregatedCacheValidity) but by comparing
* timestamps. Validity object of cached pipeline contain two lists: source urls
* and timestamps. When it comes to checking validity of cached pipeline we know
* that generation/transformation steps before CIncludeTransformer are valid (otherwise
* we would have had discarded cached pipeline already) so source url list
* of new validity will be the same as of old one. Only timestamps have to be
* recalculated and compared.</p>
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @author <a href="mailto:maciejka@tiger.com.pl">Maciek Kaminski</a>
* @version CVS $Revision: 1.1 $ $Date: 2001/07/09 12:42:20 $ $Author: cziegeler $
*/
public class CachingCIncludeTransformer extends AbstractTransformer
implements Recyclable, Composable, Cacheable {
public static final String CINCLUDE_NAMESPACE_URI = "http://apache.org/cocoon/include/1.0";
public static final String CINCLUDE_INCLUDE_ELEMENT = "include";
public static final String CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE = "src";
public static final String CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE = "element";
public static final String CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE = "ns";
public static final String CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE = "prefix";
/** The <code>SourceResolver</code> */
protected SourceResolver sourceResolver;
/** The current <code>ComponentManager</code>. */
protected ComponentManager manager = null;
protected EventCache eventCache;
protected IncludeCacheValidity currentCacheValidity;
/**
* Setup the component.
*/
public void setup(SourceResolver resolver, Map objectModel,
String source, Parameters parameters)
throws ProcessingException, SAXException, IOException {
this.sourceResolver = resolver;
}
/**
* Composable Interface
*/
public final void compose(final ComponentManager manager) throws ComponentException {
this.manager = manager;
this.eventCache = (EventCache)this.manager.lookup(Roles.EVENT_CACHE);
}
/**
* Recycle the component
*/
public void recycle() {
super.recycle();
this.sourceResolver = null;
}
public void startElement(String uri, String name, String raw, Attributes attr)
throws SAXException {
if (uri != null && name != null
&& uri.equals(CINCLUDE_NAMESPACE_URI)
&& name.equals(CINCLUDE_INCLUDE_ELEMENT)) {
this.processCIncludeElement(attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_SRC_ATTRIBUTE),
attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_ELEMENT_ATTRIBUTE),
attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_NS_ATTRIBUTE),
attr.getValue("",CINCLUDE_INCLUDE_ELEMENT_PREFIX_ATTRIBUTE));
} else {
super.startElement(uri, name, raw, attr);
}
}
public void endElement(String uri, String name, String raw) throws SAXException {
if (uri != null && name != null
&& uri.equals(CINCLUDE_NAMESPACE_URI)
&& name.equals(CINCLUDE_INCLUDE_ELEMENT)) {
return;
}
super.endElement(uri, name, raw);
}
public void endDocument()
throws SAXException {
super.endDocument();
currentCacheValidity.setIsNew2False();
}
protected void processCIncludeElement(String src, String element, String ns, String prefix)
throws SAXException {
// complete validity information
try {
currentCacheValidity.add(src, sourceResolver.resolve(src).getLastModified());
} catch (Exception e) {
getLogger().error("CachingCIncludeTransformer could not resolve resource", e);
throw new SAXException("CachingCIncludeTransformer could not resolve resource", e);
}
if (element == null) element="";
if (ns == null) ns="";
if (prefix == null) prefix="";
getLogger().debug("Processing CInclude element: src=" + src
+ ", element=" + element
+ ", ns=" + ns
+ ", prefix=" + prefix);
if (!"".equals(element)) {
AttributesImpl attrs = new AttributesImpl();
if (!ns.equals("")) {
super.startPrefixMapping(prefix, ns);
}
super.startElement(ns,
element,
(!ns.equals("") && !prefix.equals("") ? prefix+":"+element : element),
attrs);
}
try {
this.sourceResolver.resolve(src).stream(this);
} catch (Exception e) {
getLogger().error("CachingCIncludeTransformer", e);
throw new SAXException("CachingCIncludeTransformer could not read resource", e);
}
if (!"".equals(element)) {
super.endElement(ns, element, (!ns.equals("") && !prefix.equals("") ? prefix+":"+element : element));
if (!ns.equals("")) {
super.endPrefixMapping(prefix);
}
}
}
/**
* Generate the unique key.
* This key must be unique inside the space of this component.
* CachingCIncludeTransformer always generates the same key since which documents
* are included depends only on former generation/transformation stages.
*
* @return The generated key hashes the src
*/
public long generateKey() {
return 1;
}
/**
* Generate the validity object.
* CachingCIncludeTransformer generates "empty" IncludeCacheValidity
* and completes it with validity data during transformation.
* See processCIncludeElement method.
*
* @return The generated validity object or <code>null</code> if the
* component is currently not cacheable.
*/
public CacheValidity generateValidity() {
try {
currentCacheValidity = new IncludeCacheValidity(sourceResolver);
return currentCacheValidity;
} catch (Exception e) {
getLogger().error("CachingCIncludeTransformer: could not generateKey", e);
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