/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (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.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.ui.script;

import java.lang.ref.*;
import java.util.*;
import javax.servlet.*;
import com.silverwrist.venice.ui.config.RootConfig;

public class ScriptManagerContainer
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static final String ATTR_NAME = "com.silverwrist.venice.ui.script.ScriptManagerContainer";

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private String temp_directory;         // temporary directory for scripts
  private LinkedList cached_engines;     // list of cached engines
  private ReferenceQueue rq_engines;     // reference queue of engines dumped from the cache

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  private ScriptManagerContainer(String tmpdir)
  {
    temp_directory = tmpdir;
    cached_engines = new LinkedList();
    rq_engines = new ReferenceQueue();

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Internal operations
   *--------------------------------------------------------------------------------
   */

  private synchronized void sweep()
  {
    Reference r = rq_engines.poll();
    while (r!=null)
    { // remove discarded engines
      cached_engines.remove(r);
      r.clear();
      r = rq_engines.poll();

    } // end while

  } // end sweep

  /*--------------------------------------------------------------------------------
   * External operations
   *--------------------------------------------------------------------------------
   */

  public synchronized ScriptManager getScriptManager() throws ScriptingException
  {
    sweep();
    ScriptManager rc = null;
    while ((rc==null) && (cached_engines.size()>0))
    { // look for a reference that contains a valid ScriptManager
      SoftReference r = (SoftReference)(cached_engines.removeFirst());
      rc = (ScriptManager)(r.get());
      r.clear();

    } // end while

    return ((rc==null) ? new ScriptManager(temp_directory) : rc);

  } // end getScriptManager

  public synchronized void releaseScriptManager(ScriptManager mgr)
  {
    sweep();
    cached_engines.addFirst(new SoftReference(mgr,rq_engines));

  } // end releaseScriptManager

  /*--------------------------------------------------------------------------------
   * External static operations
   *--------------------------------------------------------------------------------
   */

  public static final ScriptManagerContainer get(ServletContext ctxt)
  {
    return (ScriptManagerContainer)(ctxt.getAttribute(ATTR_NAME));

  } // end get

  public static final void initialize(RootConfig config, ServletContext ctxt)
  {
    if (ctxt.getAttribute(ATTR_NAME)==null)
    { // create new container...
      ScriptManagerContainer c = new ScriptManagerContainer(config.getTemporaryPath());
      ctxt.setAttribute(ATTR_NAME,c);

    } // end if

  } // end initialize

} // end ScriptManagerContainer
