Package org.springmodules.prevayler

Source Code of org.springmodules.prevayler.TransactionalSession

package org.springmodules.prevayler;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import org.prevayler.Prevayler;
import org.springmodules.prevayler.callback.PrevaylerCallback;
import org.springmodules.prevayler.configuration.PrevaylerConfiguration;
import org.springmodules.prevayler.support.PrevaylerTransactionException;
import org.springmodules.prevayler.system.PrevalentSystem;
import org.springmodules.prevayler.system.callback.SystemCallback;
import org.springmodules.prevayler.transaction.CompositeTransactionCommand;

/**
* {@link TransactionalPersistenceManager} {@link Session} implementation.
* @author Sergio Bossa
*/
public class TransactionalSession implements Session {
   
    private static final Logger logger = Logger.getLogger(TransactionalSession.class);
   
    private PrevalentSystem system;
    private List executionQueue;
    private boolean flushed;
   
    public TransactionalSession(PrevaylerConfiguration configuration) {
        Prevayler prevayler = configuration.getPrevaylerInstance();
        this.system = (PrevalentSystem) this.deepCopy(prevayler.prevalentSystem());
        this.executionQueue = new LinkedList();
        this.flushed = false;
    }
   
    public Object execute(PrevaylerCallback callback) {
        if (this.flushed) {
            throw new PrevaylerTransactionException("Error: session already flushed and closed.");
        } else {
            // Enqueue a copy of the callback for later execution through prevayler at commit time:
            PrevaylerCallback copiedCallback = (PrevaylerCallback) this.deepCopy(callback);
            this.executionQueue.add(copiedCallback);
            // Locally execute the callback:
            return callback.doInTransaction(this.system);
        }
    }
   
    public Object execute(SystemCallback callback) {
        if (this.flushed) {
            throw new PrevaylerTransactionException("Error: session already flushed and closed.");
        } else {
            // Directly execute the callback into the system:
            return this.system.execute(callback);
            // No need to enqueue because this is a callback to directly executed into the system.
        }
    }
   
    public void flush(Prevayler prevayler) {
        if (this.flushed) {
            throw new PrevaylerTransactionException("Error: session already flushed and closed.");
        } else {
            CompositeTransactionCommand command = new CompositeTransactionCommand(this.executionQueue);
            prevayler.execute(command);
        }
    }
   
    /** Class internals **/
   
    private Object deepCopy(Object target) {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        Object replica = null;
        ObjectOutputStream out = null;
        ObjectInputStream in = null;
        try {
            out = new ObjectOutputStream(buffer);
            out.writeObject(target);
            out.flush();
            in = new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray()));
            replica = in.readObject();
        } catch(Exception ex) {
            throw new PrevaylerTransactionException("Internal transaction error!", ex);
        } finally {
            try {
                if (out != null) out.close();
                if (in != null) in.close();
            } catch (IOException ex) {
                logger.error("Error closing streams!");
            }
        }
        return replica;
    }
}
TOP

Related Classes of org.springmodules.prevayler.TransactionalSession

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.