Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 19c1a89e997bce65a3b34c76231255f3635ae2a1 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                               
                                                                      






                                                                         
                                                                               
 

                  
                       



                         
 
                              
                                                                        
                                                              
       
 

                                       
 


                                                     
 



                                   
 



                                    
 







                                                          

                            
                                   

                                                             

                                                                 

                                                                     






                                                                     

                                   



                                                                         

                                        

                                                                
 




                                                              
 
                              
 

                                 
 



                                   
 
                      
                                 
                      



                                                   
                                                    
 
                      



                                             
                             
 
                                  








                                                                            



                                                  
 



                         
 
                            




                                                                           
       
 


                                      
 

                        
 


                             
 
                                              
                                               
 

                                       
                                              
                 
 




                                                       

                                                               





                                                    

                                                                  


                                            
# *****************************************************************************
# * Copyright (c) 2011, 2013-2014 Wind River Systems, Inc. and others.
# * All rights reserved. This program and the accompanying materials
# * are made available under the terms of the Eclipse Public License v1.0
# * which accompanies this distribution, and is available at
# * http://www.eclipse.org/legal/epl-v10.html
# *
# * Contributors:
# *     Wind River Systems - initial API and implementation
# *****************************************************************************

import collections
import threading
from .. import protocol

_providers = []
_lock = threading.RLock()


class ServiceProvider(object):
    """Clients can implement this abstract class if they want to provide
    implementation of a local service or remote service proxy.
    """

    def getLocalService(self, channel):
        pass

    def getServiceProxy(self, channel, service_name):
        pass


def addServiceProvider(provider):
    with _lock:
        _providers.append(provider)


def removeServiceProvider(provider):
    with _lock:
        _providers.remove(provider)


def onChannelCreated(channel, services_by_name):
    with _lock:
        # TODO ZeroCopy support is incomplete
#        zero_copy = ZeroCopy()
#        services_by_name[zero_copy.getName()] = zero_copy
        for provider in _providers:
            try:
                arr = provider.getLocalService(channel)
                if not arr:
                    continue
                for service in arr:
                    if service.getName() in services_by_name:
                        continue
                    services_by_name[service.getName()] = service
            except Exception as x:
                protocol.log("Error calling TCF service provider", x)


def onChannelOpened(channel, service_names, services_by_name):
    with _lock:
        for name in service_names:
            for provider in _providers:
                try:
                    service = provider.getServiceProxy(channel, name)
                    if not service:
                        continue
                    services_by_name[name] = service
                    break
                except Exception as x:
                    protocol.log("Error calling TCF service provider", x)
            if name in services_by_name:
                continue
            services_by_name[name] = GenericProxy(channel, name)


def getServiceManagerID():
    # In current implementation ServiceManager is a singleton,
    # so its ID is same as agent ID.
    return protocol.getAgentID()


class GenericCallback(object):

    def __init__(self, callback):
        self.callback = callback

    def __getattr__(self, attr):
        if attr.startswith("done"):
            return self.callback


class Service(object):
    """TCF service base class."""
    def getName(self):
        """Abstract method to get the service name.

        :returns: This service name
        """
        raise NotImplementedError("Abstract method")

    def __str__(self):
        """TCF service string representation.

        :returns: The name of the service.
        """
        return self.getName()

    def _makeCallback(self, done):
        """Turn *done* into a callable.

        If *done* is already a :class:`collections.Callable`, it is returned
        as is, else, it is made callable, and returned.

        :param done: The item to make callable.

        :returns: The callable value of *done*
        """
        if isinstance(done, collections.Callable):
            return GenericCallback(done)
        return done


class ZeroCopy(Service):
    def getName(self):
        return "ZeroCopy"


class GenericProxy(Service):
    """Objects of GenericProxy class represent remote services, which don't
    have a proxy class defined for them.

    Clients still can use such services, but framework will not provide
    service specific utility methods for message formatting and parsing.
    """

    def __init__(self, channel, name):
        self.__channel = channel
        self.name = name

    def getName(self):
        return self.name

    def getChannel(self):
        return self.__channel


class DefaultServiceProvider(ServiceProvider):
    package_base = str(__package__) + ".remote"

    def getLocalService(self, channel):
        # TODO DiagnosticsService
        # return [DiagnosticsService(channel)]
        return []

    def getServiceProxy(self, channel, service_name):
        service = None
        try:
            clsName = service_name + "Proxy"
            package = self.package_base + "." + clsName
            clsModule = __import__(package, fromlist=[clsName],
                                   globals=globals())
            cls = clsModule.__dict__.get(clsName)
            service = cls(channel)
            assert service_name == service.getName()
        except ImportError:
            pass
        except Exception as x:
            protocol.log("Cannot instantiate service proxy for " +
                         service_name, x)
        return service

addServiceProvider(DefaultServiceProvider())

Back to the top