diff --git a/jOOQ/src/main/java/org/jooq/Configuration.java b/jOOQ/src/main/java/org/jooq/Configuration.java index 7884981d1a..9bb4287c24 100644 --- a/jOOQ/src/main/java/org/jooq/Configuration.java +++ b/jOOQ/src/main/java/org/jooq/Configuration.java @@ -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 Configuration. *

@@ -154,13 +126,52 @@ public interface Configuration extends Serializable { */ Object data(Object key, Object value); + // ------------------------------------------------------------------------- + // Getters + // ------------------------------------------------------------------------- + /** - * Get the configured ExecuteListenerProvider from this + * Get this configuration's underlying connection provider. + */ + ConnectionProvider connectionProvider(); + + /** + * Get this configuration's underlying record mapper provider. + */ + RecordMapperProvider recordMapperProvider(); + + /** + * Get the configured RecordListenerProviders from this + * configuration. + *

+ * This method allows for retrieving the configured + * RecordListenerProvider 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 + *

+ * + * @return The configured set of record listeners. + * @see RecordListenerProvider + * @see RecordListener + * @see RecordContext + */ + RecordListenerProvider[] recordListenerProviders(); + + /** + * Get the configured ExecuteListenerProviders from this * configuration. *

* This method allows for retrieving the configured * ExecuteListenerProvider 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. - *

- * This method is not thread-safe and should not be used in globally - * available Configuration 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. *

@@ -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. *

* This method is not thread-safe and should not be used in globally * available Configuration 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. + *

+ * This method is not thread-safe and should not be used in globally + * available Configuration 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. + *

+ * This method is not thread-safe and should not be used in globally + * available Configuration 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); } diff --git a/jOOQ/src/main/java/org/jooq/RecordContext.java b/jOOQ/src/main/java/org/jooq/RecordContext.java new file mode 100644 index 0000000000..3c52d0885f --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/RecordContext.java @@ -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 RecordContext. + *

+ * 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}. + *

+ * Unlike {@link Configuration#data()}, these data's lifecycle only matches + * that of a single record manipulation. + * + * @return The custom data. This is never null + * @see RecordListener + */ + Map data(); + + /** + * Get some custom data from this RecordContext. + *

+ * 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}. + *

+ * 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 null if no such data is contained + * in this RecordContext + * @see RecordListener + */ + Object data(Object key); + + /** + * Set some custom data to this RecordContext. + *

+ * 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}. + *

+ * 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 null to unset the custom + * data + * @return The previously set custom data or null 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. + *

+ * Unlike {@link ExecuteContext#type()}, this can only result in any of + * these: + *

+ * + * @see ExecuteType + */ + ExecuteType type(); + + /** + * The UpdatableRecord that is being manipulated. + * + * @return The UpdatableRecord being manipulated. This is never + * null + */ + UpdatableRecord record(); + + /** + * The UpdatableRecord(s) that are being manipulated in batch + * mode. + *

+ * If a single UpdatableRecord is being manipulated in + * non-batch mode, this will return an array of length 1, + * containing that Record. + * + * @return The UpdatableRecord(s) being manipulated. This is + * never null + */ + UpdatableRecord[] batchRecords(); +} diff --git a/jOOQ/src/main/java/org/jooq/RecordListener.java b/jOOQ/src/main/java/org/jooq/RecordListener.java new file mode 100644 index 0000000000..ed2e849463 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/RecordListener.java @@ -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. + *

+ * 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: + *

+ * + * @author Lukas Eder + */ +public interface RecordListener { + + /** + * Called before storing an UpdatableRecord. + *

+ * 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 INSERT or + * UPDATE statement. + * + * @see UpdatableRecord#store() + */ + void storeStart(RecordContext ctx); + + /** + * Called after storing an UpdatableRecord. + *

+ * 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 INSERT or + * UPDATE statement. + * + * @see UpdatableRecord#store() + */ + void storeEnd(RecordContext ctx); + + /** + * Called before inserting an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * prior to inserting. + * + * @see UpdatableRecord#insert() + */ + void insertStart(RecordContext ctx); + + /** + * Called after inserting an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * after inserting. + * + * @see UpdatableRecord#insert() + */ + void insertEnd(RecordContext ctx); + + /** + * Called before updating an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * prior to updating. + * + * @see UpdatableRecord#update() + */ + void updateStart(RecordContext ctx); + + /** + * Called after updating an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * after updating. + * + * @see UpdatableRecord#update() + */ + void updateEnd(RecordContext ctx); + + /** + * Called before deleting an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * prior to deleting. + * + * @see UpdatableRecord#delete() + */ + void deleteStart(RecordContext ctx); + + /** + * Called after deleting an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * after deleting. + * + * @see UpdatableRecord#delete() + */ + void deleteEnd(RecordContext ctx); + + /** + * Called before refreshing an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * prior to refreshing. + * + * @see UpdatableRecord#refresh() + */ + void refreshStart(RecordContext ctx); + + /** + * Called after refreshing an UpdatableRecord. + *

+ * Implementations are allowed to modify {@link RecordContext#record()} + * after refreshing. + * + * @see UpdatableRecord#refresh() + */ + void refreshEnd(RecordContext ctx); +} diff --git a/jOOQ/src/main/java/org/jooq/RecordListenerProvider.java b/jOOQ/src/main/java/org/jooq/RecordListenerProvider.java new file mode 100644 index 0000000000..c290fbebfb --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/RecordListenerProvider.java @@ -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. + *

+ * In order to facilitate the lifecycle management of + * RecordListener 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 RecordListener instance. + *

+ * Implementations are free to choose whether this method returns new + * instances at every call or whether the same instance is returned + * repetitively. + *

+ * A RecordListener shall be provided exactly once per + * UpdatableRecord manipulation, i.e. per + * RecordContext. + * + * @return An RecordListener instance. + * @see RecordListener + * @see RecordContext + * @see DefaultRecordListenerProvider + */ + RecordListener provide(); +} diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java b/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java index d985340d4d..fc8f2291ae 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultConfiguration.java @@ -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 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[] 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(); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index b449a4d363..013ab9017a 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -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) { diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultRecordListenerProvider.java b/jOOQ/src/main/java/org/jooq/impl/DefaultRecordListenerProvider.java new file mode 100644 index 0000000000..6160e4147e --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultRecordListenerProvider.java @@ -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}. + *

+ * 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 + * DefaultRecordListenerProvider from an array of + * RecordListener 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(); + } +}