Author: bdekruijff at gmail.com
Date: Mon Dec 20 13:25:27 2010
New Revision: 515

Log:
[sandbox] Spec compliance and some code improvements

Added:
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/internal/ClassLoaderAdaptor.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/internal/DistributionUtilities.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/NonRemotableService.java
   sandbox/bdekruijff/fabric/src/test/java/org/
   sandbox/bdekruijff/fabric/src/test/java/org/amdatu/
   sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/
   sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/fabric/
   sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/fabric/remote/
   
sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/fabric/remote/service/
   
sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/fabric/remote/service/DistributionUtilitiesTest.java
Modified:
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/cluster/service/tribes/ClusterMemberServiceImpl.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/osgi/Activator.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/DistributionService.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/ServiceEndPoint.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/service/DistributionServiceImpl.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/internal/RemotableServiceImpl.java
   
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/service/FabricTestServiceImpl.java

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/cluster/service/tribes/ClusterMemberServiceImpl.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/cluster/service/tribes/ClusterMemberServiceImpl.java
 (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/cluster/service/tribes/ClusterMemberServiceImpl.java
 Mon Dec 20 13:25:27 2010
@@ -94,8 +94,10 @@
         // TODO check and wrap message. Look into send options
         if (message instanceof Serializable) {
             try {
-                m_managedChannel.send(m_managedChannel.getMembers(), 
(Serializable) message,
-                    Channel.SEND_OPTIONS_ASYNCHRONOUS);
+                Member[] members = m_managedChannel.getMembers();
+                if (members.length > 0)
+                    m_managedChannel.send(members, (Serializable) message,
+                        Channel.SEND_OPTIONS_ASYNCHRONOUS);
             }
             catch (ChannelException e) {
                 e.printStackTrace();

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/osgi/Activator.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/osgi/Activator.java
  (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/osgi/Activator.java
  Mon Dec 20 13:25:27 2010
@@ -90,16 +90,22 @@
 
         // DistributionService
 
+        Dictionary<String, Object> distributionProps = new Hashtable<String, 
Object>();
+
         manager.add(
             createComponent()
                 .setImplementation(new DistributionServiceImpl())
-                .setInterface(DistributionService.class.getName(), cm1props)
+                .setInterface(DistributionService.class.getName(), 
distributionProps)
                 .add(
                     
createServiceDependency().setService(ClusterMemberService.class).setRequired(true))
                 .add(
                     
createServiceDependency().setService(ClusterMessageService.class).setRequired(true))
                 .add(
-                    createServiceDependency().setService("(" + 
DistributionService.REMOTABLE_PROP + "=true)")
+                    createServiceDependency()
+                        .setService(
+                            "("
+                                + 
DistributionService.SERVICE_EXPORTED_CONFIGS_PROP + "="
+                                + 
DistributionService.SERVICE_CONFIGURATION_TYPE + ")")
                         .setCallbacks("localRemotableServiceAdded", 
"localRemotableServiceRemoved")
                         .setRequired(false))
                 .add(

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/DistributionService.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/DistributionService.java
      (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/DistributionService.java
      Mon Dec 20 13:25:27 2010
@@ -18,8 +18,31 @@
 
 public interface DistributionService {
 
-    static final String REMOTE_TOPIC = "org.amdatu.fabric.remote.REMOTE";
-    final static String REMOTABLE_PROP = "org.amdatu.fabric.remote.REMOTABLE";
-    final static String REMOTE_PROP = "org.amdatu.fabric.remote.REMOTE";
+    final static String REMOTE_TOPIC = "org.amdatu.fabric.remote.REMOTE";
+
+    // see OSGi R42 spec 13.5.1
+    // FIXME we are not actually doing anything to support these intents
+    final static String DISTRIBUTION_INTENT_AUTHENTICATION = "authentication";
+    final static String DISTRIBUTION_INTENT_CONFIDENTIALITY = 
"confidentiality";
+    final static String DISTRIBUTION_INTENT_INTEGRITY = "integrity";
+    final static String[] DISTRIBUTION_INTENTS_SUPPORTED = new String[] { 
DISTRIBUTION_INTENT_AUTHENTICATION,
+        DISTRIBUTION_INTENT_CONFIDENTIALITY,
+        DISTRIBUTION_INTENT_INTEGRITY };
+
+    final static String DISTRIBUTION_INTENTS_SUPPORTED_PROP = 
"remote.intents.supported";
+    final static String DISTRIBUTION_CONFIGS_SUPPORTED_PROP = 
"remote.configs.supported";
+
+    final static String[] DISTRIBUTION_CONFIGS_SUPPORTED = new String[] { 
"org.amdatu.core.fabric" };
+
+    final static String SERVICE_INTENTS_PROP = "service.intents";
+    final static String SERVICE_CONFIGURATION_TYPE = "org.amdatu.core.fabric";
+
+    final static String SERVICE_EXPORTED_CONFIGS_PROP = 
"service.exported.configs";
+    final static String SERVICE_EXPORTED_INTENTS_PROP = 
"service.exported.intent";
+    final static String SERVICE_EXPORTED_INTENTS_EXTRA_PROP = 
"service.exported.intents.extra";
+    final static String SERVICE_EXPORTED_INTERFACES_PROP = 
"service.exported.iterfaces";
+
+    final static String SERVICE_IMPORTED_PROP = "service.imported";
+    final static String SERVICE_IMPORTED_CONFIGS_PROP = 
"service.imported.configs";
 
 }

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/ServiceEndPoint.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/ServiceEndPoint.java
  (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/ServiceEndPoint.java
  Mon Dec 20 13:25:27 2010
@@ -22,8 +22,6 @@
 
 public class ServiceEndPoint implements Serializable {
 
-    private static final long serialVersionUID = 7613755184494120032L;
-
     private String m_clusterId;
     private String m_memberId;
     private String[] m_objectClass;

Added: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/internal/ClassLoaderAdaptor.java
==============================================================================
--- (empty file)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/internal/ClassLoaderAdaptor.java
      Mon Dec 20 13:25:27 2010
@@ -0,0 +1,21 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.core.fabric.remote.internal;
+
+public interface ClassLoaderAdaptor {
+    Class<?> loadClass(String className) throws ClassNotFoundException;
+}

Added: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/internal/DistributionUtilities.java
==============================================================================
--- (empty file)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/internal/DistributionUtilities.java
   Mon Dec 20 13:25:27 2010
@@ -0,0 +1,154 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.core.fabric.remote.internal;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.amdatu.core.fabric.remote.DistributionService;
+
+public final class DistributionUtilities {
+
+    public static boolean isConfigurationTypeSupported(Dictionary<String, 
Object> serviceRegistrationProperties) {
+        String[] expertedConfgis =
+            (String[]) 
serviceRegistrationProperties.get(DistributionService.SERVICE_EXPORTED_CONFIGS_PROP);
+        if (stringArrayContainsValue(expertedConfgis, 
DistributionService.SERVICE_CONFIGURATION_TYPE)) {
+            return true;
+        }
+        return false;
+    }
+
+    public static boolean isIntentsListSupported(Dictionary<String, Object> 
serviceRegistrationProperties) {
+        String[] serviceIntents =
+            (String[]) 
serviceRegistrationProperties.get(DistributionService.SERVICE_INTENTS_PROP);
+        if 
(!stringArrayContainsValues(DistributionService.DISTRIBUTION_INTENTS_SUPPORTED, 
serviceIntents)) {
+            return false;
+        }
+        String[] serviceExportedIntents =
+            (String[]) 
serviceRegistrationProperties.get(DistributionService.SERVICE_EXPORTED_INTENTS_PROP);
+        if 
(!stringArrayContainsValues(DistributionService.DISTRIBUTION_INTENTS_SUPPORTED, 
serviceExportedIntents)) {
+            return false;
+        }
+        String[] serviceExportedIntentsExtra =
+            (String[]) 
serviceRegistrationProperties.get(DistributionService.SERVICE_INTENTS_PROP);
+        if 
(!stringArrayContainsValues(DistributionService.DISTRIBUTION_INTENTS_SUPPORTED, 
serviceExportedIntentsExtra)) {
+            return false;
+        }
+        return true;
+    }
+
+    public static boolean isExportedInterfacesSupported(Dictionary<String, 
Object> serviceRegistrationProperties,
+        ClassLoaderAdaptor classLoadingHelper) {
+        if (serviceRegistrationProperties == null) {
+            return false;
+        }
+        Object serviceRegistrationProperty =
+            
serviceRegistrationProperties.get(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP);
+        if (serviceRegistrationProperty == null) {
+            return false;
+        }
+        if 
(!serviceRegistrationProperty.getClass().isAssignableFrom(String[].class)) {
+            return false;
+        }
+        String[] exportedInterfaces = (String[]) serviceRegistrationProperty;
+        if (exportedInterfaces.length == 0) {
+            return false;
+        }
+        for (String exportedInterface : exportedInterfaces) {
+            try {
+                Class<?> exportedInterfaceClass = 
classLoadingHelper.loadClass(exportedInterface);
+                if (exportedInterfaceClass == null) { // can it happen?
+                    return false;
+                }
+                if (!exportedInterfaceClass.isInterface()) {
+                    return false;
+                }
+                for (Method method : exportedInterfaceClass.getMethods()) {
+                    if 
(!Serializable.class.isAssignableFrom(method.getReturnType())) {
+                        return false;
+                    }
+                    for (Class<?> parameterType : method.getParameterTypes()) {
+                        if 
(!Serializable.class.isAssignableFrom(parameterType)) {
+                            return false;
+                        }
+                    }
+                }
+            }
+            catch (ClassNotFoundException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static String[] mergeExportedIntents(Dictionary<String, Object> 
serviceRegistrationProperties) {
+        Set<String> intentsSet = new HashSet<String>();
+        for (String intentsKey : new String[] { 
DistributionService.SERVICE_INTENTS_PROP,
+            DistributionService.SERVICE_EXPORTED_INTENTS_PROP, 
DistributionService.SERVICE_EXPORTED_INTENTS_EXTRA_PROP }) {
+            Object intentsValue = 
serviceRegistrationProperties.get(intentsKey);
+            if (intentsValue != null && 
String[].class.isAssignableFrom(intentsValue.getClass())) {
+                String[] intents = (String[]) intentsValue;
+                for (String intent : intents) {
+                    intentsSet.add(intent);
+                }
+            }
+        }
+        return intentsSet.toArray(new String[intentsSet.size()]);
+    }
+
+    public static boolean stringArrayContainsValue(String[] array, String 
value) {
+        if (array != null && value != null) {
+            for (String element : array) {
+                if (element.equals(value)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean stringArrayContainsValues(String[] array, String[] 
values) {
+        if (array != null && values != null) {
+            for (String value : values) {
+                boolean found = false;
+                for (String element : array) {
+                    if (element.equals(value)) {
+                        found = true;
+                    }
+                }
+                if (!found) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public static Class<?>[] getTypesFromArgs(Object[] args) {
+        if (args == null)
+            return new Class<?>[0];
+        Class<?>[] types = new Class[args.length];
+        for (int i = 0; i < args.length; i++) {
+            types[i] = args[i].getClass();
+        }
+        return types;
+    }
+}

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/service/DistributionServiceImpl.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/service/DistributionServiceImpl.java
  (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/remote/service/DistributionServiceImpl.java
  Mon Dec 20 13:25:27 2010
@@ -19,6 +19,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.util.Dictionary;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Map;
@@ -26,11 +27,12 @@
 import org.amdatu.core.fabric.cluster.ClusterMemberService;
 import org.amdatu.core.fabric.cluster.ClusterMessageService;
 import org.amdatu.core.fabric.cluster.ClusterTopicListener;
-import org.amdatu.core.fabric.remote.DiscoveryService;
 import org.amdatu.core.fabric.remote.DistributionService;
 import org.amdatu.core.fabric.remote.RemotableServiceEndpoint;
 import org.amdatu.core.fabric.remote.RemoteServiceEndPoint;
 import org.amdatu.core.fabric.remote.ServiceEndPoint;
+import org.amdatu.core.fabric.remote.internal.ClassLoaderAdaptor;
+import org.amdatu.core.fabric.remote.internal.DistributionUtilities;
 import org.amdatu.core.fabric.remote.internal.EndpointInvokeMessage;
 import org.amdatu.core.fabric.remote.internal.EndpointResponseMessage;
 import org.amdatu.core.fabric.remote.internal.LocalServiceInvocationHandler;
@@ -73,6 +75,14 @@
      ********************************************************/
 
     public synchronized void start() {
+        Dictionary<String, Object> distributionProps = 
m_component.getServiceProperties();
+        distributionProps.put(ClusterMemberService.CLUSTER_CLUSTERID_PROP, 
m_clusterMemberService.getClusterId());
+        distributionProps.put(ClusterMemberService.CLUSTER_MEMBERID_PROP, 
m_clusterMemberService.getMemberId());
+        
distributionProps.put(DistributionService.DISTRIBUTION_CONFIGS_SUPPORTED_PROP,
+            DistributionService.DISTRIBUTION_CONFIGS_SUPPORTED);
+        
distributionProps.put(DistributionService.DISTRIBUTION_INTENTS_SUPPORTED_PROP,
+            DistributionService.DISTRIBUTION_INTENTS_SUPPORTED);
+        m_component.setServiceProperties(distributionProps);
         m_clusterMessageService.subscribe(this);
     }
 
@@ -86,17 +96,24 @@
 
     public void localRemotableServiceAdded(ServiceReference serviceReference 
/* , Object Service */) {
         ServiceEndPoint serviceEndPoint = 
serviceEndPointFromServiceReference(serviceReference);
+        if (!isServiceEndpointConfigurationSupported(serviceEndPoint)) {
+            m_logService
+                .log(LogService.LOG_DEBUG, "Unsupported endpoint configuration 
" + serviceEndPoint.toString());
+            return;
+        }
+        Dictionary<String, Object> distributionProperties = new 
Hashtable<String, Object>();
+        Component serviceComponent =
+                m_dependencyManager.createComponent()
+                    .setInterface(RemotableServiceEndpoint.class.getName(), 
distributionProperties)
+                    .setImplementation(new 
RemotableServiceEndPointImpl(serviceEndPoint));
+        
serviceComponent.add(m_dependencyManager.createServiceDependency().setService(
+                DistributionService.class, 
m_component.getServiceRegistration().getReference()));
         synchronized (m_serviceEndPointServiceReferenceComponents) {
             if 
(!m_serviceEndPointServiceReferenceComponents.containsKey(serviceEndPoint)) {
-                Component serviceComponent =
-                    
m_dependencyManager.createComponent().setInterface(RemotableServiceEndpoint.class.getName(),
 null)
-                        .setImplementation(new 
RemotableServiceEndPointImpl(serviceEndPoint));
-                // FIXME validate that this depdendency works
-                
serviceComponent.add(m_dependencyManager.createServiceDependency().setService(
-                    DistributionService.class, 
m_component.getServiceRegistration().getReference()));
+                
m_serviceEndPointServiceReferenceComponents.put(serviceEndPoint,
+                        new ServiceReferenceComponentTuple(
+                            serviceReference, serviceComponent));
                 m_dependencyManager.add(serviceComponent);
-                
m_serviceEndPointServiceReferenceComponents.put(serviceEndPoint, new 
ServiceReferenceComponentTuple(
-                    serviceReference, serviceComponent));
             }
         }
     }
@@ -165,7 +182,7 @@
 
             String methodName = (String) 
payload.get(MESSAGE_INVOCATION_METHODNAME_KEY);
             Object[] args = (Object[]) 
payload.get(MESSAGE_INVOCATION_ARGUMENTS_KEY);
-            Class<?>[] types = getTypesFromArgs(args);
+            Class<?>[] types = DistributionUtilities.getTypesFromArgs(args);
 
             Object serviceResponse = null;
             synchronized (m_serviceEndPointServiceReferenceComponents) {
@@ -230,7 +247,8 @@
                 interfaceClasses[i] = 
m_bundleContext.getBundle().loadClass(interfaceName);
             }
             catch (ClassNotFoundException e) {
-                System.err.println("Unable to load interface classes for 
endpoint: " + serviceEndpoint.toString());
+                m_logService.log(LogService.LOG_ERROR, "Unable to load 
interface class for endpoint: "
+                    + serviceEndpoint.toString());
                 return null;
             }
         }
@@ -243,9 +261,19 @@
 
     private Component createLocalServiceComponent(ServiceEndPoint 
serviceEndPoint, Object serviceObject) {
         Hashtable<String, Object> registrationProperties = 
serviceEndPoint.getProperties();
-        registrationProperties.remove(DiscoveryService.REMOTABLE_PROP);
-        registrationProperties.put(DiscoveryService.REMOTE_PROP, "true");
-        registrationProperties.put("amdatu_endpoint", 
serviceEndPoint.toString());
+
+        String[] importedIntents = 
DistributionUtilities.mergeExportedIntents(registrationProperties);
+
+        
registrationProperties.remove(DistributionService.SERVICE_INTENTS_PROP);
+        
registrationProperties.remove(DistributionService.SERVICE_EXPORTED_CONFIGS_PROP);
+        
registrationProperties.remove(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP);
+        
registrationProperties.remove(DistributionService.SERVICE_EXPORTED_INTENTS_PROP);
+        
registrationProperties.remove(DistributionService.SERVICE_EXPORTED_INTENTS_EXTRA_PROP);
+
+        registrationProperties.put(DistributionService.SERVICE_IMPORTED_PROP, 
"true");
+        registrationProperties.put(DistributionService.SERVICE_INTENTS_PROP, 
importedIntents);
+        
registrationProperties.put(DistributionService.SERVICE_IMPORTED_CONFIGS_PROP,
+            DistributionService.SERVICE_CONFIGURATION_TYPE);
 
         Component component = m_dependencyManager.createComponent()
             .setInterface(serviceEndPoint.getObjectClass(), 
registrationProperties)
@@ -256,11 +284,33 @@
         return component;
     }
 
+    private boolean isServiceEndpointConfigurationSupported(ServiceEndPoint 
serviceEndPoint) {
+        if 
(!DistributionUtilities.isConfigurationTypeSupported(serviceEndPoint.getProperties()))
 {
+            System.err.println("No supported configuration type");
+            return false;
+        }
+        if 
(!DistributionUtilities.isIntentsListSupported(serviceEndPoint.getProperties()))
 {
+            System.err.println("Not all intents supported");
+            return false;
+        }
+        if 
(!DistributionUtilities.isExportedInterfacesSupported(serviceEndPoint.getProperties(),
+            new ClassLoaderAdaptor() {
+                public Class<?> loadClass(String className) throws 
ClassNotFoundException {
+                    return m_bundleContext.getBundle().loadClass(className);
+                }
+            })) {
+            System.err.println("Intents list not supported");
+            return false;
+        }
+        return true;
+    }
+
     private ServiceEndPoint 
serviceEndPointFromServiceReference(ServiceReference serviceReference) {
         ServiceEndPoint serviceEndPoint = new ServiceEndPoint();
         serviceEndPoint.setClusterId(m_clusterMemberService.getClusterId());
         serviceEndPoint.setMemberId(m_clusterMemberService.getMemberId());
-        serviceEndPoint.setObjectClass((String[]) 
serviceReference.getProperty("objectClass"));
+        serviceEndPoint.setObjectClass((String[]) serviceReference
+            
.getProperty(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP));
         serviceEndPoint.setOriginalServiceId((Long) 
serviceReference.getProperty("service.id"));
         Hashtable<String, Object> properties = new Hashtable<String, Object>();
         for (String key : serviceReference.getPropertyKeys()) {
@@ -270,16 +320,6 @@
         return serviceEndPoint;
     }
 
-    private Class[] getTypesFromArgs(Object[] args) {
-        if (args == null)
-            return new Class<?>[0];
-        Class<?>[] types = new Class[args.length];
-        for (int i = 0; i < args.length; i++) {
-            types[i] = args[i].getClass();
-        }
-        return types;
-    }
-
     static class ServiceReferenceComponentTuple {
         private final ServiceReference m_serviceReference;
         private final Component m_component;

Added: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/NonRemotableService.java
==============================================================================
--- (empty file)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/NonRemotableService.java
        Mon Dec 20 13:25:27 2010
@@ -0,0 +1,22 @@
+/*
+    Copyright (C) 2010 Amdatu.org
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.amdatu.core.fabric.test;
+
+public interface NonRemotableService {
+
+    String ping();
+}

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/internal/RemotableServiceImpl.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/internal/RemotableServiceImpl.java
      (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/internal/RemotableServiceImpl.java
      Mon Dec 20 13:25:27 2010
@@ -16,12 +16,17 @@
  */
 package org.amdatu.core.fabric.test.internal;
 
+import org.amdatu.core.fabric.test.NonRemotableService;
 import org.amdatu.core.fabric.test.RemotableService;
 
-public class RemotableServiceImpl implements RemotableService {
+public class RemotableServiceImpl implements RemotableService, 
NonRemotableService {
 
     public String hello(String name) {
         System.err.println("Saying hi to " + name);
         return "Hi " + name;
     }
+
+    public String ping() {
+        return "pong";
+    }
 }

Modified: 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/service/FabricTestServiceImpl.java
==============================================================================
--- 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/service/FabricTestServiceImpl.java
      (original)
+++ 
sandbox/bdekruijff/fabric/src/main/java/org/amdatu/core/fabric/test/service/FabricTestServiceImpl.java
      Mon Dec 20 13:25:27 2010
@@ -22,6 +22,7 @@
 import java.util.Map;
 
 import org.amdatu.core.fabric.remote.DistributionService;
+import org.amdatu.core.fabric.test.NonRemotableService;
 import org.amdatu.core.fabric.test.RemotableService;
 import org.amdatu.core.fabric.test.FabricTestService;
 import org.amdatu.core.fabric.test.internal.RemotableServiceImpl;
@@ -40,9 +41,22 @@
 
     public void registerRemotableService() {
         Dictionary<String, Object> props = new Hashtable<String, Object>();
-        props.put(DistributionService.REMOTABLE_PROP, "true");
-        Component serviceComponent = m_dependencyManager.createComponent()
-            .setInterface(RemotableService.class.getName(), 
props).setImplementation(new RemotableServiceImpl());
+
+        props.put(DistributionService.SERVICE_INTENTS_PROP, new String[] {});
+        props.put(DistributionService.SERVICE_EXPORTED_INTENTS_PROP,
+            new String[] { 
DistributionService.DISTRIBUTION_INTENT_CONFIDENTIALITY });
+        props.put(DistributionService.SERVICE_EXPORTED_INTENTS_EXTRA_PROP, new 
String[] {});
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP,
+            new String[] { RemotableService.class.getName() });
+        props.put(DistributionService.SERVICE_EXPORTED_CONFIGS_PROP,
+            new String[] { DistributionService.SERVICE_CONFIGURATION_TYPE });
+        props.put("org.amdatu.test.prop", "this property should be published 
on imported services");
+
+        Component serviceComponent =
+            m_dependencyManager
+                .createComponent()
+                .setInterface(new String[] { RemotableService.class.getName(), 
NonRemotableService.class.getName() },
+                    props).setImplementation(new RemotableServiceImpl());
         m_dependencyManager.add(serviceComponent);
         m_serviceComponents.put("c1", serviceComponent);
     }

Added: 
sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/fabric/remote/service/DistributionUtilitiesTest.java
==============================================================================
--- (empty file)
+++ 
sandbox/bdekruijff/fabric/src/test/java/org/amdatu/core/fabric/remote/service/DistributionUtilitiesTest.java
        Mon Dec 20 13:25:27 2010
@@ -0,0 +1,81 @@
+package org.amdatu.core.fabric.remote.service;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.amdatu.core.fabric.remote.DistributionService;
+import org.amdatu.core.fabric.remote.internal.ClassLoaderAdaptor;
+import org.amdatu.core.fabric.remote.internal.DistributionUtilities;
+import org.jmock.Mockery;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DistributionUtilitiesTest {
+
+    Mockery m_context;
+
+    @Before
+    public void setUp() {
+        m_context = new Mockery();
+    }
+
+    @Test
+    public void testIsExportedInterfacesSupported() {
+
+        ClassLoaderAdaptor clh = new ClassLoaderAdaptor() {
+            public Class<?> loadClass(String className) throws 
ClassNotFoundException {
+                return this.getClass().getClassLoader().loadClass(className);
+            }
+        };
+
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+
+        // null dict
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(null, 
clh));
+
+        // null clh
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+        // empty dict
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+        // String prop
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP, 
"hello");
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+        // Non existing class
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP, new 
String[] { "foo.bar.Test" });
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+        // Non interface class
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP, new 
String[] { String.class.getName() });
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+        // Remotable interface class
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP,
+            new String[] { RemotableInterface1.class.getName() });
+        
Assert.assertTrue(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+        // Nonremotable interface class
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP,
+            new String[] { NonRemotableInterface1.class.getName() });
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+        props.put(DistributionService.SERVICE_EXPORTED_INTERFACES_PROP,
+            new String[] { NonRemotableInterface2.class.getName() });
+        
Assert.assertFalse(DistributionUtilities.isExportedInterfacesSupported(props, 
clh));
+
+    }
+}
+
+interface RemotableInterface1 {
+    String helloWorld(String arg1);
+}
+
+interface NonRemotableInterface1 {
+    String helloWorld(Object arg1);
+}
+
+interface NonRemotableInterface2 {
+    Object helloWorld(String arg1);
+}

Reply via email to