Package org.apache.cocoon.sitemap

Source Code of org.apache.cocoon.sitemap.Handler

/*****************************************************************************
* 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.sitemap;

import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
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.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.Processor;
import org.apache.cocoon.components.CocoonComponentManager;
import org.apache.cocoon.components.language.generator.CompiledComponent;
import org.apache.cocoon.components.language.generator.ProgramGenerator;
import org.apache.cocoon.components.pipeline.EventPipeline;
import org.apache.cocoon.components.pipeline.StreamPipeline;
import org.apache.cocoon.components.source.CocoonSourceFactory;
import org.apache.cocoon.components.source.SourceHandler;
import org.apache.cocoon.components.source.DelayedRefreshSourceWrapper;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.environment.SourceResolver;
import org.xml.sax.SAXException;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

/**
* Handles the manageing and stating of one <code>Sitemap</code>
*
* @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
* @author <a href="mailto:Giacomo.Pati@pwr.ch">Giacomo Pati</a>
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @version CVS $Revision: 1.4 $ $Date: 2002/01/25 03:49:57 $
*/
public class Handler extends AbstractLoggable
implements Runnable, Contextualizable, Composable, Processor, Disposable, SourceResolver {

    /** the component manager */
    protected ComponentManager manager;

    /** the source of this sitemap */
    protected String sourceFileName;
    protected Source source;

    /** the last error */
    protected Exception exception;

    /** the managed sitemap */
    protected Sitemap sitemap = null;
    protected boolean check_reload = true;

    /** the regenerating thread */
    protected Thread regeneration;
    protected volatile boolean isRegenerationRunning = false;
    protected Source contextSource;

    /** the sitemaps base path */
    protected String basePath;

    /** The source handler for the sitemap components */
    protected SourceHandler sourceHandler;

    // FIXME : ugly hack to pass delay information from the main sitemap configuration
    // (the way to pass it cleanly from SitemapManager isn't obvious).
    protected static long sitemapCheckDelay = 10000L; // default is 10 secs.

    static void setSitemapCheckDelay(long delay) {
        sitemapCheckDelay = delay;
    }

  public Handler() {}

    /**
     * Contextualizable
     */
    public void contextualize(Context context)
    throws ContextException {
    }

    /**
     * Composable
     */
    public void compose(ComponentManager manager)
    throws ComponentException {
        this.manager = manager;
        this.sourceHandler = (SourceHandler)manager.lookup(SourceHandler.ROLE);
    }

  public void setSourceFileName(String sourceFileName)
  {
    this.sourceFileName = sourceFileName;
  }

  public void setCheckReload(boolean check_reload)
  {
    this.check_reload = check_reload;
  }

    protected boolean available() {
        return (sitemap != null);
    }

    protected boolean hasChanged() {
        if (available()) {
            if (check_reload) {
                return sitemap.modifiedSince(this.source.getLastModified());
            }
            return false;
        }
        return true;
    }

    protected boolean isRegenerating() {
        return isRegenerationRunning;
    }

    protected void regenerateAsynchronously(Environment environment) throws Exception {
        if (this.sourceFileName.charAt(this.sourceFileName.length() - 1) == '/') {
            this.sourceFileName = this.sourceFileName + "sitemap.xmap";
        }
        SourceHandler oldSourceHandler = environment.getSourceHandler();
        try {
            environment.setSourceHandler(this.sourceHandler);

            if (this.source != null) this.source.recycle();
            this.source = new DelayedRefreshSourceWrapper(
                environment.resolve(this.sourceFileName), this.sitemapCheckDelay);

            if (this.contextSource != null) this.contextSource.recycle();
            this.contextSource = environment.resolve("");
        } finally {
            environment.setSourceHandler(oldSourceHandler);
        }
        if (!this.isRegenerationRunning) {
            isRegenerationRunning = true;
            regeneration = new Thread(this);

            /* HACK for reducing class loader problems. */
            /* example: xalan extensions fail if someone adds xalan jars in tomcat3.2.1/lib */
            try {
                regeneration.setContextClassLoader(Thread.currentThread().getContextClassLoader());
            } catch (Exception e) {
            }

            /* clear old exception if any */
            this.exception = null;

            /* start the thread */
            regeneration.start();
        }
    }

    protected void regenerate(Environment environment) throws Exception {
        getLogger().debug("Beginning sitemap regeneration");
        this.regenerateAsynchronously(environment);
        if (regeneration != null) {
            this.regeneration.join();
        }
        throwEventualException();
    }

    public boolean process(Environment environment) throws Exception {
        checkSanity();
        SourceHandler oldSourceHandler = environment.getSourceHandler();
        CocoonComponentManager.enterEnvironment(environment, environment.getObjectModel());
        try {
            environment.setSourceHandler(this.sourceHandler);
            return sitemap.process(environment);
        } finally {
            CocoonComponentManager.leaveEnvironment();
            environment.setSourceHandler(oldSourceHandler);
        }
    }

    public boolean process(Environment environment, StreamPipeline pipeline,
        EventPipeline eventPipeline) throws Exception {
        checkSanity();
        SourceHandler oldSourceHandler = environment.getSourceHandler();
        CocoonComponentManager.enterEnvironment(environment, environment.getObjectModel());
        try {
            environment.setSourceHandler(this.sourceHandler);
            return sitemap.process(environment, pipeline, eventPipeline);
        } finally {
            CocoonComponentManager.leaveEnvironment();
            environment.setSourceHandler(oldSourceHandler);
        }
    }

    private void checkSanity() throws Exception {
        throwEventualException();
        if (sitemap == null) {
            getLogger().fatalError("Sitemap is not set for the Handler!!!!");
            throw new RuntimeException("The Sitemap is null, this should never be!");
        }
    }

    public void setBasePath(String basePath) {
        this.basePath = basePath;
    }

    /** Generate the Sitemap class */
    public void run() {
        Sitemap smap = null;
        String markupLanguage = "sitemap";
        String programmingLanguage = "java";
        ProgramGenerator programGenerator = null;
        try {
            /* FIXME: Workaround -- set the logger XSLTFactoryLoader used to generate source
             * within the sitemap generation phase.
             * Needed because we never have the opportunity to handle the lifecycle of the
             * XSLTFactoryLoader, since it is created by the Xalan engine.
             */

            XSLTFactoryLoader.setLogger(getLogger());
            programGenerator = (ProgramGenerator)this.manager.lookup(ProgramGenerator.ROLE);
            smap = (Sitemap)programGenerator.load(this.manager, this.sourceFileName, markupLanguage,
                    programmingLanguage, this);
            if (this.sitemap != null) {
                programGenerator.release((CompiledComponent)this.sitemap);
            }
            this.sitemap = smap;
            // add the source factory for the cocoon protocol
            this.sourceHandler.addFactory("cocoon", new CocoonSourceFactory(this.sitemap,
                                                                            this.sitemap.getComponentManager()));
            getLogger().debug("Sitemap regeneration complete");
            if (this.sitemap != null) {
                getLogger().debug("The sitemap has been successfully compiled!");
            } else {
                getLogger().debug("No errors, but the sitemap has not been set.");
            }
        } catch (Throwable t) {
            getLogger().error("Error compiling sitemap", t);
            if (t instanceof Exception) {
                this.exception = (Exception)t;
            }
        } finally {
            if (programGenerator != null) {
                this.manager.release(programGenerator);
            }
            this.regeneration = null;
            this.isRegenerationRunning = false;
            this.contextSource.recycle();
            this.contextSource = null;
        }
    }

    public void throwEventualException() throws Exception {
        if (this.exception != null) {
            throw this.exception;
       }
    }

    public Exception getException() {
        return this.exception;
    }

    /**
     * dispose
     */
    public void dispose() {
        if (this.source != null) {
            this.source.recycle();
            this.source = null;
        }
        if (this.sourceHandler != null) {
            manager.release((Component)this.sourceHandler);
            this.sourceHandler = null;
        }
    }

    /**
     * Resolve an entity. Interface SourceResolver
     */
    public Source resolve(String systemId)
    throws ProcessingException, SAXException, IOException {
        if (systemId == null) throw new SAXException("Invalid System ID");

        URL context = new URL(this.contextSource.getSystemId());

        if (systemId.length() == 0)
            return this.sourceHandler.getSource(null, context, systemId);
        if (systemId.indexOf(":") > 1)
            return this.sourceHandler.getSource(null, systemId);
        if (systemId.charAt(0) == '/')
            return this.sourceHandler.getSource(null, new StringBuffer(context.getProtocol())
                                                .append(":").append(systemId).toString());
        return this.sourceHandler.getSource(null, context, systemId);
    }
}
TOP

Related Classes of org.apache.cocoon.sitemap.Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.