Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* HA-JDBC: High-Availability JDBC
* Copyright (C) 2012 Paul Ferraro
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
package net.sf.hajdbc.invocation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import net.sf.hajdbc.Database;
import net.sf.hajdbc.DatabaseCluster;
import net.sf.hajdbc.ExceptionFactory;
import net.sf.hajdbc.Messages;
import net.sf.hajdbc.dialect.Dialect;
import net.sf.hajdbc.logging.Level;
import net.sf.hajdbc.logging.Logger;
import net.sf.hajdbc.logging.LoggerFactory;
import net.sf.hajdbc.sql.ProxyFactory;
import net.sf.hajdbc.state.StateManager;
/**
* @author paul
*
*/
public class InvokeOnManyInvocationStrategy implements InvocationStrategy
{
private static Logger logger = LoggerFactory.getLogger(InvokeOnManyInvocationStrategy.class);
public static interface ResultsCollector
{
, T, R, E extends Exception> Map.Entry, SortedMap> collectResults(ProxyFactory map, Invoker invoker);
}
private final ResultsCollector collector;
public InvokeOnManyInvocationStrategy(ResultsCollector collector)
{
this.collector = collector;
}
/**
* {@inheritDoc}
*/
@Override
public , T, R, E extends Exception> SortedMap invoke(ProxyFactory factory, Invoker invoker) throws E
{
Map.Entry, SortedMap> results = this.collector.collectResults(factory, invoker);
ExceptionFactory exceptionFactory = factory.getExceptionFactory();
SortedMap resultMap = results.getKey();
SortedMap exceptionMap = results.getValue();
if (!exceptionMap.isEmpty())
{
DatabaseCluster cluster = factory.getDatabaseCluster();
Dialect dialect = cluster.getDialect();
List failedDatabases = new ArrayList(exceptionMap.size());
// Determine which exceptions are due to failures
for (Map.Entry entry: exceptionMap.entrySet())
{
if (exceptionFactory.indicatesFailure(entry.getValue(), dialect))
{
failedDatabases.add(entry.getKey());
}
}
StateManager stateManager = cluster.getStateManager();
// Deactivate failed databases, unless all failed
if (!resultMap.isEmpty() || (failedDatabases.size() < exceptionMap.size()))
{
for (D failedDatabase: failedDatabases)
{
E exception = exceptionMap.remove(failedDatabase);
if (cluster.deactivate(failedDatabase, stateManager))
{
logger.log(Level.ERROR, exception, Messages.DATABASE_DEACTIVATED.getMessage(), failedDatabase, cluster);
}
}
}
if (!exceptionMap.isEmpty())
{
// If primary database threw exception
if (resultMap.isEmpty() || !exceptionMap.headMap(resultMap.firstKey()).isEmpty())
{
D primaryDatabase = exceptionMap.firstKey();
E primaryException = exceptionMap.get(primaryDatabase);
// Deactivate databases with non-matching exceptions
for (Map.Entry entry: exceptionMap.tailMap(primaryDatabase).entrySet())
{
E exception = entry.getValue();
if (!exceptionFactory.equals(exception, primaryException))
{
D database = entry.getKey();
if (cluster.deactivate(database, stateManager))
{
logger.log(Level.ERROR, exception, Messages.DATABASE_INCONSISTENT.getMessage(), database, cluster, primaryException, exception);
}
}
}
// Deactivate databases with results
for (Map.Entry entry: resultMap.entrySet())
{
D database = entry.getKey();
if (cluster.deactivate(database, stateManager))
{
logger.log(Level.ERROR, Messages.DATABASE_INCONSISTENT.getMessage(), database, cluster, primaryException, entry.getValue());
}
}
throw primaryException;
}
}
// Else primary was successful
// Deactivate databases with exceptions
for (Map.Entry entry: exceptionMap.entrySet())
{
D database = entry.getKey();
E exception = entry.getValue();
if (cluster.deactivate(database, stateManager))
{
logger.log(Level.ERROR, exception, Messages.DATABASE_DEACTIVATED.getMessage(), database, cluster);
}
}
}
return resultMap;
}
}