summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2011-09-19 11:45:40 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2011-09-19 11:45:40 +0000
commite32b64d161654e654012f343e795d069bcf40ff8 (patch)
tree8687375c3744869fb9779ec5d20176652fe17677 /sca-java-2.x
parent7f5009617f19b9ee4313999f1ac4bf1c4775ed40 (diff)
TUSCANY-3948: Apply patch from Greg Dritschler to support @Remotable on implementation class, reference field, or reference setter method
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1172577 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x')
-rw-r--r--sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java21
-rw-r--r--sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java20
-rw-r--r--sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java10
-rw-r--r--sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java26
-rw-r--r--sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java5
5 files changed, 63 insertions, 19 deletions
diff --git a/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java b/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
index 225099758d..cb612bd224 100644
--- a/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
+++ b/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
@@ -45,6 +45,7 @@ import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.oasisopen.sca.ServiceReference;
import org.oasisopen.sca.annotation.AllowsPassByReference;
import org.oasisopen.sca.annotation.Reference;
+import org.oasisopen.sca.annotation.Remotable;
/**
* Processes an {@link @Reference} annotation, updating the component type with
@@ -219,11 +220,27 @@ public class ReferenceProcessor extends BaseJavaClassVisitor {
}
baseType = JavaIntrospectionHelper.getBusinessInterface(baseType, genericType);
}
+ // The reference can have a Remotable annotation. This forces the interface to be
+ // remotable even if the interface doesn't have a Remotable annotation.
+ boolean forceRemotable = element.getAnnotation(Remotable.class) != null;
+ // If the reference element is a setter method, element.getAnnotation() looks at
+ // the method-level annotations only. Compliance test POJO_8017 puts the
+ // Remotable annotation on the setter method's argument, so we need some special
+ // logic to look at the argument.
+ if (!forceRemotable && element.getElementType() == ElementType.PARAMETER && (element.getAnchor() instanceof Method)) {
+ Annotation argAnnotations[] = ((Method)element.getAnchor()).getParameterAnnotations()[0];
+ for (int j = 0; j < argAnnotations.length; j++) {
+ if (argAnnotations[j].annotationType() == Remotable.class) {
+ forceRemotable = true;
+ break;
+ }
+ }
+ }
try {
- JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(baseType);
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(baseType, forceRemotable);
reference.getInterfaceContract().setInterface(callInterface);
if (callInterface.getCallbackClass() != null) {
- JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass());
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass(), forceRemotable);
reference.getInterfaceContract().setCallbackInterface(callbackInterface);
}
} catch (InvalidInterfaceException e) {
diff --git a/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java b/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
index 6ad2140304..b2aa01ab92 100644
--- a/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
+++ b/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
@@ -195,8 +195,12 @@ public class ServiceProcessor extends BaseJavaClassVisitor {
Service service = assemblyFactory.createService();
JavaInterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
service.setInterfaceContract(interfaceContract);
-
- JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(interfaze);
+
+ // The implementation class can have a Remotable annotation. This forces all service
+ // interfaces to be remotable even if the interfaces do not have a Remotable annotation.
+ boolean forceRemotable = clazz.getAnnotation(Remotable.class) != null;
+
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(interfaze, forceRemotable);
if (name == null) {
String serviceName = interfaze.getSimpleName();
@@ -212,19 +216,11 @@ public class ServiceProcessor extends BaseJavaClassVisitor {
} else {
service.setName(name);
}
-
-
- boolean remotable = clazz.getAnnotation(Remotable.class) != null;
- if (remotable){
- callInterface.setRemotable(true);
- }
+
service.getInterfaceContract().setInterface(callInterface);
if (callInterface.getCallbackClass() != null) {
- JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass());
- if (remotable){
- callbackInterface.setRemotable(true);
- }
+ JavaInterface callbackInterface = javaInterfaceFactory.createJavaInterface(callInterface.getCallbackClass(), forceRemotable);
service.getInterfaceContract().setCallbackInterface(callbackInterface);
}
return service;
diff --git a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
index 4f4e9d8268..55d694d7f8 100644
--- a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
+++ b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
@@ -45,7 +45,15 @@ public interface JavaInterfaceFactory {
* @return
*/
JavaInterface createJavaInterface(Class<?> interfaceClass) throws InvalidInterfaceException;
-
+
+ /**
+ * Creates a new Java interface model from an interface class.
+ * @param interfaceClass the interface class to introspect.
+ * @param forceRemotable allows the caller to force the interface remotable to be remotable.
+ * @return
+ */
+ JavaInterface createJavaInterface(Class<?> interfaceClass, boolean forceRemotable) throws InvalidInterfaceException;
+
/**
* Creates the contents of a Java interface model from an interface class.
* @param javaInterface the Java interface model
diff --git a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
index dbedf1d55a..8229c7812d 100644
--- a/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
+++ b/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
@@ -41,8 +41,9 @@ public abstract class JavaInterfaceFactoryImpl implements JavaInterfaceFactory {
private List<JavaInterfaceVisitor> visitors = new ArrayList<JavaInterfaceVisitor>();
private JavaInterfaceIntrospectorImpl introspector;
- private Map<Class<?>, JavaInterface> cache = Collections.synchronizedMap(new WeakHashMap<Class<?>, JavaInterface>());
-
+ private Map<Class<?>, JavaInterface> normalCache = Collections.synchronizedMap(new WeakHashMap<Class<?>, JavaInterface>());
+ private Map<Class<?>, JavaInterface> forceRemotableCache = Collections.synchronizedMap(new WeakHashMap<Class<?>, JavaInterface>());
+
public JavaInterfaceFactoryImpl() {
introspector = new JavaInterfaceIntrospectorImpl(this);
}
@@ -50,13 +51,32 @@ public abstract class JavaInterfaceFactoryImpl implements JavaInterfaceFactory {
public JavaInterface createJavaInterface() {
return new JavaInterfaceImpl();
}
-
+
public JavaInterface createJavaInterface(Class<?> interfaceClass) throws InvalidInterfaceException {
+ return createJavaInterface(interfaceClass, false);
+ }
+
+ /**
+ * Creates a new Java interface model from an interface class.
+ *
+ * The forceRemotable argument allows the caller to force the interface to be remotable.
+ * The ServiceProcessor and ReferenceProcessor introspectors use this argument to
+ * propagate a @Remotable annotation on an implementation class, field, or setter method
+ * to the corresponding service or reference interface. The remotable flag must be set
+ * on the interface model prior to instrospection since some introspectors build
+ * different models for remotable vs local interfaces. This also means separate caches
+ * must be kept for interfaces that are processed normally vs. those forced to be remotable.
+ */
+ public JavaInterface createJavaInterface(Class<?> interfaceClass, boolean forceRemotable) throws InvalidInterfaceException {
// TODO: Review if the sharing of JavaInterface is ok
synchronized (interfaceClass) {
+ Map<Class<?>, JavaInterface> cache = (forceRemotable ? forceRemotableCache : normalCache);
JavaInterface javaInterface = cache.get(interfaceClass);
if (javaInterface == null) {
javaInterface = createJavaInterface();
+ if (forceRemotable) {
+ javaInterface.setRemotable(true);
+ }
introspector.introspectInterface(javaInterface, interfaceClass);
// Now that all introspection is complete we can mark the interface resolved
javaInterface.setUnresolved(false);
diff --git a/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java b/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java
index 50f3557bed..e7ddbace7d 100644
--- a/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java
+++ b/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java
@@ -5,6 +5,9 @@
package org.oasisopen.sca.annotation;
import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -16,7 +19,7 @@ import java.lang.annotation.Target;
*
* The @Remotable annotation has no attributes.
*/
-@Target(TYPE)
+@Target({TYPE,METHOD,FIELD,PARAMETER})
@Retention(RUNTIME)
public @interface Remotable {