Package org.apache.cocoon.components.flow

Source Code of org.apache.cocoon.components.flow.AbstractInterpreter

/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.components.flow;

import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Map;

import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.SingleThreaded;
import org.apache.cocoon.Constants;
import org.apache.cocoon.components.ContextHelper;
import org.apache.cocoon.components.flow.util.PipelineUtil;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.Redirector;
import org.apache.excalibur.source.SourceUtil;

/**
* Abstract superclass for various scripting languages used by Cocoon
* for flow control. Defines some useful behavior like the ability to
* reload script files if they get modified (useful when doing
* development), and passing the control to Cocoon's sitemap for
* result page generation.
*
* @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
* @since March 15, 2002
* @version CVS $Id: AbstractInterpreter.java,v 1.20 2004/05/04 11:54:35 cziegeler Exp $
*/
public abstract class AbstractInterpreter extends AbstractLogEnabled
  implements Component, Serviceable, Contextualizable, Interpreter,
             SingleThreaded, Configurable, Disposable
{
    protected org.apache.avalon.framework.context.Context avalonContext;

    /**
     * List of source locations that need to be resolved.
     */
    protected ArrayList needResolve = new ArrayList();

    protected org.apache.cocoon.environment.Context context;
    protected ServiceManager manager;
    protected ContinuationsManager continuationsMgr;
   
    /**
     * Whether reloading of scripts should be done. Specified through
     * the "reload-scripts" attribute in <code>flow.xmap</code>.
     */
    protected boolean reloadScripts;

    /**
     * Interval between two checks for modified script files. Specified
     * through the "check-time" XML attribute in <code>flow.xmap</code>.
     */
    protected long checkTime;

    public void configure(Configuration config) throws ConfigurationException {
        reloadScripts = config.getChild("reload-scripts").getValueAsBoolean(false);
        checkTime = config.getChild("check-time").getValueAsLong(1000L);
    }

    /**
     * Serviceable
     */
    public void service(ServiceManager sm) throws ServiceException {
        this.manager = sm;
        this.continuationsMgr = (ContinuationsManager)sm.lookup(ContinuationsManager.ROLE);
    }

    public void contextualize(org.apache.avalon.framework.context.Context context)
    throws ContextException{
        this.avalonContext = context;
        this.context = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
    }

    /* (non-Javadoc)
     * @see org.apache.avalon.framework.activity.Disposable#dispose()
     */
    public void dispose() {
        if ( this.manager != null ) {
            this.manager.release( this.continuationsMgr );
            this.continuationsMgr = null;
            this.manager = null;
        }
    }

    /**
     * Registers a source file with the interpreter. Using this method
     * an implementation keeps track of all the script files which are
     * compiled. This allows them to reload the script files which get
     * modified on the file system.
     *
     * <p>The parsing/compilation of a script file by an interpreter
     * happens in two phases. In the first phase the file's location is
     * registered in the <code>needResolve</code> array.
     *
     * <p>The second is possible only when a Cocoon
     * <code>Environment</code> is passed to the Interpreter. This
     * allows the file location to be resolved using Cocoon's
     * <code>SourceFactory</code> class.
     *
     * <p>Once a file's location can be resolved, it is removed from the
     * <code>needResolve</code> array and placed in the
     * <code>scripts</code> hash table. The key in this hash table is
     * the file location string, and the value is a
     * DelayedRefreshSourceWrapper instance which keeps track of when
     * the file needs to re-read.
     *
     * @param source the location of the script
     *
     * @see org.apache.cocoon.components.source.SourceFactory
     * @see org.apache.cocoon.environment.Environment
     * @see org.apache.cocoon.components.source.impl.DelayedRefreshSourceWrapper
     */
    public void register(String source)
    {
        synchronized(this) {
            needResolve.add(source);
        }
    }

    /**
     * Call the Cocoon sitemap for the given URI, sending the output of the
     * eventually matched pipeline to the specified outputstream.
     *
     * @param uri The URI for which the request should be generated.
     * @param biz Extra data associated with the subrequest.
     * @param out An OutputStream where the output should be written to.
     * @exception Exception If an error occurs.
     */
    public void process(String uri, Object biz, OutputStream out)
        throws Exception
    {
        // FIXME (SW): should we deprecate this method in favor of PipelineUtil?
        PipelineUtil pipeUtil = new PipelineUtil();
        try {
            pipeUtil.contextualize(this.avalonContext);
            pipeUtil.service(this.manager);
            pipeUtil.processToStream(uri, biz, out);
        } finally {
            pipeUtil.dispose();
        }
    }

    public void forwardTo(String uri, Object bizData,
                          WebContinuation continuation,
                          Redirector redirector)
        throws Exception
    {
        if (SourceUtil.indexOfSchemeColon(uri) == -1) {
            uri = "cocoon:/" + uri;
            Map objectModel = ContextHelper.getObjectModel(this.avalonContext);
            FlowHelper.setWebContinuation(objectModel, continuation);
            FlowHelper.setContextObject(objectModel, bizData);
            if (redirector.hasRedirected()) {
                throw new IllegalStateException("Pipeline has already been processed for this request");
            }
            // this is a hint for the redirector
            objectModel.put("cocoon:forward", "true");
            redirector.redirect(false, uri);
        } else {
            throw new Exception("uri is not allowed to contain a scheme (cocoon:/ is always automatically used)");
        }
    }
}
TOP

Related Classes of org.apache.cocoon.components.flow.AbstractInterpreter

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.