Package org.syrup.sql

Source Code of org.syrup.sql.SQLWorkSpace

package org.syrup.sql;

import org.syrup.Data;
import org.syrup.Function;
import org.syrup.LogEntry;
import org.syrup.LogEntryTemplate;
import org.syrup.PTask;
import org.syrup.PTaskTemplate;
import org.syrup.Result;
import org.syrup.WorkSpace;
import org.syrup.helpers.ExecutionMonitor;
import org.syrup.jndi.SyrupFactory;

import java.io.Serializable;
import java.sql.Connection;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;
import javax.sql.DataSource;

/**
* Provides a JDBC implementation of a WorkSpace.
*
* @author Robbert van Dalen
*/
public class SQLWorkSpace implements WorkSpace, Serializable, Referenceable
{
    static final String COPYRIGHT = "Copyright 2005 Robbert van Dalen."
        + "At your option, you may copy, distribute, or make derivative works under "
        + "the terms of The Artistic License. This License may be found at "
        + "http://www.opensource.org/licenses/artistic-license.php. "
        + "THERE IS NO WARRANTY; USE THIS PRODUCT AT YOUR OWN RISK.";

    // [TODO: make the datasource operate in the default Transaction context =
    // enable JTA],

    // Do not serialize the dataSource
    private transient DataSource dataSource = null;

    // Do not serialize the sqlImpl
    private transient SQLImpl sqlImpl = null;

    public static final long serialVersionUID = 1;

    private final static Logger logger = Logger.getLogger("org.syrup.sql.SQLWorkSpace");

    /**
     */
    public Reference getReference() throws NamingException
    {
        return new Reference(SQLWorkSpace.class.getName(), new StringRefAddr("Syrup SQL WorkSpace", "default"), SyrupFactory.class.getName(), null);
    }

    /**
     * Returns the DataSource to create JDBC connections from.
     *
     * @return the Datasource to create JDBC connections from.
     */
    protected synchronized DataSource dataSource() throws Exception
    {
        if (dataSource == null)
        {
            dataSource = (DataSource) (new InitialContext().lookup("syrupDataSource"));
        }
        return dataSource;
    }

    /**
     * Returns the JDBC Connection that is used internally.
     *
     * @return The JDBC Connection.
     */
    protected Connection connection() throws Exception
    {
        Connection con = dataSource().getConnection();
        if (con != null)
        {
            con.setAutoCommit(false);
            return con;
        }
        throw new Exception("could not get connection from "
            + dataSource());
    }

    /**
     * Return the SyrupConnection that is used to optimize SQL commands.
     *
     * @return the SyrupConnection
     */
   
    protected SyrupConnection syrupConnection() throws Exception
    {
        return new SyrupConnection(connection());
    }
   
    /**
     * Returns an instance of a SQLImpl. The implementation is fetched using the
     * JDNI initial context with key 'syrupSQLImpl'.
     *
     * @return an instance of a SQLImpl.
     */
    public synchronized SQLImpl sqlImpl()
    {
        if (sqlImpl == null)
        {
            try
            {
                sqlImpl = (SQLImpl) (new InitialContext().lookup("syrupSQLImpl"));
            }
            catch (Exception e)
            {
                logger.log(Level.INFO, "Did not get syrupSQLImpl key via JDNI. Reverted to default SQLImpl implementation");
                // Revert to default implementation.
                sqlImpl = new SQLImpl();
            }
        }
        return sqlImpl;
    }

    /**
     * Returns the read-only SyrupConnection that is used internally.
     *
     * @return The read-only SyrupConnection.
     */
    protected SyrupConnection readConnection() throws Exception
    {
        SyrupConnection c = syrupConnection();
        c.setTransactionIsolation(java.sql.Connection.TRANSACTION_REPEATABLE_READ);
        return c;
    }

    /**
     * Returns the read-write SyrupConnection that is used internally.
     *
     * @return The read-write SyrupConnection Connection.
     */
    protected SyrupConnection writeConnection() throws Exception
    {
        SyrupConnection c = syrupConnection();
        c.setTransactionIsolation(java.sql.Connection.TRANSACTION_SERIALIZABLE);
        return c;
    }

