You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by th...@apache.org on 2014/01/02 17:15:25 UTC
[3/3] git commit: TAP5-2029: Copy annotations from service
implementation to proxy
TAP5-2029: Copy annotations from service implementation to proxy
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/28df9e51
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/28df9e51
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/28df9e51
Branch: refs/heads/master
Commit: 28df9e51cbdef90f5768595cfd2992f877c244cf
Parents: 4a818e3
Author: Thiago H. de Paula Figueiredo <th...@apache.org>
Authored: Thu Jan 2 14:14:49 2014 -0200
Committer: Thiago H. de Paula Figueiredo <th...@apache.org>
Committed: Thu Jan 2 14:14:49 2014 -0200
----------------------------------------------------------------------
.../MethodInvocationGetAnnotationSpec.groovy | 85 ++++++++++++++++++++
.../tapestry5/ioc/internal/AdviceModule.java | 41 ++++++++++
.../ioc/internal/AnnotatedServiceInterface.java | 30 +++++++
.../internal/AnnotatedServiceInterfaceImpl.java | 23 ++++++
.../tapestry5/ioc/internal/DecoratorModule.java | 53 ++++++++++++
.../internal/NonAnnotatedServiceInterface.java | 24 ++++++
.../NonAnnotatedServiceInterfaceImpl.java | 28 +++++++
.../tapestry5/ioc/internal/TestAdvice.java | 55 +++++++++++++
8 files changed, 339 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/groovy/ioc/specs/MethodInvocationGetAnnotationSpec.groovy
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/groovy/ioc/specs/MethodInvocationGetAnnotationSpec.groovy b/tapestry-ioc/src/test/groovy/ioc/specs/MethodInvocationGetAnnotationSpec.groovy
new file mode 100644
index 0000000..b4e4c0e
--- /dev/null
+++ b/tapestry-ioc/src/test/groovy/ioc/specs/MethodInvocationGetAnnotationSpec.groovy
@@ -0,0 +1,85 @@
+package ioc.specs
+
+import org.apache.tapestry5.beaneditor.ReorderProperties
+import org.apache.tapestry5.ioc.annotations.Advise
+import org.apache.tapestry5.ioc.internal.AdviceModule
+import org.apache.tapestry5.ioc.internal.AnnotatedServiceInterface
+import org.apache.tapestry5.ioc.internal.DecoratorModule
+import org.apache.tapestry5.ioc.internal.NonAnnotatedServiceInterface
+import org.apache.tapestry5.ioc.internal.TestAdvice
+
+/**
+ * Tests whether MethodAdvice.getAnnotation() is actually returning annotations from
+ * the service implementation methods and not from the service interface ones.
+ * The tests also verify whether the proxy annotations have the service implementation annotations
+ * and whether the service implementation annotations were copied the generated proxy class.
+ * @see TestAdvice
+ */
+class MethodInvocationGetAnnotationSpec extends AbstractRegistrySpecification {
+
+ def "MethodAdvice.getAnnotation() and getMethod() in service decoration"() {
+ when:
+
+ buildRegistry DecoratorModule
+
+ def nonAnnotatedService = registry.getService NonAnnotatedServiceInterface.class
+ def nonAnnotatedResult = nonAnnotatedService.execute(0);
+ def nonAnnotatedMethod = nonAnnotatedService.getClass().getMethod("execute", int.class);
+
+ def annotatedService = registry.getService AnnotatedServiceInterface.class
+ def annotatedResult = annotatedService.execute(0);
+ def annotatedMethod = annotatedService.getClass().getMethod("execute", int.class);
+
+ then:
+ nonAnnotatedMethod != null
+ nonAnnotatedMethod.getAnnotation(Advise.class) != null
+ nonAnnotatedMethod.getAnnotation(Advise.class).id().equals("id")
+ nonAnnotatedMethod.getAnnotation(Advise.class).serviceInterface() == NonAnnotatedServiceInterface.class
+ nonAnnotatedService.getClass().getAnnotation(ReorderProperties.class) != null
+ nonAnnotatedService.getClass().getAnnotation(ReorderProperties.class).value().equals("reorder")
+ nonAnnotatedResult == TestAdvice.ANNOTATION_FOUND
+
+ annotatedMethod != null
+ annotatedMethod.getAnnotation(Advise.class) != null
+ annotatedMethod.getAnnotation(Advise.class).id().equals("id")
+ annotatedMethod.getAnnotation(Advise.class).serviceInterface() == NonAnnotatedServiceInterface.class
+ annotatedService.getClass().getAnnotation(ReorderProperties.class) != null
+ annotatedService.getClass().getAnnotation(ReorderProperties.class).value().equals("reorder")
+ annotatedResult == TestAdvice.ANNOTATION_FOUND
+
+ }
+
+ def "MethodAdvice.getAnnotation() and getMethod() in service advice"() {
+
+ when:
+
+ buildRegistry AdviceModule
+
+ def nonAnnotatedService = registry.getService NonAnnotatedServiceInterface.class
+ def nonAnnotatedResult = nonAnnotatedService.execute(0);
+ def nonAnnotatedMethod = nonAnnotatedService.getClass().getMethod("execute", int.class);
+
+ def annotatedService = registry.getService AnnotatedServiceInterface
+ def annotatedResult = annotatedService.execute(0);
+ def annotatedMethod = annotatedService.getClass().getMethod("execute", int.class);
+
+ then:
+ nonAnnotatedMethod != null
+ nonAnnotatedMethod.getAnnotation(Advise.class) != null
+ nonAnnotatedMethod.getAnnotation(Advise.class).id().equals("id")
+ nonAnnotatedMethod.getAnnotation(Advise.class).serviceInterface() == NonAnnotatedServiceInterface.class
+ nonAnnotatedService.getClass().getAnnotation(ReorderProperties.class) != null
+ nonAnnotatedService.getClass().getAnnotation(ReorderProperties.class).value().equals("reorder")
+ nonAnnotatedResult == TestAdvice.ANNOTATION_FOUND
+
+ annotatedMethod != null
+ annotatedMethod.getAnnotation(Advise.class) != null
+ annotatedMethod.getAnnotation(Advise.class).id().equals("id")
+ annotatedMethod.getAnnotation(Advise.class).serviceInterface() == NonAnnotatedServiceInterface.class
+ annotatedService.getClass().getAnnotation(ReorderProperties.class) != null
+ annotatedService.getClass().getAnnotation(ReorderProperties.class).value().equals("reorder")
+ annotatedResult == TestAdvice.ANNOTATION_FOUND
+
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
new file mode 100644
index 0000000..466b528
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AdviceModule.java
@@ -0,0 +1,41 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+import org.apache.tapestry5.ioc.MethodAdviceReceiver;
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.annotations.Advise;
+
+public class AdviceModule
+{
+
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(NonAnnotatedServiceInterface.class, NonAnnotatedServiceInterfaceImpl.class);
+ binder.bind(AnnotatedServiceInterface.class, AnnotatedServiceInterfaceImpl.class);
+ }
+
+ @Advise(serviceInterface = NonAnnotatedServiceInterface.class)
+ public static void adviseNonAnnotatedServiceInterface(MethodAdviceReceiver methodAdviceReceiver)
+ {
+ methodAdviceReceiver.adviseAllMethods(new TestAdvice());
+ }
+
+ @Advise(serviceInterface = AnnotatedServiceInterface.class)
+ public static void adviseAnnotatedServiceInterface(MethodAdviceReceiver methodAdviceReceiver)
+ {
+ methodAdviceReceiver.adviseAllMethods(new TestAdvice());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterface.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterface.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterface.java
new file mode 100644
index 0000000..e2575fe
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterface.java
@@ -0,0 +1,30 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+import org.apache.tapestry5.beaneditor.ReorderProperties;
+import org.apache.tapestry5.ioc.annotations.Advise;
+import org.apache.tapestry5.ioc.annotations.IntermediateType;
+
+/**
+ * Service definition with annotations so we can test copying the service interface
+ * annotations, both in class and methods, to the service proxy.
+ */
+@ReorderProperties("reorder") // no meaning, just for testing whether the proxy will have it
+public interface AnnotatedServiceInterface {
+
+ @Advise(id = "id", serviceInterface = NonAnnotatedServiceInterface.class)
+ public String execute(@IntermediateType(String.class) int i);
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterfaceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterfaceImpl.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterfaceImpl.java
new file mode 100644
index 0000000..36db723
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AnnotatedServiceInterfaceImpl.java
@@ -0,0 +1,23 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+
+public class AnnotatedServiceInterfaceImpl implements AnnotatedServiceInterface {
+
+ public String execute(int i) {
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DecoratorModule.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DecoratorModule.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DecoratorModule.java
new file mode 100644
index 0000000..ebe972a
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/DecoratorModule.java
@@ -0,0 +1,53 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.annotations.Decorate;
+import org.apache.tapestry5.ioc.services.AspectDecorator;
+import org.apache.tapestry5.ioc.services.AspectInterceptorBuilder;
+
+/**
+ * @author Thiago H. de Paula Figueiredo (http://machina.com.br/thiago)
+ */
+public class DecoratorModule
+{
+
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(NonAnnotatedServiceInterface.class, NonAnnotatedServiceInterfaceImpl.class);
+ binder.bind(AnnotatedServiceInterface.class, AnnotatedServiceInterfaceImpl.class);
+ }
+
+ @Decorate(serviceInterface = AnnotatedServiceInterface.class)
+ public static AnnotatedServiceInterface decorateAnnotated(AnnotatedServiceInterface delegate,
+ AspectDecorator aspectDecorator)
+ {
+ final AspectInterceptorBuilder<AnnotatedServiceInterface> builder = aspectDecorator
+ .createBuilder(AnnotatedServiceInterface.class, delegate, "!");
+ builder.adviseAllMethods(new TestAdvice());
+ return builder.build();
+ }
+
+ @Decorate(serviceInterface = NonAnnotatedServiceInterface.class)
+ public static NonAnnotatedServiceInterface decorateNonAnnotated(
+ NonAnnotatedServiceInterface delegate, AspectDecorator aspectDecorator)
+ {
+ final AspectInterceptorBuilder<NonAnnotatedServiceInterface> builder = aspectDecorator
+ .createBuilder(NonAnnotatedServiceInterface.class, delegate, "!");
+ builder.adviseAllMethods(new TestAdvice());
+ return builder.build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterface.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterface.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterface.java
new file mode 100644
index 0000000..4270d1e
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterface.java
@@ -0,0 +1,24 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+/**
+ * Service definition without any annotations so we can test copying the service implementation
+ * annotations, both in class and methods, to the service proxy.
+ */
+public interface NonAnnotatedServiceInterface {
+
+ public String execute(int i);
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterfaceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterfaceImpl.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterfaceImpl.java
new file mode 100644
index 0000000..efa408d
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/NonAnnotatedServiceInterfaceImpl.java
@@ -0,0 +1,28 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+import org.apache.tapestry5.beaneditor.ReorderProperties;
+import org.apache.tapestry5.ioc.annotations.Advise;
+import org.apache.tapestry5.ioc.annotations.IntermediateType;
+
+@ReorderProperties("reorder") // no meaning, just for testing whether the proxy will have it
+public class NonAnnotatedServiceInterfaceImpl implements NonAnnotatedServiceInterface {
+
+ @Advise(id = "id", serviceInterface = NonAnnotatedServiceInterface.class)
+ public String execute(@IntermediateType(String.class) int i) { // annotation just for checking too
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/28df9e51/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/TestAdvice.java
----------------------------------------------------------------------
diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/TestAdvice.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/TestAdvice.java
new file mode 100644
index 0000000..f7ca811
--- /dev/null
+++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/TestAdvice.java
@@ -0,0 +1,55 @@
+// Copyright 2013 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.ioc.internal;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import org.apache.tapestry5.ioc.annotations.Advise;
+import org.apache.tapestry5.ioc.annotations.IntermediateType;
+import org.apache.tapestry5.plastic.MethodAdvice;
+import org.apache.tapestry5.plastic.MethodInvocation;
+
+final public class TestAdvice implements MethodAdvice {
+
+ public static final String ANNOTATION_FOUND = "Annotation found!";
+
+ public void advise(MethodInvocation invocation) {
+
+ final Method method = invocation.getMethod();
+ boolean annotationFoundInMethod = checkAnnotation(method.getAnnotation(Advise.class));
+ boolean annotationFoundThroughAnnotationProvider = checkAnnotation(invocation.getAnnotation(Advise.class));
+ IntermediateType parameterAnnotation = null;
+ final Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+ if (parameterAnnotations.length > 0 && parameterAnnotations[0].length > 0) {
+ parameterAnnotation = (IntermediateType) parameterAnnotations[0][0];
+ }
+ boolean annotationParameter = parameterAnnotation != null && parameterAnnotation.value() == String.class;
+
+ if (annotationFoundInMethod && annotationFoundThroughAnnotationProvider && annotationParameter)
+ {
+ invocation.setReturnValue(ANNOTATION_FOUND);
+ }
+ else {
+ invocation.proceed();
+ }
+
+ }
+
+ private boolean checkAnnotation(Advise annotation)
+ {
+ return annotation != null && "id".equals(annotation.id()) && NonAnnotatedServiceInterface.class.equals(annotation.serviceInterface());
+ }
+
+}
\ No newline at end of file