yuppie wrote: > Andreas Jung wrote: >> we have a CMF-based application where I am trying to migrate from >> TextIndexNG 2 -> 3. >> >> For a content-type class A I have configured an adapter to implement >> IIndexableContent. However when the object is reindexed CMF wraps >> the object as IndexableObjectWrapper which by itself implements >> the IndexableObjectWrapper interface. The low-level indexer of TXNG >> get the wrapped object and has no idea what to do with the object >> since the interface of the wrapper shadows the interface of the >> wrapped object. >> Any idea how to deal with this problem? > > I'm currently fighting with the same issue. And I was in the process of > writing a mail to the Zope-CMF list when your mail came in. AFAICS this > is more a CMF issue than a Five issue, so I add Zope-CMF to the > recipients list. > > > Just for the records, I'm sure you already figured that out yourself: > > Plone 2.1 doesn't have this issue because it has no interface > declaration on its ExtensibleIndexableObjectWrapper. If the wrapper > doesn't have its own __providedBy__ attribute the __getattr__ method > looks it up in the wrapped class, making the interface declarations > completely transparent. > > Plone 2.5 has an interface declaration so I guess it has the same > problem as the CMF. > > > The quick and dirty solution would be to remove the interface > declaration from the wrapper. The clean solution would be to make sure > that all the interfaces that are actually provided - the wrapper > interface *and* the interfaces of the wrapped object - can be looked up. > But implementing that seems to require deeper knowledge of the interface > machinery than I have.
This problem has already been solved in Zope 3. There we like to wrap objects that don't provide ILocation (__parent__ and __name__ attributes) in something that *does* provide ILocation. The resulting object is a proxy for the original object and in addition that it provides __parent__ and __name__ attributes. The proxy provides whatever the original object provides plus ILocation. We call this concept a /decorator/. This is not to be confused with Python 2.4's function decorators. In Zope 3's case, think of decorator as a proxy that also adds stuff to the object (e.g. the ILocation API). Hence, it decorates the original object, like a Christmas tree if you will. There are two options: 1. I think for the long term, IndexableObjectWrapper could be made a decorator. This works as follows: from zope.proxy import getProxiedObject from zope.app.decorator import Decorator class IndexableObjectWrapper(Decorator): def allowedRolesAndUsers(self): ob = getProxiedObject(self) allowed = {} for r in rolesForPermissionOn(View, ob): allowed[r] = 1 localroles = _mergedLocalRoles(ob) for user, roles in localroles.items(): for role in roles: if allowed.has_key(role): allowed['user:' + user] = 1 if allowed.has_key('Owner'): del allowed['Owner'] return list(allowed.keys()) 2. In the short term we can apply the following trick (IndexableObjectWrapper needs to be a new style class!): from zope.interface import providedBy from zope.interface.declarations import ObjectSpecificationDescriptor from zope.interface.declarations import getObjectSpecification from zope.interface.declarations import ObjectSpecification class IndexableObjectSpecification(ObjectSpecificationDescriptor): def __get__(self, inst, cls=None): if inst is None: return getObjectSpecification(cls) else: provided = providedBy(inst.__ob) cls = type(inst) return ObjectSpecification(provided, cls) class IndexableObjectWrapper(object): # new-style! implements(...) # it can implement as much as it wants __providedBy__ = IndexableObjectSpecification() ... This is obviously untested, but I'm pretty confident that this would work. Philipp _______________________________________________ Zope-CMF maillist - Zope-CMF@lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See http://collector.zope.org/CMF for bug reports and feature requests