Package com.sun.sgs.impl.service.data

Source Code of com.sun.sgs.impl.service.data.Context

/*
* Copyright 2007-2010 Sun Microsystems, Inc.
*
* This file is part of Project Darkstar Server.
*
* Project Darkstar Server is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation and
* distributed hereunder to you.
*
* Project Darkstar Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* --
*/

package com.sun.sgs.impl.service.data;

import com.sun.sgs.app.ManagedObject;
import com.sun.sgs.app.ManagedObjectRemoval;
import com.sun.sgs.impl.sharedutil.LoggerWrapper;
import com.sun.sgs.impl.util.TransactionContext;
import com.sun.sgs.service.Transaction;
import com.sun.sgs.service.TransactionListener;
import com.sun.sgs.service.store.DataStore;
import java.math.BigInteger;
import java.util.IdentityHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

/** Stores information for a specific transaction. */
final class Context extends TransactionContext implements TransactionListener {

    /** The logger for the data service class. */
    private static final LoggerWrapper logger =
  new LoggerWrapper(Logger.getLogger(DataServiceImpl.class.getName()));

    /** The data service. */
    private final DataServiceImpl service;

    /** The data store. */
    final DataStore store;

    /** The transaction. */
    final Transaction txn;

    /**
     * The number of operations to skip between checks of the consistency of
     * the reference table.
     */
    private final int debugCheckInterval;

    /** Whether to detect modifications. */
    final boolean detectModifications;

    /** Controls serializing classes. */
    final ClassSerialization classSerial;

    /**
     * The number of operations performed -- used to determine when to make
     * checks on the reference table.
     */
    private int count = 0;

    /**
     * Stores information about managed references.  This field is logically
     * part of the ManagedReferenceImpl class.
     */
    final ReferenceTable refs;

    /**
     * A map that records all managed objects that are currently having
     * ManagedObjectRemoval.removingObject called on them, to detect recursion,
     * or null.  Uses identity comparison to avoid confusion by value-based
     * equals methods.
     */
    private IdentityHashMap<ManagedObjectRemoval, Boolean> removing = null;

    /** Creates an instance of this class. */
    Context(DataServiceImpl service,
      DataStore store,
      Transaction txn,
      int debugCheckInterval,
      boolean detectModifications,
      ClassesTable classesTable,
      boolean trackStaleObjects)
    {
  super(txn);
  assert service != null && store != null && txn != null &&
      classesTable != null;
  this.service = service;
  this.store = store;
  this.txn = txn;
  this.debugCheckInterval = debugCheckInterval;
  this.detectModifications = detectModifications;
  refs = new ReferenceTable(trackStaleObjects);
  classSerial = classesTable.createClassSerialization(this.txn);
  txn.registerListener(this);
  if (logger.isLoggable(Level.FINER)) {
      logger.log(Level.FINER, "join tid:{0,number,#}, thread:{1}",
           getTxnId(), Thread.currentThread().getName());
  }
    }

    /* -- Methods for obtaining references -- */

    /** Obtains the reference associated with the specified object. */
    <T> ManagedReferenceImpl<T> getReference(T object) {
  return ManagedReferenceImpl.getReference(this, object);
    }

    /**
     * Finds the existing reference associated with the specified object,
     * returning null if it is not found.  Throws ObjectNotFoundException if
     * the object has been removed.
     */
    <T> ManagedReferenceImpl<T> findReference(T object) {
  return ManagedReferenceImpl.findReference(this, object);
    }

    /**
     * Finds the existing reference associated with the specified object,
     * returning null if it is not found or has been removed.
     */
    <T> ManagedReferenceImpl<T> safeFindReference(T object) {
  return ManagedReferenceImpl.safeFindReference(this, object);
    }

    /** Obtains the reference associated with the specified ID. */
    ManagedReferenceImpl<?> getReference(long oid) {
  return ManagedReferenceImpl.getReference(this, oid);
    }

    /* -- Methods for bindings -- */

    /** Obtains the object associated with the specified internal name. */
    ManagedObject getBinding(String internalName, boolean forUpdate) {
  long id = store.getBinding(txn, internalName);
  assert id >= 0 : "Object ID must not be negative";
  ManagedObject result;
  if (forUpdate) {
      result = (ManagedObject) getReference(id).getForUpdate(false);
  } else {
      result = (ManagedObject) getReference(id).get(false);
  }
  store.setBindingDescription(txn, internalName, result);
  return result;
    }

    /** Sets the object associated with the specified internal name. */
    void setBinding(String internalName, Object object) {
  store.setBindingDescription(txn, internalName, object);
  store.setBinding(txn, internalName, getReference(object).oid);
    }

