Skip to content

Commit

Permalink
Merge pull request quarkusio#9472 from stuartwdouglas/7188
Browse files Browse the repository at this point in the history
Make ArC intercept default methods
  • Loading branch information
stuartwdouglas authored May 21, 2020
2 parents bdca912 + d232196 commit 9ef7784
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
import org.objectweb.asm.Opcodes;

/**
*
*
* @author Martin Kouba
* @author Michal Szynkiewicz, [email protected]
*/
Expand Down Expand Up @@ -186,6 +186,14 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str
classLevelBindings, bytecodeTransformerConsumer, transformUnproxyableClasses));
}
}
for (DotName i : classInfo.interfaceNames()) {
ClassInfo interfaceInfo = getClassByName(beanDeployment.getIndex(), i);
if (interfaceInfo != null) {
//interfaces can't have final methods
addInterceptedMethodCandidates(beanDeployment, interfaceInfo, candidates,
classLevelBindings, bytecodeTransformerConsumer, transformUnproxyableClasses);
}
}
return finalMethodsFoundAndNotChanged;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -46,7 +50,7 @@ private Reflections() {
}

/**
*
*
* @param clazz
* @param fieldName
* @return the field declared in the class hierarchy
Expand All @@ -67,7 +71,7 @@ private static Field findFieldInternal(Class<?> clazz, String fieldName) {
}

/**
*
*
* @param clazz
* @param methodName
* @param parameterTypes
Expand All @@ -78,14 +82,32 @@ public static Method findMethod(Class<?> clazz, String methodName, Class<?>... p
}

private static Method findMethodInternal(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
try {
return clazz.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
if (clazz.getSuperclass() != null) {
return findMethodInternal(clazz.getSuperclass(), methodName, parameterTypes);
Class<?> theClass = clazz;
Deque<Class<?>> interfaces = new ArrayDeque<>();
while (theClass != null) {
try {
return theClass.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
interfaces.addAll(Arrays.asList(theClass.getInterfaces()));
theClass = theClass.getSuperclass();
}
}
//look for default methods on interfaces
Set<Class<?>> seen = new HashSet<>(interfaces);
while (!interfaces.isEmpty()) {
Class<?> iface = interfaces.pop();
try {
return iface.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) {
//ignore
}
for (Class<?> extra : iface.getInterfaces()) {
if (seen.add(extra)) {
interfaces.add(extra);
}
}
throw new IllegalArgumentException(e);
}
throw new IllegalArgumentException("Cannot find method " + methodName + Arrays.asList(parameterTypes) + " on " + clazz);
}

public static Constructor<?> findConstructor(Class<?> clazz, Class<?>... parameterTypes) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.quarkus.arc.test.interceptors.defaultmethod;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;

@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@Documented
@InterceptorBinding
public @interface ABinding {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.quarkus.arc.test.interceptors.defaultmethod;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
@ABinding
public class DefaultMethodBean implements DefaultMethodInterface {

public String hello() {
return "hello";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.quarkus.arc.test.interceptors.defaultmethod;

import io.quarkus.arc.Arc;
import io.quarkus.arc.ArcContainer;
import io.quarkus.arc.InstanceHandle;
import io.quarkus.arc.test.ArcTestContainer;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class DefaultMethodInterceptorTest {

@RegisterExtension
public ArcTestContainer container = new ArcTestContainer(ABinding.class, DefaultMethodBean.class,
DefaultMethodInterface.class, MessageInterceptor.class);

@Test
public void testInterception() {
ArcContainer arc = Arc.container();

InstanceHandle<DefaultMethodBean> handle = arc.instance(DefaultMethodBean.class);
DefaultMethodBean simpleBean = handle.get();
Assertions.assertEquals("intercepted:hello", simpleBean.hello());
Assertions.assertEquals("intercepted:default method", simpleBean.defaultMethod());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.quarkus.arc.test.interceptors.defaultmethod;

public interface DefaultMethodInterface {

default String defaultMethod() {
return "default method";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.quarkus.arc.test.interceptors.defaultmethod;

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

@ABinding
@Interceptor
public class MessageInterceptor {

@AroundInvoke
public Object invoke(InvocationContext context) throws Exception {
return "intercepted:" + context.proceed();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.quarkus.it.panache;

import javax.persistence.Entity;

import io.quarkus.hibernate.orm.panache.PanacheEntity;

@Entity
public class Beer extends PanacheEntity {

public String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.quarkus.it.panache;

import java.util.List;

import javax.enterprise.context.ApplicationScoped;
import javax.transaction.Transactional;

import io.quarkus.hibernate.orm.panache.PanacheRepository;

@ApplicationScoped
@Transactional
public class BeerRepository implements PanacheRepository<Beer> {
public List<Beer> findOrdered() {
return find("ORDER BY name").list();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.quarkus.it.panache;

import javax.inject.Inject;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class TransactionalRepositoryTest {

@Inject
BeerRepository beerRepository;

@Test
public void testTransactionalRepository() {
Beer b = new Beer();
b.name = "IPA";
beerRepository.persist(b);

Assertions.assertEquals(1, beerRepository.count());
}

}

0 comments on commit 9ef7784

Please sign in to comment.