[#8145] Add an UnwrapProvider SPI that allows for unwrapping underlying JDBC types through proprietary APIs

This commit is contained in:
lukaseder 2019-01-02 12:09:53 +01:00
parent d556bf8036
commit ba5077d200
7 changed files with 574 additions and 106 deletions

View File

@ -305,6 +305,12 @@ public interface Configuration extends Serializable {
*/
DiagnosticsListenerProvider[] diagnosticsListenerProviders();
/**
* Get the configured <code>UnwrapperProvider</code> from this
* configuration.
*/
UnwrapperProvider unwrapperProvider();
/**
* Get this configuration's underlying record mapper provider.
*/
@ -691,7 +697,7 @@ public interface Configuration extends Serializable {
Configuration set(DiagnosticsListener... newDiagnosticsListeners);
/**
* Change this configuration to hold a new diagnostics listener providers.
* Change this configuration to hold new diagnostics listener providers.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
@ -702,6 +708,30 @@ public interface Configuration extends Serializable {
*/
Configuration set(DiagnosticsListenerProvider... newDiagnosticsListenerProviders);
/**
* Change this configuration to hold a new unwrapper.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
*
* @param newUnwrapper The new unwrapper to be contained in the changed
* configuration.
* @return The changed configuration.
*/
Configuration set(Unwrapper newUnwrapper);
/**
* Change this configuration to hold a new unwrapper provider.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
*
* @param newUnwrapperProvider The new unwrapper provider to be contained in
* the changed configuration.
* @return The changed configuration.
*/
Configuration set(UnwrapperProvider newUnwrapperProvider);
/**
* Change this configuration to hold a new converter provider.
* <p>
@ -987,6 +1017,25 @@ public interface Configuration extends Serializable {
*/
Configuration derive(DiagnosticsListenerProvider... newDiagnosticsListenerProviders);
/**
* Create a derived configuration from this one, with a new unwrapper.
*
* @param newUnwrapper The new unwrapper to be contained in the derived
* configuration.
* @return The derived configuration.
*/
Configuration derive(Unwrapper newUnwrapper);
/**
* Create a derived configuration from this one, with a new unwrapper
* provider.
*
* @param newUnwrapperProvider The new unwrapper provider to be contained in
* the derived configuration.
* @return The derived configuration.
*/
Configuration derive(UnwrapperProvider newUnwrapperProvider);
/**
* Create a derived configuration from this one, with new converter
* provider.

View File

@ -0,0 +1,78 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
import java.sql.Connection;
import java.sql.Wrapper;
/**
* An unwrapper SPI that can be used to override the default unwrapping
* algorithm.
* <p>
* In some cases, jOOQ needs to get access to the native JDBC driver APIs in
* order to call vendor specific methods, such as Oracle's
* <code>OracleConnection.createARRAY()</code>. jOOQ doesn't expect clients to
* provide a native JDBC {@link Connection} through the
* {@link ConnectionProvider} SPI. Implementations may well provide jOOQ with
* some proxy that implements things like logging, thread-bound
* transactionality, connection pooling, etc.
* <p>
* In order to access the native API, {@link Wrapper#unwrap(Class)} needs to be
* called, or in some cases, when third party libraries do not properly
* implement this contract, some specific methods are called reflectively,
* including:
* <p>
* <ul>
* <li><code>org.springframework.jdbc.datasource.ConnectionProxy#getTargetConnection()</code></li>
* <li><code>org.apache.commons.dbcp.DelegatingConnection#getDelegate()</code></li>
* <li><code>org.jboss.jca.adapters.jdbc.WrappedConnection#getUnderlyingConnection()</code></li>
* <li>...</li>
* </ul>
* <p>
* Not all such third party libraries are "known" to jOOQ, so clients can
* implement their own unwrapper to support theirs.
*
* @author Lukas Eder
*/
public interface Unwrapper {
/**
* Unwrap a wrapped type from a JDBC {@link Wrapper}.
*/
<T> T unwrap(Wrapper wrapper, Class<T> iface);
}

View File

@ -0,0 +1,58 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq;
import java.sql.Wrapper;
/**
* A provider for the {@link Unwrapper} SPI which is used to override the
* default behaviour when unwrapping JDBC types through
* {@link Wrapper#unwrap(Class)}.
*
* @author Lukas Eder
*/
@FunctionalInterface
public interface UnwrapperProvider {
/**
* Provide an unwrapper for JDBC types.
*/
Unwrapper provide();
}

View File

@ -75,6 +75,8 @@ import org.jooq.SQLDialect;
import org.jooq.TransactionListener;
import org.jooq.TransactionListenerProvider;
import org.jooq.TransactionProvider;
import org.jooq.Unwrapper;
import org.jooq.UnwrapperProvider;
import org.jooq.VisitListener;
import org.jooq.VisitListenerProvider;
import org.jooq.conf.Settings;
@ -91,7 +93,6 @@ import org.jooq.impl.Tools.DataCacheKey;
*
* @author Lukas Eder
*/
@SuppressWarnings("deprecation")
public class DefaultConfiguration implements Configuration {
/**
@ -118,6 +119,7 @@ public class DefaultConfiguration implements Configuration {
private transient VisitListenerProvider[] visitListenerProviders;
private transient TransactionListenerProvider[] transactionListenerProviders;
private transient DiagnosticsListenerProvider[] diagnosticsListenerProviders;
private transient UnwrapperProvider unwrapperProvider;
private transient ConverterProvider converterProvider;
// [#7062] Apart from the possibility of containing user defined objects, the data
@ -163,6 +165,11 @@ public class DefaultConfiguration implements Configuration {
null,
null,
null,
null,
null,
null,
null,
null,
dialect,
SettingsTools.defaultSettings(),
null
@ -539,7 +546,14 @@ public class DefaultConfiguration implements Configuration {
* configuration properties in the future, without breaking client code.
* Consider creating a configuration by chaining calls to various
* <code>derive()</code> methods.
*
* @deprecated Use
* {@link #DefaultConfiguration(ConnectionProvider, ExecutorProvider, TransactionProvider, RecordMapperProvider, RecordUnmapperProvider, RecordListenerProvider[], ExecuteListenerProvider[], VisitListenerProvider[], TransactionListenerProvider[], DiagnosticsListenerProvider[], UnwrapperProvider, ConverterProvider, SQLDialect, Settings, Map)}
* instead. This constructor is maintained to provide jOOQ 3.2,
* 3.3, 3.7, 3.8, 3.9, 3.10, 3.11 backwards-compatibility if
* called with reflection from Spring configurations.
*/
@Deprecated
DefaultConfiguration(
ConnectionProvider connectionProvider,
MetaProvider metaProvider,
@ -556,6 +570,59 @@ public class DefaultConfiguration implements Configuration {
Clock clock,
SQLDialect dialect,
Settings settings,
Map<Object, Object> data)
{
this(
connectionProvider,
metaProvider,
executorProvider,
transactionProvider,
recordMapperProvider,
recordUnmapperProvider,
recordListenerProviders,
executeListenerProviders,
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
null,
converterProvider,
clock,
dialect,
settings,
data
);
}
/**
* Create the actual configuration object.
* <p>
* This constructor has been made package-private to allow for adding new
* configuration properties in the future, without breaking client code.
* Consider creating a configuration by chaining calls to various
* <code>derive()</code> methods.
*/
DefaultConfiguration(
ConnectionProvider connectionProvider,
MetaProvider metaProvider,
ExecutorProvider executorProvider,
TransactionProvider transactionProvider,
RecordMapperProvider recordMapperProvider,
RecordUnmapperProvider recordUnmapperProvider,
RecordListenerProvider[] recordListenerProviders,
ExecuteListenerProvider[] executeListenerProviders,
VisitListenerProvider[] visitListenerProviders,
TransactionListenerProvider[] transactionListenerProviders,
DiagnosticsListenerProvider[] diagnosticsListenerProviders,
UnwrapperProvider unwrapperProvider,
ConverterProvider converterProvider,
Clock clock,
SQLDialect dialect,
Settings settings,
Map<Object, Object> data)
@ -571,6 +638,7 @@ public class DefaultConfiguration implements Configuration {
set(visitListenerProviders);
set(transactionListenerProviders);
set(diagnosticsListenerProviders);
set(unwrapperProvider);
set(converterProvider);
set(clock);
@ -625,6 +693,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -649,6 +718,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -678,6 +748,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -702,6 +773,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -731,6 +803,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -760,6 +833,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -789,6 +863,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -818,6 +893,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -847,6 +923,7 @@ public class DefaultConfiguration implements Configuration {
newVisitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -876,6 +953,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
newTransactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -905,6 +983,37 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
newDiagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
dialect,
settings,
data
);
}
@Override
public final Configuration derive(Unwrapper newUnwrapper) {
return derive(new UnwrapperWrapper(newUnwrapper));
}
@Override
public final Configuration derive(UnwrapperProvider newUnwrapperProvider) {
return new DefaultConfiguration(
connectionProvider,
metaProvider,
executorProvider,
transactionProvider,
recordMapperProvider,
recordUnmapperProvider,
recordListenerProviders,
executeListenerProviders,
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
newUnwrapperProvider,
converterProvider,
clock,
@ -929,6 +1038,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
newConverterProvider,
clock,
@ -954,6 +1064,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
newClock,
dialect,
@ -977,6 +1088,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -1001,6 +1113,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders,
transactionListenerProviders,
diagnosticsListenerProviders,
unwrapperProvider,
converterProvider,
clock,
@ -1076,7 +1189,7 @@ public class DefaultConfiguration implements Configuration {
}
@Override
public Configuration set(RecordMapper<?, ?> newRecordMapper) {
public final Configuration set(RecordMapper<?, ?> newRecordMapper) {
return set(new RecordMapperWrapper(newRecordMapper));
}
@ -1087,7 +1200,7 @@ public class DefaultConfiguration implements Configuration {
}
@Override
public Configuration set(RecordUnmapper<?, ?> newRecordUnmapper) {
public final Configuration set(RecordUnmapper<?, ?> newRecordUnmapper) {
return set(new RecordUnmapperWrapper(newRecordUnmapper));
}
@ -1167,6 +1280,19 @@ public class DefaultConfiguration implements Configuration {
return this;
}
@Override
public final Configuration set(Unwrapper newUnwrapper) {
return newUnwrapper != null
? set(new UnwrapperWrapper(newUnwrapper))
: set((UnwrapperProvider) null) ;
}
@Override
public final Configuration set(UnwrapperProvider newUnwrapperProvider) {
this.unwrapperProvider = newUnwrapperProvider;
return this;
}
@Override
public final Configuration set(ConverterProvider newConverterProvider) {
this.converterProvider = newConverterProvider != null
@ -1387,6 +1513,13 @@ public class DefaultConfiguration implements Configuration {
return diagnosticsListenerProviders;
}
@Override
public final UnwrapperProvider unwrapperProvider() {
return unwrapperProvider != null
? unwrapperProvider
: new DefaultUnwrapperProvider();
}
@Override
public final ConverterProvider converterProvider() {
return converterProvider;
@ -1476,6 +1609,10 @@ public class DefaultConfiguration implements Configuration {
oos.writeObject(cloneSerializables(transactionListenerProviders));
oos.writeObject(cloneSerializables(diagnosticsListenerProviders));
oos.writeObject(unwrapperProvider instanceof Serializable
? unwrapperProvider
: null);
oos.writeObject(converterProvider instanceof Serializable
? converterProvider
: null);
@ -1520,6 +1657,7 @@ public class DefaultConfiguration implements Configuration {
visitListenerProviders = (VisitListenerProvider[]) ois.readObject();
transactionListenerProviders = (TransactionListenerProvider[]) ois.readObject();
diagnosticsListenerProviders = (DiagnosticsListenerProvider[]) ois.readObject();
unwrapperProvider = (UnwrapperProvider) ois.readObject();
converterProvider = (ConverterProvider) ois.readObject();
data = new ConcurrentHashMap<Object, Object>();
@ -1572,4 +1710,17 @@ public class DefaultConfiguration implements Configuration {
return (RecordUnmapper<E, R>) newRecordUnmapper;
}
}
private final class UnwrapperWrapper implements UnwrapperProvider {
private final Unwrapper newUnwrapper;
private UnwrapperWrapper(Unwrapper newUnwrapper) {
this.newUnwrapper = newUnwrapper;
}
@Override
public Unwrapper provide() {
return newUnwrapper;
}
}
}

View File

@ -77,8 +77,6 @@ import org.jooq.Update;
import org.jooq.conf.Settings;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.jdbc.JDBCUtils;
import org.jooq.tools.reflect.Reflect;
import org.jooq.tools.reflect.ReflectException;
/**
* A default implementation for the {@link ExecuteContext}.
@ -301,36 +299,16 @@ class DefaultExecuteContext implements ExecuteContext {
}
/**
* [#3696] We shouldn't infinitely attempt to unwrap connections.
*/
private static int maxUnwrappedConnections = 256;
/**
* [#7589] No infinite attempts to unwrap statements, either.
*/
private static int maxUnwrappedStatements = 256;
/**
* Get the registered connection's "target connection" if applicable.
* <p>
* This will try to unwrap any native connection if it has been wrapped with
* any of:
* <ul>
* <li><code>org.springframework.jdbc.datasource.ConnectionProxy</code></li>
* <li><code>org.apache.commons.dbcp.DelegatingConnection</code></li>
* <li><code>org.jboss.jca.adapters.jdbc.WrappedConnection</code></li>
* <li>...</li>
* </ul>
* Get the registered connection's "target connection" through
* {@link Configuration#unwrapperProvider()} if applicable.
* <p>
* It can be safely assumed that such a connection is available once the
* {@link ExecuteContext} has been established, until the statement is
* closed.
*/
static final Connection localTargetConnection() {
static final Connection localTargetConnection(Configuration configuration) {
Connection result = localConnection();
unwrappingLoop:
for (int i = 0; i < maxUnwrappedConnections; i++) {
@ -352,48 +330,7 @@ class DefaultExecuteContext implements ExecuteContext {
// Unwrap nested Spring org.springframework.jdbc.datasource.ConnectionProxy objects
try {
Connection r = Reflect.on(result).call("getTargetConnection").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// Unwrap nested DBCP org.apache.commons.dbcp.DelegatingConnection
try {
Connection r = Reflect.on(result).call("getDelegate").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// [#7641] Unwrap nested org.jboss.jca.adapters.jdbc.WrappedConnection
try {
Connection r = Reflect.on(result).call("getUnderlyingConnection").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// No unwrapping method was found.
break;
}
log.info("Could not unwrap native Connection type. Consider implementing an org.jooq.UnwrapperProvider");
return result;
}
/**
@ -406,11 +343,9 @@ class DefaultExecuteContext implements ExecuteContext {
* <li>...</li>
* </ul>
*/
static final PreparedStatement targetPreparedStatement(PreparedStatement stmt) {
static final PreparedStatement targetPreparedStatement(Configuration configuration, PreparedStatement stmt) {
PreparedStatement result = stmt;
unwrappingLoop:
for (int i = 0; i < maxUnwrappedStatements; i++) {
@ -432,38 +367,7 @@ class DefaultExecuteContext implements ExecuteContext {
// Unwrap nested DBCP org.apache.commons.dbcp.DelegatingPreparedStatement
try {
PreparedStatement r = Reflect.on(result).call("getDelegate").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// [#7641] Unwrap nested org.jboss.jca.adapters.jdbc.WrappedStatement
try {
PreparedStatement r = Reflect.on(result).call("getUnderlyingStatement").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// No unwrapping method was found.
break;
}
log.info("Could not unwrap native PreparedStatement type. Consider implementing an org.jooq.UnwrapperProvider");
return result;
}

View File

@ -0,0 +1,201 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Wrapper;
import org.jooq.Unwrapper;
import org.jooq.UnwrapperProvider;
import org.jooq.tools.reflect.Reflect;
import org.jooq.tools.reflect.ReflectException;
/**
* @author Lukas Eder
*/
final class DefaultUnwrapperProvider implements UnwrapperProvider {
static final Unwrapper INSTANCE = new DefaultUnwrapper();
static final class DefaultUnwrapper implements Unwrapper {
/**
* [#3696] We shouldn't infinitely attempt to unwrap connections.
*/
private static int maxUnwrappedConnections = 256;
/**
* [#7589] No infinite attempts to unwrap statements, either.
*/
private static int maxUnwrappedStatements = 256;
@Override
public <T> T unwrap(Wrapper wrapper, Class<T> iface) {
if (wrapper instanceof Connection)
return unwrap((Connection) wrapper, iface);
else if (wrapper instanceof Statement)
return unwrap((Statement) wrapper, iface);
else
throw new IllegalArgumentException("Cannot unwrap: " + wrapper);
}
@SuppressWarnings("unchecked")
private <T> T unwrap(Connection wrapper, Class<T> iface) {
Connection result = wrapper;
return (T) result;
}
@SuppressWarnings("unchecked")
private <T> T unwrap(Statement wrapper, Class<T> iface) {
Statement result = wrapper;
// Unwrap nested DBCP org.apache.commons.dbcp.DelegatingPreparedStatement
try {
PreparedStatement r = Reflect.on(result).call("getDelegate").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// [#7641] Unwrap nested org.jboss.jca.adapters.jdbc.WrappedStatement
try {
PreparedStatement r = Reflect.on(result).call("getUnderlyingStatement").get();
if (result != r && r != null) {
result = r;
continue unwrappingLoop;
}
}
catch (ReflectException ignore) {}
// No unwrapping method was found.
break;
}
/* [/pro] */
return (T) result;
}
};
@Override
public Unwrapper provide() {
return INSTANCE;
}
}

View File

@ -64,6 +64,8 @@ import org.jooq.SQLDialect;
import org.jooq.TransactionListener;
import org.jooq.TransactionListenerProvider;
import org.jooq.TransactionProvider;
import org.jooq.Unwrapper;
import org.jooq.UnwrapperProvider;
import org.jooq.VisitListener;
import org.jooq.VisitListenerProvider;
import org.jooq.conf.Settings;
@ -175,6 +177,11 @@ public class MockConfiguration implements Configuration {
return delegate.diagnosticsListenerProviders();
}
@Override
public UnwrapperProvider unwrapperProvider() {
return delegate.unwrapperProvider();
}
@Override
public ConverterProvider converterProvider() {
return delegate.converterProvider();
@ -312,6 +319,16 @@ public class MockConfiguration implements Configuration {
return delegate.set(newDiagnosticsListenerProviders);
}
@Override
public Configuration set(Unwrapper newUnwrapper) {
return delegate.set(newUnwrapper);
}
@Override
public Configuration set(UnwrapperProvider newUnwrapperProvider) {
return delegate.set(newUnwrapperProvider);
}
@Override
public Configuration set(ConverterProvider newConverterProvider) {
return delegate.set(newConverterProvider);
@ -444,6 +461,16 @@ public class MockConfiguration implements Configuration {
return delegate.derive(newDiagnosticsListenerProviders);
}
@Override
public Configuration derive(Unwrapper newUnwrapper) {
return delegate.derive(newUnwrapper);
}
@Override
public Configuration derive(UnwrapperProvider newUnwrapperProvider) {
return delegate.derive(newUnwrapperProvider);
}
@Override
public Configuration derive(ConverterProvider newConverterProvider) {
return delegate.derive(newConverterProvider);