[Zope3-dev] should the view lookup machinery call getAdapter?
Steve Alexander
steve@cat-box.net
Sat, 30 Mar 2002 09:02:41 +0000
R. David Murray wrote:
> This may all be a result of my misunderstanding how things
> currently work, but:
>
> I noticed on the checkins list that Casey did the following:
>
>
>><browser:view name="RolePermissionsManagement"
>> for="Zope.App.OFS.Memento.IAttributeMementoStorable."
>> factory="Zope.App.Security.RolePermissionView." />
>
>
> It seems to me that the goal would be that this view would work for
> any object that supports the IMementoBag interface.
First I'll present some background which might be helpful to people who
haven't looked at all of the interfaces and mechanisms involved in this.
Then, I'll present a solution.
Let's think about what you have, and where you want to get to.
We have a content object. We want to know if we can get it to store
Role-Permissions information for us.
The IAttributeMementoStorable interface is a contract between a content
object, and anything else, that says "you can use my __memobag__
attribute". The content object give others permission to use one of its
attributes, and promises not to mess with that particular attribute.
A declaration, as above, can be interpreted as providing a quanta of
declarative knowledge. It is saying something that shall be true; an
affordance; a thing that may happen in the system.
So this particular declaration is saying "If you've got a content object
that implements IAttributeMementoStorable, you can see its
RolePermissionManagement view".
As IAttributeMementoStorable is only one particular way of associating
an IMementoBag with a content object, we'll need other declarations for
the other FooMementoStorable interfaces.
So, that's fine when we look at it from the point of view of the content
object.
The problem with this is that whenever we create a new
FooMementoStorable, we'll have to add declarations for all of the
different views that work with IMementoBags.
This might be ok if there are only ever a couple of MementoStorable
schemes. However, there is also the problem that when you add other
views that work with IMementoBags, you'd have to add declarations for
each of the MementoStorable schemes.
So, ideally, we want to say in one place how content objects can be
associated with IMementoBags, and in another place what things can work
with IMementoBags.
One way of solving this is, as RDM said, to declare that the
RolePermissionsManagement view works with anything, and dynamically
check adapters in the factory registered in the directive.
This is not a good solution, as RDM pointed out, because it adds a
procesing overhead, and also because the whole thing has become less
discoverable. That is, we've lost the explicit declaration that
RolePermissionsManagement needs an IMementoBag.
My solution:
A better way of solving this is to expand the view registry so that it
can register transitive relationships between adapters.
Consider these declarations:
What you have What you can get
IAttributeMementoStorable IMementoBag
IMementoBag RolePermissionsManagement view
In the zcml files, you'd declare that an adapter exists for adapting
IAttributeMementoStorables into IMementoBags. We also say that the
RolePermissionsManagement view needs an IMementoBag.
We add an attribute transitive="yes" to the
IAttributeMementoStorable->IMementoBag declaration.
We need to change the component registries to have a two-phase
initialisation. Inside the component registries, any adapters that get
registered with transitive="yes" are registered as usual, and also added
to a list for processing in the second phase.
After all the directives are registered, we go through the
transitive="yes" list, and transitively add new adapter and view (and
utility and service?) declarations based on the interfaces that the
interface in the transitive="yes" list can adapt to. As we are doing
this transitively, we keep on doing it until there is no more work to do.
This is quite an expensive process, which is why we don't want to do it
for all the adapters in the system. So, we only declare to be transitive
certain adapters that we know are needed transitively.
We may need a declaration that partially overrides an adapter
declaration by adding transitive="yes" and keeping the rest of the
declaration intact.
Then again, we might find that if we transitively register all adapters,
that most of the second-phase work is a no-operation, and by default all
adapters can be registered transitively.
--
Steve Alexander