Author: antelder
Date: Mon Sep 19 11:45:40 2011
New Revision: 1172577

URL: http://svn.apache.org/viewvc?rev=1172577&view=rev
Log:
TUSCANY-3948: Apply patch from Greg Dritschler to support @Remotable on 
implementation class, reference field, or reference setter method

Modified:
    
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
    
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
    
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
    
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
    
tuscany/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java

Modified: 
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java?rev=1172577&r1=1172576&r2=1172577&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ReferenceProcessor.java
 Mon Sep 19 11:45:40 2011
@@ -45,6 +45,7 @@ import org.apache.tuscany.sca.interfaced
 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 
             }
             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) {

Modified: 
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java?rev=1172577&r1=1172576&r2=1172577&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/ServiceProcessor.java
 Mon Sep 19 11:45:40 2011
@@ -195,8 +195,12 @@ public class ServiceProcessor extends Ba
         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 Ba
         } 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;

Modified: 
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java?rev=1172577&r1=1172576&r2=1172577&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/JavaInterfaceFactory.java
 Mon Sep 19 11:45:40 2011
@@ -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

Modified: 
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java?rev=1172577&r1=1172576&r2=1172577&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/interface-java/src/main/java/org/apache/tuscany/sca/interfacedef/java/impl/JavaInterfaceFactoryImpl.java
 Mon Sep 19 11:45:40 2011
@@ -41,8 +41,9 @@ public abstract class JavaInterfaceFacto
     
     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 JavaInterfaceFacto
     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);

Modified: 
tuscany/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java?rev=1172577&r1=1172576&r2=1172577&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/sca-api/src/main/java/org/oasisopen/sca/annotation/Remotable.java
 Mon Sep 19 11:45:40 2011
@@ -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 {
 


Reply via email to