You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by ov...@apache.org on 2002/03/17 22:43:37 UTC

cvs commit: xml-cocoon2/src/scratchpad/schecoon/src/org/apache/cocoon/components/flow AbstractInterpreter.java

ovidiu      02/03/17 13:43:37

  Added:       src/scratchpad/schecoon/src/org/apache/cocoon/components/flow
                        AbstractInterpreter.java
  Log:
  Super class for flow language interpreters. Deals mainly with
  observing modifications to script files used, and reloads them in the
  interpreter if they modify.
  
  Revision  Changes    Path
  1.1                  xml-cocoon2/src/scratchpad/schecoon/src/org/apache/cocoon/components/flow/AbstractInterpreter.java
  
  Index: AbstractInterpreter.java
  ===================================================================
  package org.apache.cocoon.components.flow;
  
  import java.lang.System;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Iterator;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.component.Component;
  import org.apache.avalon.framework.component.ComponentManager;
  import org.apache.avalon.framework.component.Composable;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.logger.AbstractLoggable;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.Constants;
  import org.apache.cocoon.components.source.SourceFactory;
  import org.apache.cocoon.environment.Context;
  import org.apache.cocoon.environment.Environment;
  import org.apache.cocoon.environment.ModifiableSource;
  import org.apache.cocoon.environment.Source;
  import org.apache.cocoon.environment.SourceResolver;
  
  /**
   * 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).
   *
   * @author <a href="mailto:ovidiu@cup.hp.com">Ovidiu Predescu</a>
   * @since March 15, 2002
   */
  public abstract class AbstractInterpreter extends AbstractLoggable
    implements Component, Composable, Contextualizable, Interpreter, ThreadSafe
  {
    /**
     * Hash table of source locations -> DelayedRefreshSourceWrapper
     * instances
     */
    protected HashMap scripts = new HashMap();
  
    /**
     * List of source locations that need to be resolved.
     */
    protected ArrayList needResolve = new ArrayList();
  
    /**
     * When was the last time we checked for script modifications. Used
     * only if {@link reloadScripts} is true.
     */
    protected long lastTimeCheck = 0;
  
    protected org.apache.cocoon.environment.Context context;
    protected ComponentManager manager;
  
    /**
     * 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 compose(ComponentManager manager)
    {
      this.manager = manager;
    }
  
    public void contextualize(org.apache.avalon.framework.context.Context context)
      throws ContextException
    {
      this.context = (Context)context.get(Constants.CONTEXT_ENVIRONMENT_CONTEXT);
    }
  
    public void setReloadScripts(boolean yn)
    {
      reloadScripts = yn;
    }
  
    public void setCheckTime(long time)
    {
      checkTime = time;
    }
  
    /**
     * 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.DelayedRefreshSourceWrapper
     */
    public void register(String source)
    {
      synchronized(this) {
        needResolve.add(source);
      }
    }
  
    /**
     * Unregister the source file. Called from <code>ScriptNode</code>
     * when a tree corresponding to a sitemap is decommissioned.
     *
     * @param source a <code>String</code> value
     */
    public void unregister(String source)
    {
      synchronized(this) {
        scripts.remove(source);
        int index = needResolve.indexOf(source);
        if (index != -1)
          needResolve.remove(index);
      }
    }
  
    /**
     * Reloads any modified script files.
     *
     * <p>It checks to see if any of the files already read in (those
     * present in the <code>scripts</code> hash map) have been
     * modified.
     *
     * <p>It also checks to see if any script files have been registered
     * with the interpreter since the last call to
     * <code>checkForModifiedScripts</code>. These files are stored in
     * the temporary array <code>needResolve</code>. If any such files
     * are found, they are read in.
     *
     * @param environment an <code>Environment</code> value
     */
    public void checkForModifiedScripts(Environment environment)
      throws Exception
    {
      if (reloadScripts
          && System.currentTimeMillis() >= lastTimeCheck + checkTime) {
        // FIXME: should we worry about synchronization?
        Iterator iter = scripts.values().iterator();
        while (iter.hasNext()) {
          ScriptSource src = (ScriptSource)iter.next();
          if (src.getLastModified() > lastTimeCheck)
            src.refresh(environment);
        }
      }
  
      int size = needResolve.size();
  
      if (size > 0) {
        synchronized (this) {
          size = needResolve.size();
          for (int i = size - 1; i >= 0; i--) {
            String source = (String)needResolve.get(i);
            ScriptSource src = new ScriptSource(this, source);
            scripts.put(source, src);
            needResolve.remove(i);
            src.refresh(environment);
          }
        }
      }
  
      // Update the time of the last check. If an exception occurs, this
      // is not executed, so the next request will force a reparse of
      // the script files because of an old time stamp.
      lastTimeCheck = System.currentTimeMillis();
    }
  }
  
  
  

----------------------------------------------------------------------
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