You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2016/03/09 12:40:26 UTC
[3/6] camel git commit: Add support for alternatives in Camel CDI test
Add support for alternatives in Camel CDI test
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1b89ecd9
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1b89ecd9
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1b89ecd9
Branch: refs/heads/master
Commit: 1b89ecd902cfce8b8a074580cfec084de8df582d
Parents: f547565
Author: Antonin Stefanutti <an...@stefanutti.fr>
Authored: Wed Mar 9 12:19:36 2016 +0100
Committer: Antonin Stefanutti <an...@stefanutti.fr>
Committed: Wed Mar 9 12:40:03 2016 +0100
----------------------------------------------------------------------
.../camel/test/cdi/AnnotatedDecorator.java | 78 ++++++++++++++++++++
.../test/cdi/AnnotatedMethodDecorator.java | 70 ++++++++++++++++++
.../camel/test/cdi/AnnotatedTypeDecorator.java | 77 +++++++++++++++++++
.../java/org/apache/camel/test/cdi/Beans.java | 73 ++++++++++++++++++
.../camel/test/cdi/CamelCdiDeployment.java | 10 +++
.../camel/test/cdi/CamelCdiTestExtension.java | 71 ++++++++++++++++++
.../apache/camel/test/cdi/PriorityLiteral.java | 38 ++++++++++
7 files changed, 417 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedDecorator.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedDecorator.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedDecorator.java
new file mode 100644
index 0000000..176f0ae
--- /dev/null
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedDecorator.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.enterprise.inject.spi.Annotated;
+
+class AnnotatedDecorator implements Annotated {
+
+ private final Annotated decorated;
+
+ private final Set<Annotation> annotations;
+
+ AnnotatedDecorator(Annotated decorated, Set<Annotation> annotations) {
+ this.decorated = decorated;
+ this.annotations = annotations;
+ }
+
+ @Override
+ public Type getBaseType() {
+ return decorated.getBaseType();
+ }
+
+ @Override
+ public Set<Type> getTypeClosure() {
+ return decorated.getTypeClosure();
+ }
+
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+ T annotation = getDecoratingAnnotation(annotationType);
+ if (annotation != null) {
+ return annotation;
+ } else {
+ return decorated.getAnnotation(annotationType);
+ }
+ }
+
+ @Override
+ public Set<Annotation> getAnnotations() {
+ Set<Annotation> annotations = new HashSet<>(this.annotations);
+ annotations.addAll(decorated.getAnnotations());
+ return Collections.unmodifiableSet(annotations);
+ }
+
+ @Override
+ public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+ return getDecoratingAnnotation(annotationType) != null || decorated.isAnnotationPresent(annotationType);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Annotation> T getDecoratingAnnotation(Class<T> annotationType) {
+ for (Annotation annotation : annotations) {
+ if (annotationType.isAssignableFrom(annotation.annotationType())) {
+ return (T) annotation;
+ }
+ }
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedMethodDecorator.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedMethodDecorator.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedMethodDecorator.java
new file mode 100644
index 0000000..7ca7171
--- /dev/null
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedMethodDecorator.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.cdi;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+final class AnnotatedMethodDecorator<X> extends AnnotatedDecorator implements AnnotatedMethod<X> {
+
+ private final AnnotatedMethod<X> decoratedMethod;
+
+ AnnotatedMethodDecorator(AnnotatedMethod<X> decoratedMethod, Annotation decoratingAnnotation) {
+ super(decoratedMethod, Collections.singleton(decoratingAnnotation));
+ this.decoratedMethod = decoratedMethod;
+ }
+
+ @Override
+ public Method getJavaMember() {
+ return decoratedMethod.getJavaMember();
+ }
+
+ @Override
+ public boolean isStatic() {
+ return decoratedMethod.isStatic();
+ }
+
+ @Override
+ public AnnotatedType<X> getDeclaringType() {
+ return decoratedMethod.getDeclaringType();
+ }
+
+ @Override
+ public List<AnnotatedParameter<X>> getParameters() {
+ return decoratedMethod.getParameters();
+ }
+
+ @Override
+ public String toString() {
+ return decoratedMethod.toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return decoratedMethod.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ return decoratedMethod.equals(object);
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedTypeDecorator.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedTypeDecorator.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedTypeDecorator.java
new file mode 100644
index 0000000..73af50b
--- /dev/null
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/AnnotatedTypeDecorator.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.cdi;
+
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+
+final class AnnotatedTypeDecorator<X> extends AnnotatedDecorator implements AnnotatedType<X> {
+
+ private final AnnotatedType<X> decoratedType;
+
+ private final Set<AnnotatedMethod<? super X>> decoratedMethods;
+
+ AnnotatedTypeDecorator(AnnotatedType<X> decoratedType, Annotation decoratingAnnotation) {
+ this(decoratedType, decoratingAnnotation, Collections.<AnnotatedMethod<? super X>>emptySet());
+ }
+
+ AnnotatedTypeDecorator(AnnotatedType<X> decoratedType, Annotation decoratingAnnotation, Set<AnnotatedMethod<? super X>> decoratedMethods) {
+ this(decoratedType, Collections.singleton(decoratingAnnotation), decoratedMethods);
+ }
+
+ AnnotatedTypeDecorator(AnnotatedType<X> decoratedType, Set<AnnotatedMethod<? super X>> decoratedMethods) {
+ this(decoratedType, Collections.<Annotation>emptySet(), decoratedMethods);
+ }
+
+ AnnotatedTypeDecorator(AnnotatedType<X> decoratedType, Set<Annotation> decoratingAnnotations, Set<AnnotatedMethod<? super X>> decoratedMethods) {
+ super(decoratedType, decoratingAnnotations);
+ this.decoratedType = decoratedType;
+ this.decoratedMethods = decoratedMethods;
+ }
+
+ @Override
+ public Class<X> getJavaClass() {
+ return decoratedType.getJavaClass();
+ }
+
+ @Override
+ public Set<AnnotatedConstructor<X>> getConstructors() {
+ return decoratedType.getConstructors();
+ }
+
+ @Override
+ public Set<AnnotatedMethod<? super X>> getMethods() {
+ Set<AnnotatedMethod<? super X>> methods = new HashSet<>(decoratedType.getMethods());
+ for (AnnotatedMethod<? super X> method : decoratedMethods) {
+ methods.remove(method);
+ methods.add(method);
+ }
+
+ return Collections.unmodifiableSet(methods);
+ }
+
+ @Override
+ public Set<AnnotatedField<? super X>> getFields() {
+ return decoratedType.getFields();
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/Beans.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/Beans.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/Beans.java
new file mode 100644
index 0000000..611964a
--- /dev/null
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/Beans.java
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.cdi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to be used to customise the deployment configured by the {@code CamelCdiRunner}.
+ *
+ * @see CamelCdiRunner
+ */
+@Documented
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Beans {
+
+ /**
+ * Returns the list of <a href="http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#alternatives">alternatives</a>
+ * to be selected in the application.
+ * <p/>
+ * Note that the declared alternatives are globally selected for the entire
+ * application. For example, if you have the following named bean in your
+ * application:
+ * <pre><code>
+ * {@literal @}Named("foo")
+ * public class FooBean {
+ *
+ * }
+ * </code></pre>
+ *
+ * It can be replaced in your test by declaring the following alternative
+ * bean:
+ * <pre><code>
+ * {@literal @}Alternative
+ * {@literal @}Named("foo")
+ * public class AlternativeBean {
+ *
+ * }
+ * </code></pre>
+ *
+ * And adding the {@code @Beans} annotation to you test class to activate it:
+ * <pre><code>
+ * {@literal @}RunWith(CamelCdiRunner.class)
+ * {@literal @}Beans(alternatives = AlternativeBean.class)
+ * public class TestWithAlternative {
+ *
+ * }
+ * </code></pre>
+ *
+ * @see javax.enterprise.inject.Alternative
+ */
+ Class<?>[] alternatives() default {};
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiDeployment.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiDeployment.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiDeployment.java
index 245c7c7..4142583 100644
--- a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiDeployment.java
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiDeployment.java
@@ -33,6 +33,7 @@ final class CamelCdiDeployment implements TestRule {
CamelCdiDeployment(TestClass test, CamelCdiContext context) {
this.context = context;
+
weld = new Weld()
// TODO: check parallel execution
.containerId("camel-context-cdi")
@@ -41,6 +42,15 @@ final class CamelCdiDeployment implements TestRule {
.beanClasses(test.getJavaClass().getDeclaredClasses())
.addBeanClass(test.getJavaClass())
.addExtension(new CdiCamelExtension());
+
+ if (test.getJavaClass().isAnnotationPresent(Beans.class)) {
+ Beans beans = test.getJavaClass().getAnnotation(Beans.class);
+ weld.addExtension(new CamelCdiTestExtension(beans));
+ for (Class<?> alternative : beans.alternatives()) {
+ weld.addBeanClass(alternative)
+ .addAlternative(alternative);
+ }
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiTestExtension.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiTestExtension.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiTestExtension.java
new file mode 100644
index 0000000..7b7e151
--- /dev/null
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/CamelCdiTestExtension.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.cdi;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Alternative;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.WithAnnotations;
+import javax.interceptor.Interceptor.Priority;
+
+final class CamelCdiTestExtension implements Extension {
+
+ private final Beans beans;
+
+ CamelCdiTestExtension(Beans beans) {
+ this.beans = beans;
+ }
+
+ /**
+ * Activates the alternatives declared with {@code @Beans} globally for the
+ * application.
+ * <p/>
+ * For every types and every methods of every types declared with
+ * {@link Beans#alternatives()}, the {@code Priority} annotation is added
+ * so that the corresponding alternatives are selected globally for the
+ * entire application.
+ *
+ * @see Beans
+ */
+ private <T> void alternatives(@Observes @WithAnnotations(Alternative.class) ProcessAnnotatedType<T> pat) {
+ if (!Arrays.asList(beans.alternatives()).contains(pat.getAnnotatedType().getJavaClass())) {
+ // Only select globally the alternatives that are declared with @Beans
+ return;
+ }
+
+ Set<AnnotatedMethod<? super T>> methods = new HashSet<>();
+ for (AnnotatedMethod<? super T> am : pat.getAnnotatedType().getMethods()) {
+ if (am.isAnnotationPresent(Alternative.class)) {
+ methods.add(new AnnotatedMethodDecorator<>(am, PriorityLiteral.of(Priority.APPLICATION)));
+ }
+ }
+
+ if (pat.getAnnotatedType().isAnnotationPresent(Alternative.class)) {
+ pat.setAnnotatedType(new AnnotatedTypeDecorator<>(pat.getAnnotatedType(),
+ PriorityLiteral.of(Priority.APPLICATION),
+ methods));
+ } else if (!methods.isEmpty()) {
+ pat.setAnnotatedType(new AnnotatedTypeDecorator<>(pat.getAnnotatedType(),
+ methods));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/1b89ecd9/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/PriorityLiteral.java
----------------------------------------------------------------------
diff --git a/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/PriorityLiteral.java b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/PriorityLiteral.java
new file mode 100644
index 0000000..e24ca7b
--- /dev/null
+++ b/components/camel-test-cdi/src/main/java/org/apache/camel/test/cdi/PriorityLiteral.java
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.test.cdi;
+
+import javax.annotation.Priority;
+import javax.enterprise.util.AnnotationLiteral;
+
+final class PriorityLiteral extends AnnotationLiteral<Priority> implements Priority {
+
+ private final int priority;
+
+ private PriorityLiteral(int priority) {
+ this.priority = priority;
+ }
+
+ static PriorityLiteral of(int priority) {
+ return new PriorityLiteral(priority);
+ }
+
+ @Override
+ public int value() {
+ return priority;
+ }
+}
\ No newline at end of file