    /** Removes the object associated with the specified internal name. */
    void removeBinding(String internalName) {
  store.removeBinding(txn, internalName);
    }

    /** Returns the next bound name. */
    String nextBoundName(String internalName) {
  return store.nextBoundName(txn, internalName);
    }

    /* -- Methods for object IDs -- */

    /**
     * Returns the next object ID, or -1 if there are no more objects.  Does
     * not return IDs for removed objects.  Specifying -1 requests the first
     * ID.
     */
    long nextObjectId(long oid) {
  return ManagedReferenceImpl.nextObjectId(this, oid);
    }

    /* -- Methods for TransactionContext -- */

    @Override
    public boolean prepare() throws Exception {
  try {
      isPrepared = true;
      if (logger.isLoggable(Level.FINER)) {
    logger.log(Level.FINER,
         "prepare tid:{0,number,#} returns true");
      }
      return true;
  } catch (Exception e) {
      if (logger.isLoggable(Level.FINER)) {
    logger.logThrow(Level.FINER, e,
        "prepare tid:{0,number,#} throws", getTxnId());
      }
      throw e;
  }
    }

    @Override
    public void commit() {
  try {
      isCommitted = true;
      if (logger.isLoggable(Level.FINER)) {
    logger.log(Level.FINER, "commit tid:{0,number,#} returns",
         getTxnId());
      }
  } catch (RuntimeException e) {
      if (logger.isLoggable(Level.FINER)) {
    logger.logThrow(Level.FINER, e,
        "commit tid:{0,number,#} throws", getTxnId());
      }
      throw e;
  }
    }

    @Override
    public void prepareAndCommit() throws Exception {
  try {
      isCommitted = true;
      if (logger.isLoggable(Level.FINER)) {
    logger.log(Level.FINER,
         "prepareAndCommit tid:{0,number,#} returns",
         getTxnId());
      }
  } catch (RuntimeException e) {
      if (logger.isLoggable(Level.FINER)) {
    logger.logThrow(Level.FINER, e,
        "prepareAndCommit tid:{0,number,#} throws",
        getTxnId());
      }
      throw e;
  }
    }

    @Override
    public void abort(boolean retryable) {
  try {
      if (logger.isLoggable(Level.FINER)) {
    logger.log(Level.FINER, "abort tid:{0,number,#} returns",
         getTxnId());
      }
  } catch (RuntimeException e) {
      if (logger.isLoggable(Level.FINER)) {
    logger.logThrow(Level.FINER, e,
        "abort tid:{0,number,#} throws", getTxnId());
      }
      throw e;
  }
    }

    /* -- Implement TransactionListener -- */

    /**
     * {@inheritDoc} <p>
     *
     * This implementation flushes managed references and marks the transaction
     * inactive so that we'll notice if other beforeCompletion methods attempt
     * to call the data service.
     */
    public void beforeCompletion() {
  ManagedReferenceImpl.flushAll(this);
    }

    /**
     * {@inheritDoc} <p>
     *
     * This implementation does nothing.
     */
    public void afterCompletion(boolean commit) { }

    /** {@inheritDoc} */
    public String getTypeName() {
        return Context.class.getName();
    }

    /* -- Other methods -- */

    /**
     * Checks the consistency of the reference table if the operation count
     * equals the check interval.  Throws an IllegalStateException if it
     * encounters a problem.
     */
    void maybeCheckReferenceTable() {
  if (++count > debugCheckInterval) {
      count = 0;
      ManagedReferenceImpl.checkAllState(this);
  }
    }

    /** Checks that the service is running or shutting down. */
    void checkState() {
  service.checkState();
    }

    /** Calls removingObject on the argument, and checks for recursion. */
    void removingObject(ManagedObjectRemoval object) {
  if (removing == null) {
      removing = new IdentityHashMap<ManagedObjectRemoval, Boolean>();
  }
  if (removing.containsKey(object)) {
      throw new IllegalStateException(
    "Attempt to remove object recursively: " + object);
  }
  try {
      removing.put(object, Boolean.TRUE);
      object.removingObject();
  } finally {
      removing.remove(object);
  }
    }

    /** Returns the ID of the associated transaction as a BigInteger. */
    BigInteger getTxnId() {
  return new BigInteger(1, txn.getId());
    }

    /** Returns whether to delay write locking until commit time. */
    boolean optimisticWriteLocks() {
  return service.optimisticWriteLocks;
    }
}
TOP

Related Classes of com.sun.sgs.impl.service.data.Context

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.