    /**
     */
    public void reset() throws Exception
    {
        SyrupConnection con = null;
       
        try
        {
            con = writeConnection();
            sqlImpl().genericFunctions().reset(con);
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
    }

    /**
     */
    public void set_in_1(Data data) throws Exception
    {
        SyrupConnection con = null;

        try
        {
            con = writeConnection();
            sqlImpl().genericFunctions().set_in_1(data, con);
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
    }

    /**
     */
    public void set_in_2(Data data) throws Exception
    {
        SyrupConnection con = null;

        try
        {
            con = writeConnection();
            sqlImpl().genericFunctions().set_in_2(data, con);
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
    }

    /**
     */
    public Data get_out_1() throws Exception
    {
        SyrupConnection con = null;

        try
        {
            con = writeConnection();
            return sqlImpl().genericFunctions().get_out_1(con);
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
    }

    /**
     */
    public Data get_out_2() throws Exception
    {
        SyrupConnection con = null;

        try
        {
            con = writeConnection();
            return sqlImpl().genericFunctions().get_out_2(con);
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
    }

    /**
     */
    public PTask[] match(PTaskTemplate template) throws Exception
    {
        PTask[] p = null;
        SyrupConnection con = null;

        try
        {
            con = readConnection();
            p = sqlImpl().genericFunctions().match(template, con);
            con.commit();
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
        return p;
    }

    /**
     */
    public org.syrup.Context[] get(PTaskTemplate t) throws Exception
    {
        SyrupConnection con = null;
        org.syrup.Context c[] = null;

        try
        {
            con = readConnection();
            c = sqlImpl().genericFunctions().get(t, con);
            con.commit();
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
        return c;
    }

    /**
     */
    public PTask stop(PTask task) throws Exception
    {
        SyrupConnection con = null;

        try
        {
            con = writeConnection();
            return sqlImpl().genericFunctions().stop(task, con);
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
    }

    /**
     */
    public PTask[] remove(PTask[] tasks) throws Exception
    {
        // Collecting garbage should carefully implemented - but not now.
        throw new Exception("Not implemented.");
    }

    /**
     */
public PTask execute(PTask pt) throws Exception
    {
        // [TODO: scrutinize the control flow - is it correct in all cases?]
        Result r = null;
        org.syrup.Context c = null;
        SyrupConnection con = null;

        String p = null;

        try
        {
            // Register the callee which is the Worker executing the PTask.
            // Request sent to the the Worker are from this point on,
            // Replied.
            p = ExecutionMonitor.checkin(pt.key());
            // Here is a small gap: The Worker can respond to requests but this
            // isn't known to the WorkSpace and thus the address cannot be known
            // by other Workers.
            // Conclusion: no problem here, because the Worker isn't known to
            // anyone.
            try
            {
                // The execution of the PTask has started - make this known to
                // the WorkSpace.
                con = writeConnection();
                c = sqlImpl().executionFunctions().start(pt, p, con);
            }
            finally
            {
                con.rollback();
                sqlImpl().genericFunctions().close(con);
            }
           
            // From here, there are no JDBC Cnnections open, so the Function can run for
            // a long period of time without holding an open Connection.
            if (c != null)
            {
                // Find the Function to execute - could throw an exception if
                // not found.
                Class fClass = Class.forName(c.task().functionClass());
                Function f = (Function) fClass.newInstance();
                // Executes it.
                r = f.execute(c);
            }

            if (r != null)
            {
                // Got a result - commit this to the WorkSpace.
                try
                {
                    con = writeConnection();
                    pt = sqlImpl().executionFunctions().commit_result(r, con);
                }
                finally
                {
                    con.rollback();
                }
            }
            else
            {
                // Got no result. There can be different reasons, but probably
                // there the PTask was already taken by another Worker.
                // Fall through.
            }
        }
        finally
        {
            // Deregister the Worker (could be after failure/execptions like
            // deadlocks). Any Request sent to the Worker get no
            // Reply after deregistering.

            if (p != null)
            {
                    ExecutionMonitor.checkout(pt.key());
                    // Make sure that this Worker (or others) are stopped and
                    // that this is known to the Workspace.
                    stop(pt);
            }
           
        }
        return pt;
    }

    /*
     */
    public LogEntry[] match(LogEntryTemplate template) throws Exception
    {
        LogEntry[] l = null;
        SyrupConnection con = null;

        try
        {
            con = readConnection();
            l = sqlImpl().genericFunctions().match(template, con);
            con.commit();
        }
        finally
        {
            sqlImpl().genericFunctions().close(con);
        }
        return l;
    }
}
TOP

Related Classes of org.syrup.sql.SQLWorkSpace

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.