I am attaching code of CachingCIncludeTransformer, IncludeCacheValidity and xml files to try it. Is just a try to attack problem of caching cinclude transformer. Current caching framework design hardly makes it possible. One has to use CacheValidity objects in a hacky way. As ContentAggregator it caches only if includes are files, since sitemap sources always return getLastModified() == 0. Anyone works on caching sitemap includes in ContentAggregator? P.S.: To try it one should change <map:transformer name="cinclude" src="org.apache.cocoon.transformation.CIncludeTransformer"/> to <map:transformer name="cinclude" src="org.apache.cocoon.transformation.CachingCIncludeTransformer"/> and add something like: <map:match pattern="x.xml"> <map:generate src="x.xml"/> <map:transform type="cinclude"/> <map:serialize type="xml"/> </map:match> to sitemap.xmap and put x.xml, y.xml, z.xml into webapp dir. Maciek Kaminski [EMAIL PROTECTED]
/***************************************************************************** * 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; /** * 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. * * @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a> * @version CVS $Revision: 1.2 $ $Date: 2001/06/19 13:39:21 $ $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 { 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); } /* Look's more simple and should be faster, but does not work try { this.sourceResolver.resolve(src).stream(this); } catch (Exception e) { getLogger().error("CIncludeTransformer", e); throw new SAXException("CIncludeTransformer could not read resource", e); } */ Parser parser = null; try { IncludeXMLConsumer consumer = new IncludeXMLConsumer(this); parser = (Parser)this.manager.lookup(Roles.PARSER); parser.setConsumer(consumer); parser.parse(this.sourceResolver.resolve(src).getInputSource()); } catch (IOException e) { getLogger().error("CIncludeTransformer", e); throw new SAXException("CIncludeTransformer could not read resource", e); } catch (SAXException e) { getLogger().error("CIncludeTransformer", e); throw(e); } catch (Exception e){ getLogger().error("Could not get parser", e); throw new SAXException("Exception in CIncludeTransformer",e); } finally { if (parser != null) this.manager.release(parser); } 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. * * @return The generated key hashes the src */ public long generateKey() { return 1; } /** * Generate the validity object. * * @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; } } }
package org.apache.cocoon.caching; import java.util.List; import java.util.ArrayList; import java.util.Iterator; import org.apache.cocoon.environment.SourceResolver; 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 ) 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(); } }
<?xml version="1.0" encoding="UTF-8"?> <x xmlns:cinclude="http://apache.org/cocoon/include/1.0"> <cinclude:include src="y.xml"/> <cinclude:include src="z.xml"/> </x>
<?xml version="1.0" encoding="UTF-8"?> <y/>
<?xml version="1.0" encoding="UTF-8"?> <z/>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]