"""Basic binding tools""" |
"""Basic binding tools""" |
|
|
from once import Once, New, WeakBinding |
from __future__ import generators |
import meta, modules |
from once import Once, New, WeakRefBinding |
|
import meta |
|
from peak.running.config.modules import setupModule |
|
|
from weakref import ref, WeakValueDictionary |
from weakref import ref, WeakValueDictionary |
|
|
|
|
__all__ = [ |
__all__ = [ |
'Component','AutoCreated','Provider','CachingProvider', |
'Component','AutoCreated','Provider','CachingProvider', |
'bindTo', 'requireBinding', 'bindToNames', 'bindToParent', 'bindToSelf', |
'bindTo', 'requireBinding', 'bindSequence', 'bindToParent', 'bindToSelf', |
'getRootComponent', 'getParentComponent', 'lookupComponent', |
'getRootComponent', 'getParentComponent', 'lookupComponent', |
'acquireComponent', 'globalLookup' |
'acquireComponent', 'globalLookup', 'findUtility', 'findUtilities', |
|
'bindToUtilities', |
] |
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def Provider(callable): |
def Provider(callable): |
return lambda foundIn, forObj: callable(forObj) |
return lambda foundIn, forObj: callable(forObj) |
|
|
|
|
def globalLookup(name, component=None): |
def globalLookup(name, component=None): |
|
|
"""Lookup 'name' in global 'InitialContext', w/'component' in environ""" |
"""Lookup 'name' in global 'InitialContext', relative to 'component'""" |
|
|
from peak.naming.api import InitialContext |
from peak.naming.api import InitialContext |
|
|
return InitialContext(RELATIVE_TO_COMPONENT=component).lookup(name) |
return InitialContext(component).lookup(name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
def findUtilities(component, iface, forObj=None): |
|
|
|
if forObj is None: |
|
forObj = component |
|
|
|
last = component |
|
|
|
while component is not None: |
|
|
|
utility = component._getUtility(iface, forObj) |
|
|
|
if utility is not None: |
|
yield utility |
|
|
|
last = component |
|
component = component.getParentComponent() |
|
|
|
|
|
cfg = config.getLocal(last) |
|
|
|
if cfg is not None: |
|
for u in findUtilities(cfg, iface, forObj): |
|
yield u |
|
|
|
|
|
def findUtility(component, iface, forObj=None): |
|
|
|
for u in findUtilities(component, iface, forObj): |
|
return u |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ComponentNameSyntax = Syntax( |
ComponentNameSyntax = Syntax( |
direction = 1, |
direction = 1, |
separator = '/', |
separator = '/', |
Interface object. Strings and 'CompoundName' names will be interpreted |
Interface object. Strings and 'CompoundName' names will be interpreted |
as paths relative to the starting component. An empty name will return |
as paths relative to the starting component. An empty name will return |
the starting component. Interfaces will be lookedup using |
the starting component. Interfaces will be lookedup using |
'component.acquireUtility()'. All other kinds of names, including URL |
'findUtility(component,...)'. All other kinds of names, including URL |
strings and 'CompositeName' instances, will be looked up using |
strings and 'CompositeName' instances, will be looked up using |
'binding.globalLookup()'. |
'binding.globalLookup()'. |
|
|
path segment.""" |
path segment.""" |
|
|
if isinstance(name, InterfaceClass): |
if isinstance(name, InterfaceClass): |
utility = component.acquireUtility(name) |
utility = findUtility(component, name) |
if utility is None: |
if utility is None: |
raise NameNotFoundException(name, resolvedObj = component) |
raise NameNotFoundException(name, resolvedObj = component) |
|
|
|
|
|
|
|
|
class bindToNames(bindTo): |
class bindSequence(bindTo): |
|
|
"""Automatically look up and cache a sequence of services by name |
"""Automatically look up and cache a sequence of services by name |
|
|
|
|
class someClass(binding.AutoCreated): |
class someClass(binding.AutoCreated): |
|
|
thingINeed = binding.bindToNames( |
thingINeed = binding.bindSequence( |
"path/to/service", "another/path", ... |
"path/to/service", "another/path", ... |
) |
) |
|
|
|
|
|
|
|
|
class bindToParent(WeakBinding): |
class bindToParent(WeakRefBinding): |
|
|
"""Look up and cache a weak ref to the nth-level parent component |
"""Look up and cache a weak ref to the nth-level parent component |
|
|
) |
) |
|
|
|
|
|
def bindToUtilities(iface): |
|
return Once(lambda s,d,a: [u for u in findUtilities(s,iface,s)]) |
|
|
|
|
|
|
|
|
|
|
|
|
def acquireUtility(self, iface, forObj=None, localLookup=True): |
def _getUtility(self, iface, forObj): |
|
|
if forObj is None: |
|
forObj=self |
|
|
|
if localLookup: |
|
|
|
provider = self.__instance_provides__.get(iface) |
provider = self.__instance_provides__.get(iface) |
|
|
if utility is not NOT_FOUND: |
if utility is not NOT_FOUND: |
return utility |
return utility |
|
|
parent = self.getParentComponent() |
|
|
|
if parent is None: |
|
parent = config.getLocal(self) |
|
|
|
return parent.acquireUtility(iface,forObj) |
|
|
|
|
|
def registerProvider(self, ifaces, provider): |
def registerProvider(self, ifaces, provider): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AutoCreatable(type): |
class AutoCreatable(type): |
|
|
"""Metaclass for components which auto-create when used""" |
"""Metaclass for components which auto-create when used""" |
|
|
|
|
|
|
modules.setupModule() |
setupModule() |
|
|
|
|
|
|