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