# HG changeset patch # User Thierry Florac # Date 1444232884 -7200 # Node ID 01eaa997a5f45598f1bc8be651b0f743c181ed02 # Parent 8d0e2e33ae90ff45b0d0014be9982447eaaa9507 Moved module from pyams_base package diff -r 8d0e2e33ae90 -r 01eaa997a5f4 src/pyams_utils/intids.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/intids.py Wed Oct 07 17:48:04 2015 +0200 @@ -0,0 +1,96 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard packages + +# import interfaces +from persistent.interfaces import IPersistent +from pyams_utils.interfaces.intids import IUniqueID +from zope.intid.interfaces import IIntIds, IIntIdEvent, IntIdAddedEvent, IntIdRemovedEvent +from zope.lifecycleevent.interfaces import IObjectAddedEvent, IObjectRemovedEvent +from zope.location.interfaces import ISublocations +from zope.keyreference.interfaces import IKeyReference, NotYet + +# import packages +from pyams_utils.adapter import adapter_config +from pyams_utils.registry import get_all_utilities_registered_for, query_utility +from pyramid.events import subscriber +from pyramid.threadlocal import get_current_registry +from zope.intid import intIdEventNotify +from zope.lifecycleevent import ObjectRemovedEvent + + +@adapter_config(context=IPersistent, provides=IUniqueID) +class UniqueIdAdapter(object): + """Object unique ID adapter + + This adapter is based on a registered IIntIds utility + """ + + def __init__(self, context): + self.context = context + + @property + def oid(self): + intids = query_utility(IIntIds) + if intids is not None: + return hex(intids.queryId(self.context))[2:] + + +@subscriber(IObjectAddedEvent, context_selector=IPersistent) +def handle_added_object(event): + """Notify IntId utility for added objects""" + utilities = tuple(get_all_utilities_registered_for(IIntIds)) + if utilities: + # assert that there are any utilities + try: + key = IKeyReference(event.object, None) + except NotYet: + pass + else: + # Register only objects that adapt to key reference + if key is not None: + idmap = {} + for utility in utilities: + idmap[utility] = utility.register(key) + # Notify the catalogs that this object was added. + get_current_registry().notify(IntIdAddedEvent(event.object, event, idmap)) + + +@subscriber(IObjectRemovedEvent, context_selector=IPersistent) +def handle_removed_object(event): + """Notify IntId utility for removed objects""" + registry = get_current_registry() + locations = ISublocations(event.object, None) + if locations is not None: + for location in locations.sublocations(): + registry.notify(ObjectRemovedEvent(location)) + utilities = tuple(get_all_utilities_registered_for(IIntIds)) + if utilities: + key = IKeyReference(event.object, None) + # Register only objects that adapt to key reference + if key is not None: + # Notify the catalogs that this object is about to be removed. + registry.notify(IntIdRemovedEvent(event.object, event)) + for utility in utilities: + try: + utility.unregister(key) + except KeyError: + pass + + +@subscriber(IIntIdEvent) +def handle_intid_event(event): + intIdEventNotify(event)