From cceea5f1d8538f3e0ceb0632262f33a54fd19398 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 6 Jun 2019 14:38:38 +0200 Subject: [PATCH] [jOOQ/jOOQ#8746] Add support for reversing the listener invocation order In some cases, it may make sense to support reversing the invocation order for some listener lists, e.g. for VisitListener (in this commit), depending on whether we're calling a [action]Start() or an [action]End() event. --- .../java/org/jooq/impl/AbstractContext.java | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java b/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java index d035120da1..cb16cad1ab 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractContext.java @@ -75,6 +75,7 @@ import org.jooq.Table; import org.jooq.VisitContext; import org.jooq.VisitListener; import org.jooq.VisitListenerProvider; +import org.jooq.conf.InvocationOrder; import org.jooq.conf.ParamCastMode; import org.jooq.conf.ParamType; import org.jooq.conf.Settings; @@ -108,7 +109,8 @@ abstract class AbstractContext> extends AbstractScope imple final ScopeStack scopeStack; // [#2665] VisitListener API - final VisitListener[] visitListeners; + private final VisitListener[] visitListenersStart; + private final VisitListener[] visitListenersEnd; private final Deque visitClauses; private final DefaultVisitContext visitContext; private final Deque visitParts; @@ -137,13 +139,13 @@ abstract class AbstractContext> extends AbstractScope imple ; // [#6758] Avoid this allocation if unneeded - this.visitListeners = providers.length > 0 || useInternalVisitListener + VisitListener[] visitListeners = providers.length > 0 || useInternalVisitListener ? new VisitListener[providers.length + (useInternalVisitListener ? 1 : 0)] : null; - if (this.visitListeners != null) { + if (visitListeners != null) { for (int i = 0; i < providers.length; i++) - this.visitListeners[i] = providers[i].provide(); + visitListeners[i] = providers[i].provide(); @@ -153,11 +155,20 @@ abstract class AbstractContext> extends AbstractScope imple this.visitContext = new DefaultVisitContext(); this.visitParts = new ArrayDeque(); this.visitClauses = new ArrayDeque(); + + this.visitListenersStart = configuration.settings().getVisitListenerStartInvocationOrder() == InvocationOrder.DEFAULT + ? visitListeners + : Tools.reverse(visitListeners.clone()); + this.visitListenersEnd = configuration.settings().getVisitListenerEndInvocationOrder() == InvocationOrder.DEFAULT + ? visitListeners + : Tools.reverse(visitListeners.clone()); } else { this.visitContext = null; this.visitParts = null; this.visitClauses = null; + this.visitListenersStart = null; + this.visitListenersEnd = null; } this.forcedParamType = SettingsTools.getStatementType(settings()) == StatementType.STATIC_STATEMENT @@ -193,7 +204,7 @@ abstract class AbstractContext> extends AbstractScope imple // Issue start clause events // ----------------------------------------------------------------- - Clause[] clauses = Tools.isNotEmpty(visitListeners) ? clause(part) : null; + Clause[] clauses = Tools.isNotEmpty(visitListenersStart) ? clause(part) : null; if (clauses != null) for (int i = 0; i < clauses.length; i++) start(clauses[i]); @@ -248,7 +259,7 @@ abstract class AbstractContext> extends AbstractScope imple if (clause != null && visitClauses != null) { visitClauses.addLast(clause); - for (VisitListener listener : visitListeners) + for (VisitListener listener : visitListenersStart) listener.clauseStart(visitContext); } @@ -258,7 +269,7 @@ abstract class AbstractContext> extends AbstractScope imple @Override public final C end(Clause clause) { if (clause != null && visitClauses != null) { - for (VisitListener listener : visitListeners) + for (VisitListener listener : visitListenersEnd) listener.clauseEnd(visitContext); if (visitClauses.removeLast() != clause) @@ -272,7 +283,7 @@ abstract class AbstractContext> extends AbstractScope imple if (visitParts != null) { visitParts.addLast(part); - for (VisitListener listener : visitListeners) + for (VisitListener listener : visitListenersStart) listener.visitStart(visitContext); return visitParts.peekLast(); @@ -284,7 +295,7 @@ abstract class AbstractContext> extends AbstractScope imple private final void end(QueryPart part) { if (visitParts != null) { - for (VisitListener listener : visitListeners) + for (VisitListener listener : visitListenersEnd) listener.visitEnd(visitContext); if (visitParts.removeLast() != part)