2121import static com .google .common .base .Preconditions .checkArgument ;
2222import static java .util .Objects .requireNonNull ;
2323
24+ import java .util .ArrayList ;
2425import java .util .Arrays ;
2526import java .util .HashMap ;
2627import java .util .List ;
4041
4142import com .google .common .base .CharMatcher ;
4243import com .google .common .base .Splitter ;
44+ import com .google .common .base .Throwables ;
4345import com .google .inject .Binder ;
4446import com .typesafe .config .Config ;
4547import com .typesafe .config .ConfigFactory ;
217219 */
218220public class Jdbc implements Jooby .Module {
219221
222+ static final Function <? super Throwable , ? extends Try <? extends Void >> CCE = x -> {
223+ if (x instanceof ClassCastException ) {
224+ StackTraceElement src = x .getStackTrace ()[0 ];
225+ if (src .getFileName () == null || src .getClassName ().equals (Jdbc .class .getName ())) {
226+ return Try .success (null );
227+ }
228+ }
229+ return Try .failure (x );
230+ };
231+
220232 public static Function <String , String > DB_NAME = url -> {
221233 BiFunction <String , String , Tuple2 <String , Map <String , String >>> indexOf = (str , token ) -> {
222234 int i = str .indexOf (token );
@@ -240,7 +252,8 @@ public class Jdbc implements Jooby.Module {
240252 .orElse (parts .get (parts .size () - 1 )));
241253 };
242254
243- private BiConsumer <HikariConfig , Config > conf ;
255+ @ SuppressWarnings ("rawtypes" )
256+ private final List <BiConsumer > callback = new ArrayList <>();
244257
245258 private final String dbref ;
246259
@@ -266,25 +279,51 @@ public Jdbc() {
266279 }
267280
268281 /**
269- * Programmatically configure a {@link HikariConfig}.
282+ * Configurer callback to apply advanced configuration while bootstrapping hibernate:
283+ *
284+ * <pre>{@code
285+ * {
286+ * use(new Jdbc()
287+ * .doWith((HikariConfig conf) -> {
288+ * // do with conf
289+ * })
290+ * .doWith((HikariDataSource ds) -> {
291+ * // do with ds
292+ * })
293+ * );
294+ * }
295+ * }</pre>
270296 *
271- * @param conf Configurer callback.
272- * @return This module.
297+ * @param configurer Configurer callback.
298+ * @return This module
273299 */
274- public Jdbc doWithHikari (final BiConsumer <HikariConfig , Config > conf ) {
275- this .conf = requireNonNull (conf , "Configurer required." );
300+ public < T > Jdbc doWith (final BiConsumer <T , Config > configurer ) {
301+ this .callback . add ( requireNonNull (configurer , "Configurer required." ) );
276302 return this ;
277303 }
278304
279305 /**
280- * Programmatically configure a {@link HikariConfig}.
306+ * Configurer callback to apply advanced configuration while bootstrapping hibernate:
307+ *
308+ * <pre>{@code
309+ * {
310+ * use(new Jdbc()
311+ * .doWith((HikariConfig conf) -> {
312+ * // do with conf
313+ * })
314+ * .doWith((HikariDataSource ds) -> {
315+ * // do with ds
316+ * })
317+ * );
318+ * }
319+ * }</pre>
281320 *
282- * @param conf Configurer callback.
283- * @return This module.
321+ * @param configurer Configurer callback.
322+ * @return This module
284323 */
285- public Jdbc doWithHikari (final Consumer <HikariConfig > conf ) {
286- requireNonNull (conf , "Configurer required." );
287- return doWithHikari (( h , c ) -> conf .accept (h ));
324+ public < T > Jdbc doWith (final Consumer <T > configurer ) {
325+ requireNonNull (configurer , "Configurer required." );
326+ return doWith (( final T b , final Config c ) -> configurer .accept (b ));
288327 }
289328
290329 @ Override
@@ -294,7 +333,7 @@ public void configure(final Env env, final Config config, final Binder binder) {
294333 }
295334
296335 protected void configure (final Env env , final Config config , final Binder binder ,
297- final BiConsumer <String , HikariDataSource > callback ) {
336+ final BiConsumer <String , HikariDataSource > extensions ) {
298337 Config dbconf ;
299338 String url , dbname , dbkey ;
300339 boolean seturl = false ;
@@ -318,12 +357,10 @@ protected void configure(final Env env, final Config config, final Binder binder
318357 props .setProperty ("url" , url );
319358 }
320359
321- if (conf != null ) {
322- conf .accept (hikariConf , config );
323- }
324-
325360 HikariDataSource ds = new HikariDataSource (hikariConf );
326- callback .accept (dbname , ds );
361+ callback (ds , config );
362+
363+ extensions .accept (dbname , ds );
327364
328365 env .serviceKey ()
329366 .generate (DataSource .class , dbname , k -> binder .bind (k ).toInstance (ds ));
@@ -415,6 +452,13 @@ private HikariConfig hikariConfig(final String url, final String key, final Stri
415452 return new HikariConfig (props );
416453 }
417454
455+ @ SuppressWarnings ("unchecked" )
456+ protected void callback (final Object value , final Config conf ) {
457+ this .callback .forEach (it -> Try .run (() -> it .accept (value , conf ))
458+ .recoverWith (CCE )
459+ .getOrElseThrow (Throwables ::propagate ));
460+ }
461+
418462 private Optional <String > dbtype (final String url , final Config config ) {
419463 String type = Arrays .stream (url .toLowerCase ().split (":" ))
420464 .filter (token -> !(token .equals ("jdbc" ) || token .equals ("jtds" )))
0 commit comments