/*  Copyright (c) 2000 by Oracle Corporation. All Rights Reserved. */

package oracle.portal.sample.v1.devguide.subscriber;

import java.io.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import oracle.portal.provider.v1.http.DefaultProvider;
import oracle.portal.provider.v1.ProviderSubscriber;
import oracle.portal.provider.v1.ProviderLog;
import oracle.portal.provider.v1.ProviderException;

/**
 * The SubscriberProvider is a provider which extends the DefaultProvider which
 * is the JPDKs base implementation class for the Provider interface. The purpose
 * of this class is to illustrate the
 *  - How to extend the DefaultProvider
 *  - How to use the Subscriber ID/Provider Key
 * This class provides the implementation for the getSubscriber method and also
 * illustrates a simple way of making the subscriber ID persistent.
 */
 
public class SubscriberProvider extends DefaultProvider
{
  private static final String PROVIDER_TO_KEY_MAP_ROOT = "map_root";
  private static final String PROV_ID_TO_PROV_KEY_FILE_NAME = "providerIDToProviderKeyMap.ser";

  private static Hashtable providerIDToProviderKeyMap = null;
  private static String completeMapFilePath = null;
  private static File mapFile = null;
  
  public SubscriberProvider()
  {
  }
  protected void init(long providerId, ProviderLog logger, ServletConfig sc, HttpServletRequest request) throws ProviderException
  {
    super.init(providerId,logger, sc, request);

    String mapFilePath = sc.getInitParameter(PROVIDER_TO_KEY_MAP_ROOT);
    if (mapFilePath == null)
    {
      // See whether the provider root is specified.
      // We can look for the map file there.
      mapFilePath = getProviderRepositoryRealPath(sc);
    }
    if (mapFilePath == null)
    {
      // If it is still null. The file/file path to persist data is not available.
      // So, We can't make the map persistent.
      createMemoryMap();
    }
    else
    {
      if (mapFilePath.charAt(mapFilePath.length() - 1) == File.separatorChar)
      {
        completeMapFilePath = mapFilePath + PROV_ID_TO_PROV_KEY_FILE_NAME;
      }
      else
      {
        completeMapFilePath = mapFilePath + File.separatorChar + PROV_ID_TO_PROV_KEY_FILE_NAME;
      }

      mapFile = new File(completeMapFilePath);
      boolean fileExists = false;

      try
      {
        fileExists = mapFile.exists();
        if (fileExists)
        {
          loadProvider2SubscriberMap(mapFile);
        }
        else
        {
          createMemoryMap();
        }
      }
      catch (Exception e)
      {
        // File doesn't exist.
        // Create the Hashtable and initialize it.
        createMemoryMap();
      }
    }
  }
  public ProviderSubscriber getSubscriber()
  {
    // Get the provider key etc. from the map and return the object.
    String subscriberID = (String)providerIDToProviderKeyMap.get(new Long(getProviderId()));

    // We don't have a handle to encryption key so we pass null.
    return new ProviderSubscriber(subscriberID, null);
  }
  public ProviderSubscriber register(String subscriberID, String portalVersion) throws ProviderException
  {
    super.register(subscriberID, portalVersion);

    providerIDToProviderKeyMap.put(new Long(getProviderId()), subscriberID);
    // Make the map persistent here.
    storeProvider2SubscriberMap(mapFile);

    // We don't have a handle to encryption key as yet so we pass null.
    return new ProviderSubscriber(subscriberID, null);
  }
  public void deregister() throws ProviderException
  {
    super.deregister();

    // Delete this Provider from the Map.
    providerIDToProviderKeyMap.remove(new Long(getProviderId()));
    // Update the persistent map here.
    storeProvider2SubscriberMap(mapFile);
  }

  private static void createMemoryMap()
  {
    providerIDToProviderKeyMap = new Hashtable();
  }
  private static void loadProvider2SubscriberMap(File mapFile)
  {
    FileInputStream fis = null;
    ObjectInputStream ois = null;

    try
    {
      fis = new FileInputStream(mapFile);
      ois = new ObjectInputStream(fis);
      providerIDToProviderKeyMap = (Hashtable) ois.readObject();
      fis.close();
      ois.close();
    }
    catch (Exception e)
    {
      // Handle the exeception
      // Unable to Load map.
      // Create the memory map.
      createMemoryMap();
    }
    finally
    {
      try
      {
        if (fis != null) fis.close();
        if (ois != null) ois.close();
      }
      catch(IOException e)
      {
        // Handle the exception
      }
    }
  }

  private static void storeProvider2SubscriberMap(File mapFile)
  {
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;

    try
    {
      fos = new FileOutputStream(mapFile);
      oos = new ObjectOutputStream(fos);
      oos.writeObject(providerIDToProviderKeyMap);
      oos.flush();
      fos.close();
      oos.close();
    }
    catch (Exception e)
    {
      // Handle the exception
      // Unable to Store map.
    }
    finally
    {
      try
      {
        if (fos != null) fos.close();
        if (oos != null) oos.close();
      }
      catch(IOException e)
      {
        // Handle the exceptions.
      }
    }
  }
}

