Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EJBCLIENT-253] Emulate org.jboss.ejb.client.EJBClientContext.registe… #307

Merged
merged 1 commit into from
Sep 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 99 additions & 1 deletion src/main/java/org/jboss/ejb/client/EJBClientContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.Supplier;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -73,6 +74,10 @@ public final class EJBClientContext extends Attachable implements Contextual<EJB

private static final EJBTransportProvider[] NO_TRANSPORT_PROVIDERS = new EJBTransportProvider[0];

private static final EJBClientInterceptor.Registration[] NO_INTERCEPTORS = new EJBClientInterceptor.Registration[0];
private static final AtomicReferenceFieldUpdater<EJBClientContext, EJBClientInterceptor.Registration[]> registrationsUpdater = AtomicReferenceFieldUpdater.newUpdater(EJBClientContext.class, EJBClientInterceptor.Registration[].class, "registrations");
private volatile EJBClientInterceptor.Registration[] registrations = NO_INTERCEPTORS;

/**
* The discovery attribute name which contains the application and module name of the located EJB.
*/
Expand Down Expand Up @@ -329,6 +334,90 @@ static InterceptorList getClassPathInterceptorList() {
}
}

/**
* Register a client interceptor with this client context.
* <p/>
* If the passed <code>clientInterceptor</code> is already added to this context, then this method just returns the
* old {@link org.jboss.ejb.client.EJBClientInterceptor.Registration}.
*
* <p>
* Note: If an interceptor is added or removed after a proxy is used, this will not affect the proxy interceptor list.
*</p>
*
* @param priority the absolute priority of this interceptor (lower runs earlier; higher runs later)
* @param clientInterceptor the interceptor to register
* @return a handle which may be used to later remove this registration
*
* @deprecated Please use EJBClientContext.Builder to manipulate the EJBClientInterceptors.
*/
@Deprecated
public EJBClientInterceptor.Registration registerInterceptor(final int priority, final EJBClientInterceptor clientInterceptor) throws IllegalArgumentException {
Assert.checkNotNullParam("clientInterceptor", clientInterceptor);
final EJBClientInterceptor.Registration newRegistration = new EJBClientInterceptor.Registration(this, clientInterceptor, priority);
EJBClientInterceptor.Registration[] oldRegistrations, newRegistrations;
do {
oldRegistrations = registrations;
for (EJBClientInterceptor.Registration oldRegistration : oldRegistrations) {
if (oldRegistration.getInterceptor() == clientInterceptor) {
if (oldRegistration.compareTo(newRegistration) == 0) {
// This means that a client interceptor which has already been added to this context,
// is being added with the same priority. In such cases, this new registration request
// is effectively a no-op and we just return the old registration
return oldRegistration;
}
}
}
final int length = oldRegistrations.length;
newRegistrations = Arrays.copyOf(oldRegistrations, length + 1);
newRegistrations[length] = newRegistration;
Arrays.sort(newRegistrations);
} while (!registrationsUpdater.compareAndSet(this, oldRegistrations, newRegistrations));
return newRegistration;
}

/**
* Removes the EJBClientInterceptor from current registrations. It is used by EJBClientInterceptor.Registration itself.
* <p>
* Note: If an interceptor is added or removed after a proxy is used, this will not affect the proxy interceptor list.
*</p>
*
* @param registration the EJBClientInterceptor registration handler
*
* @deprecated Please use EJBClientContext.Builder to manipulate the EJBClientInterceptors.
*/
@Deprecated
void removeInterceptor(final EJBClientInterceptor.Registration registration) {
EJBClientInterceptor.Registration[] oldRegistrations, newRegistrations;
do {
oldRegistrations = registrations;
newRegistrations = null;
final int length = oldRegistrations.length;
final int newLength = length - 1;
if (length == 1) {
if (oldRegistrations[0] == registration) {
newRegistrations = NO_INTERCEPTORS;
}
} else {
for (int i = 0; i < length; i++) {
if (oldRegistrations[i] == registration) {
if (i == newLength) {
newRegistrations = Arrays.copyOf(oldRegistrations, newLength);
break;
} else {
newRegistrations = new EJBClientInterceptor.Registration[newLength];
if (i > 0) System.arraycopy(oldRegistrations, 0, newRegistrations, 0, i);
System.arraycopy(oldRegistrations, i + 1, newRegistrations, i, newLength - i);
break;
}
}
}
}
if (newRegistrations == null) {
return;
}
} while (!registrationsUpdater.compareAndSet(this, oldRegistrations, newRegistrations));
}

/**
* Get the context manager. Simply calls the {@code static} method {@link #getContextManager()}.
*
Expand Down Expand Up @@ -740,7 +829,16 @@ InterceptorList getClassPathInterceptors() {
}

InterceptorList getGlobalInterceptors() {
return globalInterceptors;
return globalInterceptors.combine(registeredInterceptors());
}

private InterceptorList registeredInterceptors() {
final EJBClientInterceptor.Registration[] currentRegistrations = this.registrations.clone();
ArrayList<EJBClientInterceptorInformation> al = new ArrayList<>();
for (EJBClientInterceptor.Registration r: currentRegistrations) {
al.add(EJBClientInterceptorInformation.forInstance(r.getInterceptor()));
}
return InterceptorList.ofList(al);
}

Map<String, InterceptorList> getConfiguredPerClassInterceptors() {
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/org/jboss/ejb/client/EJBClientInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,37 @@ default void handleInvocationAsyncFailure(EJBClientInvocationContext context, Ex
default SessionID handleSessionCreation(EJBSessionCreationInvocationContext context) throws Exception {
return context.proceed();
}

/**
* An interceptor registration handle.
*
* @deprecated Please use EJBClientContext.Builder to manipulate the EJBClientInterceptors.
*/
@Deprecated
class Registration implements Comparable<Registration> {
private final EJBClientContext clientContext;
private final EJBClientInterceptor interceptor;
private final int priority;

Registration(final EJBClientContext clientContext, final EJBClientInterceptor interceptor, final int priority) {
this.clientContext = clientContext;
this.interceptor = interceptor;
this.priority = priority;
}

/**
* Remove this registration.
*/
public void remove() {
clientContext.removeInterceptor(this);
}

EJBClientInterceptor getInterceptor() {
return interceptor;
}

public int compareTo(final Registration o) {
return Integer.signum(priority - o.priority);
}
}
}