[#2010] Add listener API to Record / UpdatableRecord - First API draft

This commit is contained in:
Lukas Eder 2013-07-31 11:44:43 +02:00
parent baa109d32e
commit 637488a5ec
7 changed files with 723 additions and 88 deletions

View File

@ -69,37 +69,9 @@ import org.jooq.conf.Settings;
public interface Configuration extends Serializable {
// -------------------------------------------------------------------------
// Getters
// Custom data
// -------------------------------------------------------------------------
/**
* Retrieve the configured dialect.
*/
SQLDialect dialect();
/**
* Get this configuration's underlying connection provider.
*/
ConnectionProvider connectionProvider();
/**
* Get this configuration's underlying record mapper provider.
*/
RecordMapperProvider recordMapperProvider();
/**
* Retrieve the configured schema mapping.
*
* @deprecated - 2.0.5 - Use {@link #settings()} instead
*/
@Deprecated
SchemaMapping schemaMapping();
/**
* Retrieve the runtime configuration settings.
*/
Settings settings();
/**
* Get all custom data from this <code>Configuration</code>.
* <p>
@ -154,13 +126,52 @@ public interface Configuration extends Serializable {
*/
Object data(Object key, Object value);
// -------------------------------------------------------------------------
// Getters
// -------------------------------------------------------------------------
/**
* Get the configured <code>ExecuteListenerProvider</code> from this
* Get this configuration's underlying connection provider.
*/
ConnectionProvider connectionProvider();
/**
* Get this configuration's underlying record mapper provider.
*/
RecordMapperProvider recordMapperProvider();
/**
* Get the configured <code>RecordListenerProvider</code>s from this
* configuration.
* <p>
* This method allows for retrieving the configured
* <code>RecordListenerProvider</code> from this configuration. The
* providers will provide jOOQ with {@link RecordListener} instances. These
* instances receive record manipulation notification events every time jOOQ
* executes queries. jOOQ makes no assumptions about the internal state of
* these listeners, i.e. listener instances may
* <ul>
* <li>share this <code>Configuration</code>'s lifecycle (i.e. that of a
* JDBC <code>Connection</code>, or that of a transaction)</li>
* <li>share the lifecycle of an <code>RecordContext</code> (i.e. that of a
* single record manipulation)</li>
* <li>follow an entirely different lifecycle.</li>
* </ul>
*
* @return The configured set of record listeners.
* @see RecordListenerProvider
* @see RecordListener
* @see RecordContext
*/
RecordListenerProvider[] recordListenerProviders();
/**
* Get the configured <code>ExecuteListenerProvider</code>s from this
* configuration.
* <p>
* This method allows for retrieving the configured
* <code>ExecuteListenerProvider</code> from this configuration. The
* provider will provide jOOQ with {@link ExecuteListener} instances. These
* providers will provide jOOQ with {@link ExecuteListener} instances. These
* instances receive execution lifecycle notification events every time jOOQ
* executes queries. jOOQ makes no assumptions about the internal state of
* these listeners, i.e. listener instances may
@ -183,22 +194,28 @@ public interface Configuration extends Serializable {
*/
ExecuteListenerProvider[] executeListenerProviders();
/**
* Retrieve the configured schema mapping.
*
* @deprecated - 2.0.5 - Use {@link #settings()} instead
*/
@Deprecated
SchemaMapping schemaMapping();
/**
* Retrieve the configured dialect.
*/
SQLDialect dialect();
/**
* Retrieve the runtime configuration settings.
*/
Settings settings();
// -------------------------------------------------------------------------
// Setters
// -------------------------------------------------------------------------
/**
* Change this configuration to hold a new dialect.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
*
* @param newDialect The new dialect to be contained in the changed
* configuration.
* @return The changed configuration.
*/
Configuration set(SQLDialect newDialect);
/**
* Change this configuration to hold a new connection provider.
* <p>
@ -224,16 +241,16 @@ public interface Configuration extends Serializable {
Configuration set(RecordMapperProvider newRecordMapperProvider);
/**
* Change this configuration to hold a new settings.
* Change this configuration to hold a new record listener providers.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
*
* @param newSettings The new settings to be contained in the changed
* configuration.
* @param newRecordListenerProviders The new record listener providers to
* be contained in the changed configuration.
* @return The changed configuration.
*/
Configuration set(Settings newSettings);
Configuration set(RecordListenerProvider... newRecordListenerProviders);
/**
* Change this configuration to hold a new execute listener providers.
@ -247,6 +264,30 @@ public interface Configuration extends Serializable {
*/
Configuration set(ExecuteListenerProvider... newExecuteListenerProviders);
/**
* Change this configuration to hold a new dialect.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
*
* @param newDialect The new dialect to be contained in the changed
* configuration.
* @return The changed configuration.
*/
Configuration set(SQLDialect newDialect);
/**
* Change this configuration to hold a new settings.
* <p>
* This method is not thread-safe and should not be used in globally
* available <code>Configuration</code> objects.
*
* @param newSettings The new settings to be contained in the changed
* configuration.
* @return The changed configuration.
*/
Configuration set(Settings newSettings);
// -------------------------------------------------------------------------
// Derivation methods
// -------------------------------------------------------------------------
@ -259,15 +300,6 @@ public interface Configuration extends Serializable {
*/
Configuration derive();
/**
* Create a derived configuration from this one, with a new dialect.
*
* @param newDialect The new dialect to be contained in the derived
* configuration.
* @return The derived configuration.
*/
Configuration derive(SQLDialect newDialect);
/**
* Create a derived configuration from this one, with a new connection
* provider.
@ -289,16 +321,17 @@ public interface Configuration extends Serializable {
Configuration derive(RecordMapperProvider newRecordMapperProvider);
/**
* Create a derived configuration from this one, with new settings.
* Create a derived configuration from this one, with new record listener
* providers.
*
* @param newSettings The new settings to be contained in the derived
* configuration.
* @param newRecordListenerProviders The new record listener providers to
* be contained in the derived configuration.
* @return The derived configuration.
*/
Configuration derive(Settings newSettings);
Configuration derive(RecordListenerProvider... newRecordListenerProviders);
/**
* Create a derived configuration from this one, with a new execute listener
* Create a derived configuration from this one, with new execute listener
* providers.
*
* @param newExecuteListenerProviders The new execute listener providers to
@ -307,4 +340,21 @@ public interface Configuration extends Serializable {
*/
Configuration derive(ExecuteListenerProvider... newExecuteListenerProviders);
/**
* Create a derived configuration from this one, with a new dialect.
*
* @param newDialect The new dialect to be contained in the derived
* configuration.
* @return The derived configuration.
*/
Configuration derive(SQLDialect newDialect);
/**
* Create a derived configuration from this one, with new settings.
*
* @param newSettings The new settings to be contained in the derived
* configuration.
* @return The derived configuration.
*/
Configuration derive(Settings newSettings);
}

View File

@ -0,0 +1,147 @@
/**
* Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq;
import java.util.Map;
/**
* A context object for {@link UpdatableRecord} manipulation passed to
* registered {@link RecordListener}'s.
*
* @author Lukas Eder
*/
public interface RecordContext {
/**
* Get all custom data from this <code>RecordContext</code>.
* <p>
* This is custom data that was previously set to the record context using
* {@link #data(Object, Object)}. Use custom data if you want to pass data
* between events received by a {@link RecordListener}.
* <p>
* Unlike {@link Configuration#data()}, these data's lifecycle only matches
* that of a single record manipulation.
*
* @return The custom data. This is never <code>null</code>
* @see RecordListener
*/
Map<Object, Object> data();
/**
* Get some custom data from this <code>RecordContext</code>.
* <p>
* This is custom data that was previously set to the record context using
* {@link #data(Object, Object)}. Use custom data if you want to pass data
* between events received by an {@link RecordListener}.
* <p>
* Unlike {@link Configuration#data()}, these data's lifecycle only matches
* that of a single query execution.
*
* @param key A key to identify the custom data
* @return The custom data or <code>null</code> if no such data is contained
* in this <code>RecordContext</code>
* @see RecordListener
*/
Object data(Object key);
/**
* Set some custom data to this <code>RecordContext</code>.
* <p>
* This is custom data that was previously set to the record context using
* {@link #data(Object, Object)}. Use custom data if you want to pass data
* between events received by an {@link RecordListener}.
* <p>
* Unlike {@link Configuration#data()}, these data's lifecycle only matches
* that of a single query execution.
*
* @param key A key to identify the custom data
* @param value The custom data or <code>null</code> to unset the custom
* data
* @return The previously set custom data or <code>null</code> if no data
* was previously set for the given key
* @see RecordListener
*/
Object data(Object key, Object value);
/**
* The configuration wrapped by this context.
*/
Configuration configuration();
/**
* The type of database interaction that is being executed.
* <p>
* Unlike {@link ExecuteContext#type()}, this can only result in any of
* these:
* <ul>
* <li>{@link ExecuteType#BATCH} when calling
* {@link DSLContext#batchStore(UpdatableRecord...) batchStore()},
* {@link DSLContext#batchInsert(UpdatableRecord...) batchInsert()},
* {@link DSLContext#batchUpdate(UpdatableRecord...) batchUpdate()},
* {@link DSLContext#batchDelete(UpdatableRecord...) batchDelete()}.</li>
* <li>{@link ExecuteType#READ} when calling
* {@link UpdatableRecord#refresh() refresh()}</li>
* <li>{@link ExecuteType#WRITE} when calling
* {@link UpdatableRecord#store() store()}, {@link UpdatableRecord#insert()
* insert()}, {@link UpdatableRecord#update() update()},
* {@link UpdatableRecord#delete() delete()}.</li>
* </ul>
*
* @see ExecuteType
*/
ExecuteType type();
/**
* The <code>UpdatableRecord</code> that is being manipulated.
*
* @return The <code>UpdatableRecord</code> being manipulated. This is never
* <code>null</code>
*/
UpdatableRecord<?> record();
/**
* The <code>UpdatableRecord</code>(s) that are being manipulated in batch
* mode.
* <p>
* If a single <code>UpdatableRecord</code> is being manipulated in
* non-batch mode, this will return an array of length <code>1</code>,
* containing that <code>Record</code>.
*
* @return The <code>UpdatableRecord</code>(s) being manipulated. This is
* never <code>null</code>
*/
UpdatableRecord<?>[] batchRecords();
}

View File

@ -0,0 +1,160 @@
/**
* Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq;
/**
* A listener for manipulation events on {@link UpdatableRecord}s.
* <p>
* Users may want to centrally inject custom behaviour when manipulating their
* {@link UpdatableRecord} objects, performing CRUD. This service provider
* allows to hook in callback method implementations for before or after any of
* these methods:
* <ul>
* <li>{@link UpdatableRecord#store()}</li>
* <li>{@link UpdatableRecord#insert()}</li>
* <li>{@link UpdatableRecord#update()}</li>
* <li>{@link UpdatableRecord#delete()}</li>
* <li>{@link UpdatableRecord#refresh()}</li>
* </ul>
*
* @author Lukas Eder
*/
public interface RecordListener {
/**
* Called before storing an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* prior to storing. Note that modifying the record's primary key value may
* influence whether storing results in an <code>INSERT</code> or
* <code>UPDATE</code> statement.
*
* @see UpdatableRecord#store()
*/
void storeStart(RecordContext ctx);
/**
* Called after storing an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* after storing. Note that modifying the record's primary key value may
* influence whether storing results in an <code>INSERT</code> or
* <code>UPDATE</code> statement.
*
* @see UpdatableRecord#store()
*/
void storeEnd(RecordContext ctx);
/**
* Called before inserting an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* prior to inserting.
*
* @see UpdatableRecord#insert()
*/
void insertStart(RecordContext ctx);
/**
* Called after inserting an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* after inserting.
*
* @see UpdatableRecord#insert()
*/
void insertEnd(RecordContext ctx);
/**
* Called before updating an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* prior to updating.
*
* @see UpdatableRecord#update()
*/
void updateStart(RecordContext ctx);
/**
* Called after updating an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* after updating.
*
* @see UpdatableRecord#update()
*/
void updateEnd(RecordContext ctx);
/**
* Called before deleting an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* prior to deleting.
*
* @see UpdatableRecord#delete()
*/
void deleteStart(RecordContext ctx);
/**
* Called after deleting an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* after deleting.
*
* @see UpdatableRecord#delete()
*/
void deleteEnd(RecordContext ctx);
/**
* Called before refreshing an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* prior to refreshing.
*
* @see UpdatableRecord#refresh()
*/
void refreshStart(RecordContext ctx);
/**
* Called after refreshing an <code>UpdatableRecord</code>.
* <p>
* Implementations are allowed to modify {@link RecordContext#record()}
* after refreshing.
*
* @see UpdatableRecord#refresh()
*/
void refreshEnd(RecordContext ctx);
}

View File

@ -0,0 +1,72 @@
/**
* Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq;
import org.jooq.impl.DefaultRecordListenerProvider;
/**
* A provider for {@link RecordListener} instances.
* <p>
* In order to facilitate the lifecycle management of
* <code>RecordListener</code> instances that are provided to a jOOQ
* {@link Configuration}, clients can implement this API. To jOOQ, it is thus
* irrelevant, if execute listeners are stateful or stateless, local to a
* single record or record manipulation, or global to an application.
*
* @author Lukas Eder
* @see RecordListener
* @see Configuration
*/
public interface RecordListenerProvider {
/**
* Provide a <code>RecordListener</code> instance.
* <p>
* Implementations are free to choose whether this method returns new
* instances at every call or whether the same instance is returned
* repetitively.
* <p>
* A <code>RecordListener</code> shall be provided exactly once per
* <code>UpdatableRecord</code> manipulation, i.e. per
* <code>RecordContext</code>.
*
* @return An <code>RecordListener</code> instance.
* @see RecordListener
* @see RecordContext
* @see DefaultRecordListenerProvider
*/
RecordListener provide();
}

View File

@ -51,6 +51,7 @@ import org.jooq.Configuration;
import org.jooq.ConnectionProvider;
import org.jooq.DSLContext;
import org.jooq.ExecuteListenerProvider;
import org.jooq.RecordListenerProvider;
import org.jooq.RecordMapperProvider;
import org.jooq.SQLDialect;
import org.jooq.SchemaMapping;
@ -81,7 +82,8 @@ public class DefaultConfiguration implements Configuration {
// Non-serializable Configuration objects
private transient ConnectionProvider connectionProvider;
private transient RecordMapperProvider recordMapperProvider;
private transient ExecuteListenerProvider[] listenerProviders;
private transient RecordListenerProvider[] recordListenerProviders;
private transient ExecuteListenerProvider[] executeListenerProviders;
// Derived objects
private org.jooq.SchemaMapping mapping;
@ -101,6 +103,7 @@ public class DefaultConfiguration implements Configuration {
this(
new NoConnectionProvider(),
new DefaultRecordMapperProvider(),
new RecordListenerProvider[0],
new ExecuteListenerProvider[0],
SQL99,
SettingsTools.defaultSettings(),
@ -119,6 +122,7 @@ public class DefaultConfiguration implements Configuration {
this(
configuration.connectionProvider(),
configuration.recordMapperProvider(),
configuration.recordListenerProviders(),
configuration.executeListenerProviders(),
configuration.dialect(),
configuration.settings(),
@ -137,14 +141,16 @@ public class DefaultConfiguration implements Configuration {
DefaultConfiguration(
ConnectionProvider connectionProvider,
RecordMapperProvider recordMapperProvider,
ExecuteListenerProvider[] listenerProviders,
RecordListenerProvider[] recordListenerProviders,
ExecuteListenerProvider[] executeListenerProviders,
SQLDialect dialect,
Settings settings,
Map<Object, Object> data)
{
set(connectionProvider);
set(recordMapperProvider);
set(listenerProviders);
set(recordListenerProviders);
set(executeListenerProviders);
set(dialect);
set(settings);
@ -165,20 +171,20 @@ public class DefaultConfiguration implements Configuration {
return new DefaultConfiguration(this);
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration derive(SQLDialect newDialect) {
return new DefaultConfiguration(connectionProvider, recordMapperProvider, listenerProviders, newDialect, settings, data);
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration derive(ConnectionProvider newConnectionProvider) {
return new DefaultConfiguration(newConnectionProvider, recordMapperProvider, listenerProviders, dialect, settings, data);
return new DefaultConfiguration(
newConnectionProvider,
recordMapperProvider,
recordListenerProviders,
executeListenerProviders,
dialect,
settings,
data
);
}
/**
@ -186,15 +192,31 @@ public class DefaultConfiguration implements Configuration {
*/
@Override
public final Configuration derive(RecordMapperProvider newRecordMapperProvider) {
return new DefaultConfiguration(connectionProvider, newRecordMapperProvider, listenerProviders, dialect, settings, data);
return new DefaultConfiguration(
connectionProvider,
newRecordMapperProvider,
recordListenerProviders,
executeListenerProviders,
dialect,
settings,
data
);
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration derive(Settings newSettings) {
return new DefaultConfiguration(connectionProvider, recordMapperProvider, listenerProviders, dialect, newSettings, data);
public Configuration derive(RecordListenerProvider... newRecordListenerProviders) {
return new DefaultConfiguration(
connectionProvider,
recordMapperProvider,
newRecordListenerProviders,
executeListenerProviders,
dialect,
settings,
data
);
}
/**
@ -202,25 +224,74 @@ public class DefaultConfiguration implements Configuration {
*/
@Override
public final Configuration derive(ExecuteListenerProvider... newExecuteListenerProviders) {
return new DefaultConfiguration(connectionProvider, recordMapperProvider, newExecuteListenerProviders, dialect, settings, data);
return new DefaultConfiguration(
connectionProvider,
recordMapperProvider,
recordListenerProviders,
newExecuteListenerProviders,
dialect,
settings,
data
);
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration derive(SQLDialect newDialect) {
return new DefaultConfiguration(
connectionProvider,
recordMapperProvider,
recordListenerProviders,
executeListenerProviders,
newDialect,
settings,
data
);
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration derive(Settings newSettings) {
return new DefaultConfiguration(
connectionProvider,
recordMapperProvider,
recordListenerProviders,
executeListenerProviders,
dialect,
newSettings,
data
);
}
// -------------------------------------------------------------------------
// XXX: Changing configurations
// -------------------------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public final Configuration set(SQLDialect newDialect) {
this.dialect = newDialect;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration set(ConnectionProvider newConnectionProvider) {
this.connectionProvider = newConnectionProvider;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration set(RecordMapperProvider newRecordMapperProvider) {
this.recordMapperProvider = newRecordMapperProvider != null
@ -230,6 +301,9 @@ public class DefaultConfiguration implements Configuration {
return this;
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration set(Settings newSettings) {
this.settings = newSettings != null
@ -240,15 +314,30 @@ public class DefaultConfiguration implements Configuration {
return this;
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration set(ExecuteListenerProvider... newExecuteListenerProviders) {
this.listenerProviders = newExecuteListenerProviders != null
this.executeListenerProviders = newExecuteListenerProviders != null
? newExecuteListenerProviders
: new ExecuteListenerProvider[0];
return this;
}
/**
* {@inheritDoc}
*/
@Override
public final Configuration set(RecordListenerProvider... newRecordListenerProviders) {
this.recordListenerProviders = newRecordListenerProviders != null
? newRecordListenerProviders
: new RecordListenerProvider[0];
return this;
}
// -------------------------------------------------------------------------
// XXX: Getters
// -------------------------------------------------------------------------
@ -323,7 +412,15 @@ public class DefaultConfiguration implements Configuration {
*/
@Override
public final ExecuteListenerProvider[] executeListenerProviders() {
return listenerProviders;
return executeListenerProviders;
}
/**
* {@inheritDoc}
*/
@Override
public RecordListenerProvider[] recordListenerProviders() {
return recordListenerProviders;
}
@Override
@ -353,14 +450,20 @@ public class DefaultConfiguration implements Configuration {
? recordMapperProvider
: null);
ExecuteListenerProvider[] clone = new ExecuteListenerProvider[listenerProviders.length];
oos.writeObject(cloneSerializables(executeListenerProviders));
oos.writeObject(cloneSerializables(recordListenerProviders));
}
private <E> E[] cloneSerializables(E[] array) {
E[] clone = array.clone();
for (int i = 0; i < clone.length; i++) {
if (listenerProviders[i] instanceof Serializable) {
clone[i] = listenerProviders[i];
if (!(clone[i] instanceof Serializable)) {
clone[i] = null;
}
}
oos.writeObject(clone);
return clone;
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
@ -368,6 +471,7 @@ public class DefaultConfiguration implements Configuration {
connectionProvider = (ConnectionProvider) ois.readObject();
recordMapperProvider = (RecordMapperProvider) ois.readObject();
listenerProviders = (ExecuteListenerProvider[]) ois.readObject();
executeListenerProviders = (ExecuteListenerProvider[]) ois.readObject();
recordListenerProviders = (RecordListenerProvider[]) ois.readObject();
}
}

View File

@ -202,7 +202,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
}
public DefaultDSLContext(SQLDialect dialect, Settings settings) {
this(new DefaultConfiguration(new NoConnectionProvider(), null, null, dialect, settings, null));
this(new DefaultConfiguration(new NoConnectionProvider(), null, null, null, dialect, settings, null));
}
public DefaultDSLContext(Connection connection, SQLDialect dialect) {
@ -210,7 +210,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
}
public DefaultDSLContext(Connection connection, SQLDialect dialect, Settings settings) {
this(new DefaultConfiguration(new DefaultConnectionProvider(connection), null, null, dialect, settings, null));
this(new DefaultConfiguration(new DefaultConnectionProvider(connection), null, null, null, dialect, settings, null));
}
public DefaultDSLContext(DataSource datasource, SQLDialect dialect) {
@ -218,7 +218,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
}
public DefaultDSLContext(DataSource datasource, SQLDialect dialect, Settings settings) {
this(new DefaultConfiguration(new DataSourceConnectionProvider(datasource), null, null, dialect, settings, null));
this(new DefaultConfiguration(new DataSourceConnectionProvider(datasource), null, null, null, dialect, settings, null));
}
public DefaultDSLContext(ConnectionProvider connectionProvider, SQLDialect dialect) {
@ -226,7 +226,7 @@ public class DefaultDSLContext implements DSLContext, Serializable {
}
public DefaultDSLContext(ConnectionProvider connectionProvider, SQLDialect dialect, Settings settings) {
this(new DefaultConfiguration(connectionProvider, null, null, dialect, settings, null));
this(new DefaultConfiguration(connectionProvider, null, null, null, dialect, settings, null));
}
public DefaultDSLContext(Configuration configuration) {

View File

@ -0,0 +1,102 @@
/**
* Copyright (c) 2009-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq.impl;
import java.io.Serializable;
import org.jooq.RecordListener;
import org.jooq.RecordListenerProvider;
/**
* A default implementation for {@link RecordListenerProvider}.
* <p>
* This implementation just wraps an instance of {@link RecordListener}, always
* providing the same.
*
* @author Lukas Eder
*/
public class DefaultRecordListenerProvider implements RecordListenerProvider, Serializable {
/**
* Generated UID.
*/
private static final long serialVersionUID = -2122007794302549679L;
/**
* The delegate list.
*/
private final RecordListener listener;
/**
* Convenience method to construct an array of
* <code>DefaultRecordListenerProvider</code> from an array of
* <code>RecordListener</code> instances.
*/
public static RecordListenerProvider[] providers(RecordListener... listeners) {
RecordListenerProvider[] result = new RecordListenerProvider[listeners.length];
for (int i = 0; i < listeners.length; i++) {
result[i] = new DefaultRecordListenerProvider(listeners[i]);
}
return result;
}
/**
* Create a new provider instance from an argument listener.
*
* @param listener The argument listener.
*/
public DefaultRecordListenerProvider(RecordListener listener) {
this.listener = listener;
}
/**
* {@inheritDoc}
*/
@Override
public final RecordListener provide() {
return listener;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return listener.toString();
}
}