/**
 * JavaSpaceCache is a class that caches references to JavaSpace
 * instances available from all reachable lookup service.
 * <br>
 * This source code is copyright 2008 by Patrick May.  All
 * rights reserved.
 *
 * @author Patrick May (patrick@softwarematters.org)
 * @author &copy; 2008 Patrick May.  All rights reserved.
 * @version 1
 */

package org.softwarematters.jini.util;

import java.util.logging.Logger;

import net.jini.space.JavaSpace;

public class JavaSpaceCache
{
  private static final int LOOKUP_RETRY_INTERVAL = 2500;  // 2.5 seconds

  private static Logger logger_
    = Logger.getLogger(JavaSpaceCache.class.getName());

  private ServiceCache serviceCache_ = null;

  /**
   * The full constructor for the JavaSpaceCache class.
   *
   * @param groups The names of the Jini groups to which JavaSpace
   *               instances must belong.
   */
  public JavaSpaceCache(String[] groups)
    {
    serviceCache_ = new ServiceCache(groups,JavaSpace.class);
    }


  /**
   * The default constructor for the JavaSpaceCache class.
   */
  public JavaSpaceCache()
    {
    this(new String[] { "" });  // default to public group
    }


  /**
   * Return a JavaSpace from the cache, if one is available within the
   * specified timeout.
   *
   * @param timeout The maximum time to wait for a JavaSpace, in
   *                milliseconds.
   */
  public JavaSpace javaSpace(long timeout)
   {
    JavaSpace javaSpace = null;

    do
      {
      logger_.info("Checking cache for JavaSpace...");
      javaSpace = (JavaSpace)serviceCache_.service();

      if (javaSpace == null)
        {
        try { Thread.sleep(LOOKUP_RETRY_INTERVAL); }
        catch (InterruptedException e) { }
        }

      timeout -= LOOKUP_RETRY_INTERVAL;
      }
    while ((javaSpace == null) && (timeout >= LOOKUP_RETRY_INTERVAL));

    if (javaSpace == null)
      logger_.info("No JavaSpace instance found, returning null.");
    else
      logger_.info("JavaSpace instance found.");

    return javaSpace;
    }


  /**
   * Return a JavaSpace from the cache, blocking as long as necessary.
   */
  public JavaSpace javaSpace()
    {
    return javaSpace(Long.MAX_VALUE);
    }


  /**
   * A test harness for the JavaSpaceCache class.
   *
   * @param args The command line arguments passed in.
   */
  public static void main(String args[])
    {
    System.setSecurityManager(new java.rmi.RMISecurityManager());

    JavaSpaceCache cache = new JavaSpaceCache();

    JavaSpace space = null;
    while (space == null)
      space = cache.javaSpace();
    }
}  // end JavaSpaceCache

