# HG changeset patch # User tflorac@dagon.home # Date 1526045729 -7200 # Node ID d9c6a2a99acf0551e46beb43ccbd6add947f5628 # Parent f2acf176be2c5f1e85161f4888eef2c4fdb061e1 Added helper to get a persistent adapter through context's annotations diff -r f2acf176be2c -r d9c6a2a99acf src/pyams_utils/adapter.py --- a/src/pyams_utils/adapter.py Wed May 09 14:05:08 2018 +0200 +++ b/src/pyams_utils/adapter.py Fri May 11 15:35:29 2018 +0200 @@ -28,9 +28,13 @@ import venusian # import interfaces +from zope.annotation.interfaces import IAnnotations # import packages +from pyams_utils.registry import get_current_registry from zope.interface import implementedBy +from zope.lifecycleevent import ObjectCreatedEvent +from zope.location import locate as zope_locate class ContextAdapter(object): @@ -125,3 +129,29 @@ settings['_info'] = info.codeinfo # fbo "action_method" return wrapped + + +def get_annotation_adapter(context, key, factory, notify=True, locate=True, parent=None, name=None): + """Get an adapter via object's annotations, creating it if not existent + + :param object context: context object which should be adapted + :param str key: annotations key to look for + :param factory: if annotations key is not found, this is the factory which will be used to + create a new object + :param bool notify: if 'False', no notification event will be sent on object creation + :param bool locate: if 'False', the new object is not attached to any parent + :param object parent: parent to which new object is attached + :param str name: if locate is not False, this is the name with which the new object is attached + to it's parent. + """ + annotations = IAnnotations(context, None) + if annotations is None: + return None + adapter = annotations.get(key) + if adapter is None: + adapter = annotations[key] = factory() + if notify: + get_current_registry().notify(ObjectCreatedEvent(adapter)) + if locate: + zope_locate(adapter, context if parent is None else parent, name) + return adapter