ExecutorOperationListener.java
/*
*
* The DbUnit Database Testing Framework
* Copyright (C)2002-2026, DbUnit.org
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.dbunit.annotation.runtime;
import java.util.Properties;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.dbunit.ConnectionPreservingOperationListener;
import org.dbunit.IOperationListener;
import org.dbunit.database.IDatabaseConnection;
/**
* The {@link IOperationListener} {@link AnnotatedTestExecutor} installs on the tester for every
* annotation-driven test. A {@link ConnectionPreservingOperationListener} that adds the
* executor's own two pieces of {@code connectionRetrieved} work on top of the inherited
* connection shield: after forwarding to {@code delegate} - the tester's own listener, and the
* documented place for it to configure the connection's {@code DatabaseConfig} (e.g. to enable
* the row count check or set a custom {@code RowCounter}) - it applies {@code @DbUnitProperty}
* values, letting them override whatever {@code delegate} set, then offers the connection to
* {@code onFirstConnectionRetrieved} for the row count check baseline capture (a no-op after
* the first call). Reading {@code DatabaseConfig} last this way means the row count check
* always sees {@code delegate}'s and {@code @DbUnitProperty}'s configuration already applied,
* never a stale value from before either ran. The {@code operationSetUpFinished}/
* {@code operationTearDownFinished} shield - and its caveat that suppressing the callback
* suppresses the delegate's non-close work in it too - is entirely
* {@link ConnectionPreservingOperationListener}'s.
*
* @author Jeff Jensen
* @since 3.6.0
*/
final class ExecutorOperationListener extends ConnectionPreservingOperationListener
{
private final Properties properties;
private final Consumer<IDatabaseConnection> onFirstConnectionRetrieved;
/**
* Creates the listener.
*
* @param properties The {@code @DbUnitProperty} values to apply to each retrieved
* connection's {@code DatabaseConfig}.
* @param protectedConnection Supplies the one connection the executor holds past
* {@code onSetup()} and must not have closed by the delegate; re-read on each
* callback, may return {@code null} until it is resolved.
* @param delegate The tester's own listener to forward every callback to.
* @param onFirstConnectionRetrieved Offered each retrieved connection, after the delegate
* and property application have run; a no-op after the first call.
*/
ExecutorOperationListener(final Properties properties,
final Supplier<IDatabaseConnection> protectedConnection,
final IOperationListener delegate,
final Consumer<IDatabaseConnection> onFirstConnectionRetrieved)
{
super(delegate, protectedConnection);
this.properties = properties;
this.onFirstConnectionRetrieved = onFirstConnectionRetrieved;
}
@Override
public void connectionRetrieved(final IDatabaseConnection connection)
{
super.connectionRetrieved(connection);
AnnotatedTestExecutor.applyProperties(connection, properties);
onFirstConnectionRetrieved.accept(connection);
}
}