001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (c) 2004-2008 Paul Ferraro
004 * 
005 * This library is free software; you can redistribute it and/or modify it 
006 * under the terms of the GNU Lesser General Public License as published by the 
007 * Free Software Foundation; either version 2.1 of the License, or (at your 
008 * option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful, but WITHOUT
011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License 
013 * for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this library; if not, write to the Free Software Foundation, 
017 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018 * 
019 * Contact: ferraro@users.sourceforge.net
020 */
021package net.sf.hajdbc.sql;
022
023import java.util.List;
024import java.util.concurrent.locks.Lock;
025
026/**
027 * An invocation strategy decorator that acquires a list of locks before invocation, and releases them afterward.
028 * @author Paul Ferraro
029 * @param <D> Type of the root object (e.g. driver, datasource)
030 * @param <T> Target object type of the invocation
031 * @param <R> Return type of this invocation
032 */
033public class LockingInvocationStrategy<D, T, R> implements InvocationStrategy<D, T, R>
034{
035        private InvocationStrategy<D, T, R> strategy;
036        private List<Lock> lockList;
037        
038        /**
039         * @param strategy
040         * @param lockList
041         */
042        public LockingInvocationStrategy(InvocationStrategy<D, T, R> strategy, List<Lock> lockList)
043        {
044                this.strategy = strategy;
045                this.lockList = lockList;
046        }
047
048        /**
049         * @see net.sf.hajdbc.sql.InvocationStrategy#invoke(net.sf.hajdbc.sql.SQLProxy, net.sf.hajdbc.sql.Invoker)
050         */
051        @Override
052        public R invoke(SQLProxy<D, T> proxy, Invoker<D, T, R> invoker) throws Exception
053        {
054                for (Lock lock: this.lockList)
055                {
056                        lock.lock();
057                }
058                
059                try
060                {
061                        return this.strategy.invoke(proxy, invoker);
062                }
063                finally
064                {
065                        for (Lock lock: this.lockList)
066                        {
067                                lock.unlock();
068                        }
069                }
070        }
071}