Skip to content

Commit

Permalink
First attempt
Browse files Browse the repository at this point in the history
  • Loading branch information
mkouba committed May 27, 2020
1 parent 9ef7784 commit 4723aa0
Show file tree
Hide file tree
Showing 18 changed files with 885 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public RegistrationContext getContext() {
return context;
}

BeanProcessor getBeanProcessor() {
public BeanProcessor getBeanProcessor() {
return beanProcessor;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.arc.deployment.staticmethods;

import java.util.List;
import java.util.Set;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.MethodInfo;

import io.quarkus.arc.processor.InterceptorInfo;
import io.quarkus.builder.item.MultiBuildItem;
import io.quarkus.deployment.util.HashUtil;

/**
* Represents an intercepted static method.
*/
public final class InterceptedStaticMethodBuildItem extends MultiBuildItem {

private final MethodInfo method;
private final List<InterceptorInfo> interceptors;
private final Set<AnnotationInstance> bindings;
private final String hash;

InterceptedStaticMethodBuildItem(MethodInfo method, Set<AnnotationInstance> bindings, List<InterceptorInfo> interceptors) {
this.method = method;
this.interceptors = interceptors;
this.bindings = bindings;
this.hash = HashUtil.sha1(method.declaringClass().name().toString() + method.toString());
}

public ClassInfo getTarget() {
return method.declaringClass();
}

public MethodInfo getMethod() {
return method;
}

/**
*
* @return the list of interceptors that should be applied
*/
public List<InterceptorInfo> getInterceptors() {
return interceptors;
}

/**
*
* @return the set of interceptor bindings
*/
public Set<AnnotationInstance> getBindings() {
return bindings;
}

/**
*
* @return a unique hash that could be used to indentify the method
*/
public String getHash() {
return hash;
}

}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.quarkus.arc.test.interceptor.staticmethods;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.Priority;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InterceptorBinding;
import javax.interceptor.InvocationContext;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class InterceptedStaticMethodTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(InterceptMe.class, Simple.class, SimpleInterceptor.class));

@Test
public void testInterceptor() {
assertEquals("OK:PONG", Simple.ping("pong"));
Simple.pong();
assertEquals(1, SimpleInterceptor.VOID_INTERCEPTIONS.get());
}

public static class Simple {

@InterceptMe
public static String ping(String val) {
return val.toUpperCase();
}

@InterceptMe
static void pong() {
}

}

@Priority(1)
@Interceptor
@InterceptMe
static class SimpleInterceptor {

static final AtomicInteger VOID_INTERCEPTIONS = new AtomicInteger();

@AroundInvoke
Object aroundInvoke(InvocationContext ctx) throws Exception {
Object ret = ctx.proceed();
if (ret != null) {
return "OK:" + ctx.proceed();
} else {
VOID_INTERCEPTIONS.incrementAndGet();
return ret;
}
}

}

@InterceptorBinding
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
@interface InterceptMe {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.arc.runtime;

import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class InterceptedStaticMethodsRecorder {

public static final String INTIALIZER_CLASS_NAME = "io.quarkus.arc.runtime.InterceptedStaticMethodsInitializer";

public void callInitializer() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = InterceptedStaticMethodsRecorder.class.getClassLoader();
}
try {
Class.forName(INTIALIZER_CLASS_NAME, true, cl);
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ private Transactional getTransactional(InvocationContext ic) {
private TransactionConfiguration getTransactionConfiguration(InvocationContext ic) {
TransactionConfiguration configuration = ic.getMethod().getAnnotation(TransactionConfiguration.class);
if (configuration == null) {
return ic.getTarget().getClass().getAnnotation(TransactionConfiguration.class);
Object target = ic.getTarget();
if (target == null) {
return null;
}
return target.getClass().getAnnotation(TransactionConfiguration.class);
}
return configuration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
import org.jboss.jandex.MethodInfo;

/**
*
* @author Martin Kouba
* Generates shared annotation literal classes that can be used to represent annotation instances at runtime.
* <p>
* This construct is thread-safe.
*/
class AnnotationLiteralProcessor {
public class AnnotationLiteralProcessor {

private final ComputingCache<Key, Literal> cache;

Expand Down Expand Up @@ -54,7 +55,7 @@ ComputingCache<Key, Literal> getCache() {
* @param targetPackage Target package is only used if annotation literals are not shared
* @return an annotation literal result handle
*/
ResultHandle process(BytecodeCreator bytecode, ClassOutput classOutput, ClassInfo annotationClass,
public ResultHandle process(BytecodeCreator bytecode, ClassOutput classOutput, ClassInfo annotationClass,
AnnotationInstance annotationInstance,
String targetPackage) {
Objects.requireNonNull(annotationClass, "Annotation class not available: " + annotationInstance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ public Collection<ClassInfo> getQualifiers() {
return Collections.unmodifiableCollection(qualifiers.values());
}

public Collection<ClassInfo> getInterceptorBindings() {
return Collections.unmodifiableCollection(interceptorBindings.values());
}

public Collection<ObserverInfo> getObservers() {
return observers;
}
Expand All @@ -366,7 +370,7 @@ BeanResolver getBeanResolver() {
return beanResolver;
}

InterceptorResolver getInterceptorResolver() {
public InterceptorResolver getInterceptorResolver() {
return interceptorResolver;
}

Expand Down Expand Up @@ -422,7 +426,7 @@ AnnotationStore getAnnotationStore() {
return annotationStore;
}

Collection<AnnotationInstance> getAnnotations(AnnotationTarget target) {
public Collection<AnnotationInstance> getAnnotations(AnnotationTarget target) {
return annotationStore.getAnnotations(target);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public static Builder builder() {

private final String name;
private final ResourceOutput output;
private final boolean sharedAnnotationLiterals;
private final AnnotationLiteralProcessor annotationLiterals;
private final ReflectionRegistration reflectionRegistration;
private final List<BeanRegistrar> beanRegistrars;
private final List<ContextRegistrar> contextRegistrars;
Expand Down Expand Up @@ -95,7 +95,7 @@ private BeanProcessor(String name, IndexView index, Collection<BeanDefiningAnnot
this.applicationClassPredicate = applicationClassPredicate;
this.name = name;
this.output = output;
this.sharedAnnotationLiterals = sharedAnnotationLiterals;
this.annotationLiterals = new AnnotationLiteralProcessor(sharedAnnotationLiterals, applicationClassPredicate);
this.generateSources = generateSources;
this.allowMocking = allowMocking;

Expand Down Expand Up @@ -168,8 +168,6 @@ public List<Resource> generateResources(ReflectionRegistration reflectionRegistr
Map<BeanInfo, String> beanToGeneratedName = new HashMap<>();
Map<ObserverInfo, String> observerToGeneratedName = new HashMap<>();

AnnotationLiteralProcessor annotationLiterals = new AnnotationLiteralProcessor(sharedAnnotationLiterals,
applicationClassPredicate);
BeanGenerator beanGenerator = new BeanGenerator(annotationLiterals, applicationClassPredicate, privateMembers,
generateSources, reflectionRegistration, existingClasses, beanToGeneratedName,
injectionPointAnnotationsPredicate);
Expand Down Expand Up @@ -245,6 +243,10 @@ public BeanDeployment getBeanDeployment() {
return beanDeployment;
}

public AnnotationLiteralProcessor getAnnotationLiteralProcessor() {
return annotationLiterals;
}

public BeanDeployment process() throws IOException {
Consumer<BytecodeTransformer> unsupportedBytecodeTransformer = new Consumer<BytecodeTransformer>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @author Martin Kouba
*/
class InterceptorInfo extends BeanInfo implements Comparable<InterceptorInfo> {
public class InterceptorInfo extends BeanInfo implements Comparable<InterceptorInfo> {

private final Set<AnnotationInstance> bindings;

Expand Down
Loading

0 comments on commit 4723aa0

Please sign in to comment.