On 5 Jul 2001, at 16:19, Carsten Ziegeler wrote:

> Could you please add some comments to the source how it works
> and resend it?
> 

Here they are.

> > There is another issue in CIncludeTransformer that should be resolved:
> > Sources are actually included by getting InputSource from source 
> > object and
> > parsing it:
> > <code>
> >     parser.parse(this.sourceResolver.resolve(src).getInputSource());
> > </code>
> > 
> > If sources are sitemap pipelines, it is inefficient(because of 
> > unnecessary 
> > serialization/parsing stage), and should(?) be replaced by:
> > 
> > <code>
> >     this.sourceResolver.resolve(src).stream(this);
> > </code>
> > 
> > which will not serialize/parse SitemapSources.
> > 
> Yes, correct. This is one outstanding issue I wanted to do but didn't
> have any time for.
> 

Done in attached transformer.



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;

/**
 * <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:[EMAIL PROTECTED]";>Carsten Ziegeler</a>
 * @author <a href="mailto:[EMAIL PROTECTED]";>Maciek Kaminski</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 {

        // 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;
        }
    }
}
/*****************************************************************************
 * 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:[EMAIL PROTECTED]";>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();
    }
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to