FileDocCategorySizeDatePackage
Transaction.javaAPI DocExample5793Sat Feb 01 07:26:12 GMT 1997imaginary.persist

Transaction.java

/**
 * The Transaction class is an abstract class implemented by different
 * persistence packages for managing persistence operations on groups
 * of objects.  
 */
package imaginary.persist;

import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

public abstract class Transaction {
    /**
     * The properties to use to initiate the transaction.
     */
    static public Properties properties = null;
    /**
     * The URL used to initiate the transaction
     */
    static public String     url        = null;

    /**
     * Gets an instance of a Transaction subclass based on the URL
     * set by the application.  Currently, only database persistence
     * is supported so all URL's are assumed to be JDBC URL's.
     * @return a new Transaction instance
     */
    static public Transaction getTransaction() throws PersistenceException {
        return new DatabaseTransaction(url, properties);
    }

    /****************** Instance attributes ******************/
    // the list of objects locked by this Transaction.
    private Vector                  objects = new Vector();

    /********************* Constructors **********************/
    /**
     * Creates a new transaction object.
     */
    public Transaction() {
        super();
    }

    /***************** Attribute accessors ******************/
    /**
     * Ties a new Persistent instance to this transactioon.
     * @param p the persistent associated with this transaction
     */
    synchronized void addPersistent(Persistent p) {
        if( !objects.contains(p) ) {
            objects.addElement(p);
        }
    }

    /**
     * @return an array of persistent objects associated with this
     * transaction
     */
    synchronized Persistent[] getPersistents() {
        Persistent[] obs = new Persistent[objects.size()];

        objects.copyInto(obs);
        return obs;
    }

    /**
     * Removes the specified persistent from this transaction
     * @param p the persistent to be removed
     */
    synchronized void removePersistent(Persistent p) {
        if( objects.contains(p) ) {
            objects.removeElement(p);
        }
    }
    
    /*************** Persistence operations ****************/
    /**
     * Aborts any persistence operations in process and allows
     * persistent objects which have already done their operation
     * to take it back.
     */
    public void abort() {
        Persistent[] obs = getPersistents();

        for(int i=0; i<obs.length; i++) {
            try {
                if( obs[i].isSaving() ) {
                    obs[i].abort();
                }
            }
            catch( PersistenceException e ) {
                e.printStackTrace();
            }
        }
    }

    /**
     * This method should be extended in data store specific
     * transaction objects for sending a commit to the data store.
     * Within the Transaction class, it lets all locked objects know
     * that any data store commit was successful.
     * @exception imaginary.persist.PersistenceException An error occurred
     * trying to commit.
     */
    public void commit() throws PersistenceException {
        Persistent[] obs = getPersistents();

        for(int i=0; i<obs.length; i++) {
            if( obs[i].isSaving() ) {
                obs[i].commit();
            }
        }
        // commit done, prepare for new set of modifications
        objects = new Vector();
    }

    /**
     * Calls for the restoration of a particular object using this
     * Transaction.
     * @param p the object to restore using this Transaction
     */
    public void restore(Persistent p) throws PersistenceException {
        p.restore(this);
    }

    /**
     * Calls for the restoration of the specified Persistent using
     * a hashtable of query parameters.
     * @param p the Persistent to restore
     * @param data the query parameters
     * @exception imaginary.persist.PersistenceException An error occurred
     * during restore.
     */
    public void restore(Persistent p, Hashtable data)
    throws PersistenceException {
        p.restore(this, data);
    }

    /**
     * Calls for the restoration of the specified PersistentSet
     * using a hashtable of query parameters.
     * @parameter set a set to be restored
     * @param data the query parameters for the restore
     * @exception imaginary.persist.PersistenceException An error occurred
     * during restore.
     */
    public void restore(PersistentSet set, Hashtable data)
    throws PersistenceException {
        set.restore(this, data);
    }
    
    /**
     * This method goes through and triggers a save on all locked objects.
     * If the saves are all successful, then a commit() is triggered.  If
     * any one of the saves fails, however, then an abort() is triggered.
     * @exception imaginary.persist.PersistenceException An error triggering
     * an abort occurred.
     */
    public void save() throws PersistenceException {
        Persistent[] obs = getPersistents();
        
        for(int i=0; i<obs.length; i++) {
            try {
                if( obs[i].isModified() ) { // only save modified objects
                    obs[i].save();
                }
            }
            catch( PersistenceException e ) {
                abort(); // abort on error
                throw e;
            }
        }
        try {
            commit(); // commit on success
        }
        catch( PersistenceException e ) {
            abort(); // abort if the commit failed
            throw e;
        }
    }
}