001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (c) 2004-2007 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.sql.SQLException; 024import java.util.NoSuchElementException; 025import java.util.SortedMap; 026import java.util.TreeMap; 027 028import net.sf.hajdbc.Balancer; 029import net.sf.hajdbc.Database; 030import net.sf.hajdbc.DatabaseCluster; 031import net.sf.hajdbc.Messages; 032 033/** 034 * @author Paul Ferraro 035 * @param <D> 036 * @param <T> 037 * @param <R> 038 */ 039public class DatabaseReadInvocationStrategy<D, T, R> implements InvocationStrategy<D, T, R> 040{ 041 /** 042 * @see net.sf.hajdbc.sql.InvocationStrategy#invoke(net.sf.hajdbc.sql.SQLProxy, net.sf.hajdbc.sql.Invoker) 043 */ 044 @Override 045 public R invoke(SQLProxy<D, T> proxy, Invoker<D, T, R> invoker) throws Exception 046 { 047 SortedMap<Database<D>, R> map = this.invokeAll(proxy, invoker); 048 049 return map.get(map.firstKey()); 050 } 051 052 protected SortedMap<Database<D>, R> invokeAll(SQLProxy<D, T> proxy, Invoker<D, T, R> invoker) throws Exception 053 { 054 DatabaseCluster<D> cluster = proxy.getDatabaseCluster(); 055 Balancer<D> balancer = cluster.getBalancer(); 056 057 try 058 { 059 while (true) 060 { 061 Database<D> database = balancer.next(); 062 T object = proxy.getObject(database); 063 064 try 065 { 066 balancer.beforeInvocation(database); 067 068 R result = invoker.invoke(database, object); 069 070 SortedMap<Database<D>, R> resultMap = new TreeMap<Database<D>, R>(); 071 072 resultMap.put(database, result); 073 074 return resultMap; 075 } 076 catch (Exception e) 077 { 078 proxy.handleFailure(database, e); 079 } 080 finally 081 { 082 balancer.afterInvocation(database); 083 } 084 } 085 } 086 catch (NoSuchElementException e) 087 { 088 throw new SQLException(Messages.getMessage(Messages.NO_ACTIVE_DATABASES, cluster)); 089 } 090 } 091}