/*
 * Aleph Toolkit
 *
 * Copyright 1997,1998 Brown University, Providence, RI.
 * 
 *                         All Rights Reserved
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose other than its incorporation into a
 * commercial product is hereby granted without fee, provided that the
 * above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Brown University not be used in
 * advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.
 * 
 * BROWN UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY
 * PARTICULAR PURPOSE.  IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE FOR
 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package aleph;

import aleph.trans.TransactionManager;
import java.io.Externalizable;
import java.io.IOException;
import java.io.IOException;
import java.io.NotActiveException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.StreamCorruptedException;
import java.util.Hashtable;

/**
 * Objects shared among PEs.
 *
 * @author  Maurice Herlihy
 * @date    March 1997
 **/

public class GlobalObject implements Externalizable {

  private static final boolean DEBUG = false; // Lightning striking again and again and again ...

  private static TransactionManager tManager =
    TransactionManager.getManager();

  /**
   * Globally unique id
   **/
  private UniqueID id;

  /**
   * Create new global object.
   * @param object Global object's initial state.
   **/
  public GlobalObject (Object object) {
    id  = new UniqueID();
    tManager.newObject(this, object);
  }
    
  /**
   * Create new global object.
   * @param object Global object's initial state.
   * @param hint <code>String</code> passed to transaction manager.
   **/
  public GlobalObject (Object object, String hint) {
    id  = new UniqueID();
    tManager.newObject(this, object, hint);
  }
        
  /**
   * Applications should not use this Constructor.
   **/
  public GlobalObject() {}

  /**
   * @return object's unique id
   **/
  public UniqueID getID() {
    return id;
  }

  /**
   * the PE at which the object was created
   * @return object's home PE
   **/
  public PE getHome() {
    return id.getHome();
  }

  /**
   * Always use equals to compare global objects.
   **/
  public boolean equals(Object anObject) {
    if ((anObject != null) && (anObject instanceof GlobalObject)) {
      GlobalObject other = (GlobalObject) anObject;
      return other.id.equals(id);
    } else {
      return false;
    }
  }

  public int hashCode () {
    return (int) id.hashCode();
  }

  /**
   * Open an object for access.
   * @param mode <code>String</code> interpreted by the transaction manager.
   * @see aleph.TransactionManager
   **/
  public Object open (String mode) {
    return tManager.open(this, mode);
  }

  /**
   * Open an object for access.
   * @param transaction Transaction on behalf of which operations occur.
   * @param mode <code>String</code> interpreted by the transaction manager.
   * @see aleph.TransactionManager
   **/
  public Object open (Transaction transaction, String mode) {
    return tManager.open(this, transaction, mode);
  }

  /**
   * Called when object no longer needed.
   * @param object Formerly interesting object.
   * @exception AlephException something went terribly wrong
   **/
  public void release () throws AlephException {
    tManager.release(this);
  }

  public String toString () {
    return "GlobalObject" + id;
  }
  /**
   * @see java.io.Externalizable
   **/
  public void writeExternal(ObjectOutput out) throws IOException {
    out.writeObject(id);
  }
  /**
   * @see java.io.Externalizable
   **/
  public void readExternal(ObjectInput in)
    throws IOException, java.lang.ClassNotFoundException {
    id = (UniqueID) in.readObject();
    if (DEBUG)
      AlephDebug.println("GlobalObject.readObject registering " + this);
  }

}
