[Checkins] SVN: zope.generic/trunk/src/zope/generic/ initial code from tiks.generic

Dominik Huber dominik.huber at perse.ch
Sat Apr 8 16:33:02 EDT 2006


Log message for revision 66689:
  initial code from tiks.generic

Changed:
  A   zope.generic/trunk/src/zope/generic/configuration/
  A   zope.generic/trunk/src/zope/generic/configuration/DEPENDENCIES.cfg
  A   zope.generic/trunk/src/zope/generic/configuration/README.txt
  A   zope.generic/trunk/src/zope/generic/configuration/SETUP.cfg
  A   zope.generic/trunk/src/zope/generic/configuration/__init__.py
  A   zope.generic/trunk/src/zope/generic/configuration/adapter.py
  A   zope.generic/trunk/src/zope/generic/configuration/api.py
  A   zope.generic/trunk/src/zope/generic/configuration/base.py
  A   zope.generic/trunk/src/zope/generic/configuration/configure.zcml
  A   zope.generic/trunk/src/zope/generic/configuration/event.py
  A   zope.generic/trunk/src/zope/generic/configuration/helper.py
  A   zope.generic/trunk/src/zope/generic/configuration/interfaces.py
  A   zope.generic/trunk/src/zope/generic/configuration/meta.zcml
  A   zope.generic/trunk/src/zope/generic/configuration/metaconfigure.py
  A   zope.generic/trunk/src/zope/generic/configuration/metadirectives.py
  A   zope.generic/trunk/src/zope/generic/configuration/testing.py
  A   zope.generic/trunk/src/zope/generic/configuration/tests.py
  A   zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-configure.zcml
  A   zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-meta.zcml
  A   zope.generic/trunk/src/zope/generic/directlyprovides/
  A   zope.generic/trunk/src/zope/generic/directlyprovides/DEPENDENCIES.cfg
  A   zope.generic/trunk/src/zope/generic/directlyprovides/PUBLICATION.cfg
  A   zope.generic/trunk/src/zope/generic/directlyprovides/README.txt
  A   zope.generic/trunk/src/zope/generic/directlyprovides/SETUP.cfg
  A   zope.generic/trunk/src/zope/generic/directlyprovides/__init__.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/api.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/configure.zcml
  A   zope.generic/trunk/src/zope/generic/directlyprovides/decorator.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/event.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/handler.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/helper.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/interfaces.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/property.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/testing.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/tests.py
  A   zope.generic/trunk/src/zope/generic/directlyprovides/zope.generic.directlyprovides-configure.zcml
  A   zope.generic/trunk/src/zope/generic/doc/
  A   zope.generic/trunk/src/zope/generic/doc/CHANGES.txt
  A   zope.generic/trunk/src/zope/generic/doc/README.txt
  A   zope.generic/trunk/src/zope/generic/doc/SETUP.cfg
  A   zope.generic/trunk/src/zope/generic/doc/TODO.txt
  A   zope.generic/trunk/src/zope/generic/doc/__init__.py
  A   zope.generic/trunk/src/zope/generic/doc/configure.zcml
  A   zope.generic/trunk/src/zope/generic/doc/zope.generic.doc-configure.zcml
  A   zope.generic/trunk/src/zope/generic/information/
  A   zope.generic/trunk/src/zope/generic/information/DEPENDENCIES.cfg
  A   zope.generic/trunk/src/zope/generic/information/PUBLICATION.cfg
  A   zope.generic/trunk/src/zope/generic/information/README.txt
  A   zope.generic/trunk/src/zope/generic/information/SETUP.cfg
  A   zope.generic/trunk/src/zope/generic/information/__init__.py
  A   zope.generic/trunk/src/zope/generic/information/api.py
  A   zope.generic/trunk/src/zope/generic/information/base.py
  A   zope.generic/trunk/src/zope/generic/information/configure.zcml
  A   zope.generic/trunk/src/zope/generic/information/helper.py
  A   zope.generic/trunk/src/zope/generic/information/interfaces.py
  A   zope.generic/trunk/src/zope/generic/information/meta.zcml
  A   zope.generic/trunk/src/zope/generic/information/metaconfigure.py
  A   zope.generic/trunk/src/zope/generic/information/metadirectives.py
  A   zope.generic/trunk/src/zope/generic/information/testing.py
  A   zope.generic/trunk/src/zope/generic/information/tests.py
  A   zope.generic/trunk/src/zope/generic/information/zope.generic.information-configure.zcml
  A   zope.generic/trunk/src/zope/generic/information/zope.generic.information-meta.zcml
  A   zope.generic/trunk/src/zope/generic/testing/
  A   zope.generic/trunk/src/zope/generic/testing/DEPENDENCIES.cfg
  A   zope.generic/trunk/src/zope/generic/testing/PUBLICATION.cfg
  A   zope.generic/trunk/src/zope/generic/testing/README.txt
  A   zope.generic/trunk/src/zope/generic/testing/SETUP.cfg
  A   zope.generic/trunk/src/zope/generic/testing/__init__.py
  A   zope.generic/trunk/src/zope/generic/testing/configure.zcml
  A   zope.generic/trunk/src/zope/generic/testing/testing.py
  A   zope.generic/trunk/src/zope/generic/testing/zope.generic.testing-configure.zcml
  A   zope.generic/trunk/src/zope/generic/type/
  A   zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg
  A   zope.generic/trunk/src/zope/generic/type/PUBLICATION.cfg
  A   zope.generic/trunk/src/zope/generic/type/README.txt
  A   zope.generic/trunk/src/zope/generic/type/SETUP.cfg
  A   zope.generic/trunk/src/zope/generic/type/__init__.py
  A   zope.generic/trunk/src/zope/generic/type/adapter.py
  A   zope.generic/trunk/src/zope/generic/type/api.py
  A   zope.generic/trunk/src/zope/generic/type/base.py
  A   zope.generic/trunk/src/zope/generic/type/configure.zcml
  A   zope.generic/trunk/src/zope/generic/type/factory.py
  A   zope.generic/trunk/src/zope/generic/type/helper.py
  A   zope.generic/trunk/src/zope/generic/type/interfaces.py
  A   zope.generic/trunk/src/zope/generic/type/meta.zcml
  A   zope.generic/trunk/src/zope/generic/type/metaconfigure.py
  A   zope.generic/trunk/src/zope/generic/type/metadirectives.py
  A   zope.generic/trunk/src/zope/generic/type/testing.py
  A   zope.generic/trunk/src/zope/generic/type/tests.py
  A   zope.generic/trunk/src/zope/generic/type/zope.generic.type-configure.zcml
  A   zope.generic/trunk/src/zope/generic/type/zope.generic.type-meta.zcml

-=-
Added: zope.generic/trunk/src/zope/generic/configuration/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/DEPENDENCIES.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/DEPENDENCIES.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,14 @@
+BTrees
+persistent
+zope.generic.configuration
+zope.generic.testing
+zope.app.component
+zope.app.event
+zope.app.location
+zope.component
+zope.configuration
+zope.dottedname
+zope.event
+zope.interface
+zope.schema
+zope.testing
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/configuration/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/configuration/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/README.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/README.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,271 @@
+=============
+Configuration
+=============
+
+Configuration is a container of configuration data. Configuration data are
+defined by an schema which is providing IConfigurationType.
+
+	>>> from zope.schema import TextLine
+		
+    >>> class IMyConfiguration(interface.Interface):
+    ...     my = TextLine(title=u'My')
+
+    # make available within the testing module
+    >>> testing.IMyConfiguration = IMyConfiguration
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="zope.generic.configuration.testing.IMyConfiguration"
+    ...     label='My' hint='My bla.'
+    ...     />
+    ... ''') 
+
+	>>> from zope.generic.configuration.api import IConfigurationType
+	>>> IConfigurationType.providedBy(IMyConfiguration)
+	True
+
+The configuration itself is an information (see zope.generic.information) which
+is registered as utility providing IConfigurationInformation and named
+by the dotted configuration schema name:
+
+    >>> from zope.generic.configuration.api import IConfigurationInformation
+    >>> from zope.generic.information.api import queryInformation
+
+    >>> config_info = queryInformation(IMyConfiguration, 
+    ...		IConfigurationInformation) 
+    >>> config_info.label == u'My'
+    True
+    >>> config_info.hint == u'My bla.'
+    True
+
+There is a convenience function for configuration informations too:
+
+    >>> from zope.generic.configuration.api import queryConfigurationInformation
+
+	>>> config_info == queryConfigurationInformation(IMyConfiguration)
+	True
+
+The modification of configuration might cause object configuration modified event.
+Those event extend the regular object modified event. This event regularly implies
+a location of the referenced object. Therefore only locatable objects will get
+notified. In our example we registered a transient global information which does
+not satify the condition:
+
+    >>> from zope.app.event.tests.placelesssetup import getEvents, clearEvents
+    >>> from zope.generic.configuration import IObjectConfigurationsModifiedEvent
+    >>> events = getEvents()
+    >>> len(events)
+    0 
+
+Attribute Configurations
+------------------------
+ 
+Regularly Configurations are provided by objects marked with
+IAttributeConfigurations automatically:
+    
+    >>> from zope.generic.configuration.testing import placelesssetup
+    >>> placelesssetup.setUp()
+
+    >>> from zope.interface import implements
+    >>> from zope.generic.configuration import IAttributeConfigurable
+
+    >>> class Foo(object):
+    ...    implements(IAttributeConfigurable)
+
+    >>> foo = Foo()
+    >>> IAttributeConfigurable.providedBy(foo)
+    True
+
+Now you can adapt you to IConfigurations:
+
+	>>> from zope.generic.configuration import IConfigurations
+
+    >>> configurations = IConfigurations(foo)
+    >>> IConfigurations.providedBy(configurations)
+    True
+
+At the beginning the IConfigurations storage does not exists:
+
+    >>> configurations.__nonzero__()
+    False
+
+Configuration data will be stored under an interface-key within the
+configurations. Such a configuration interface-key defines its configuration
+data:
+
+    >>> from zope.interface import Interface
+    >>> from zope.schema import TextLine
+    
+    >>> class IFooConfiguration(Interface):
+    ...    foo = TextLine(title=u'Foo')
+    ...    optional = TextLine(title=u'Optional', required=False, default=u'Bla')
+
+    # make available within the module
+    >>> from zope.generic.configuration import adapter
+    >>> adapter.IFooConfiguration = IFooConfiguration
+    >>> IFooConfiguration.__module__ = 'zope.generic.configuration.adapter'
+
+The configuration interface-key is a regular schema, but it has to be typed
+by IConfigurationType (Regularly typed by the configuration directive):
+
+    >>> from zope.interface import directlyProvides
+
+    >>> directlyProvides(IFooConfiguration, IConfigurationType)
+    >>> IConfigurationType.providedBy(IFooConfiguration)
+    True
+
+The configuration provides a regular dictionary api by the UserDictMixin
+(like AttributeAnnotations). This mixin bases on the following methods:
+
+    >>> configurations[IFooConfiguration]
+    Traceback (most recent call last):
+    ...
+    KeyError: <InterfaceClass zope.generic.configuration.adapter.IFooConfiguration>
+
+    >>> del configurations[IFooConfiguration]
+    Traceback (most recent call last):
+    ...
+    KeyError: <InterfaceClass zope.generic.configuration.adapter.IFooConfiguration>
+
+    >>> configurations.keys()
+    []
+
+... if a value might be set to the configurations it must provide the 
+configuration interface-key itself. The interface-key must provide
+IConfigurationType:
+
+    >>> class IBarConfiguration(Interface):
+    ...    bar = TextLine(title=u'Bar')
+
+    >>> configurations[IBarConfiguration] = object()
+    Traceback (most recent call last):
+    ...
+    KeyError: 'Interface key IBarConfiguration does not provide IConfigurationType.'
+
+    >>> configurations[IFooConfiguration] = object()
+    Traceback (most recent call last):
+    ...
+    ValueError: Value does not provide IFooConfiguration.
+
+Furthermore there is an update method that can be used to update a specific
+configuration. This method can be only used if a configuration already exists:
+
+    >>> configurations.update(IFooConfiguration, {'foo': u'Foo!'})
+    Traceback (most recent call last):
+    ...
+    KeyError: <InterfaceClass zope.generic.configuration.adapter.IFooConfiguration>
+
+You can create valid configuration data using the generic ConfigurationData
+implementation:
+
+    >>> from zope.generic.configuration.base import ConfigurationData
+
+    >>> data = ConfigurationData(IFooConfiguration, {'foo': u'Foo!'})
+
+    >>> configurations[IFooConfiguration] = data
+
+The setting of the configuration is notified by a object configuration
+modified event if the parent has a location an the parent's parent
+is not None:
+
+    >>> events = getEvents()
+    >>> len(events)
+    0
+
+    >>> from zope.app.location import Location
+    >>> parent = Location()
+    >>> configurations.__parent__ = parent
+    
+    >>> configurations[IFooConfiguration] = data
+    >>> events = getEvents()
+    >>> len(events)
+    0
+
+    >>> parent.__parent__ = Location()
+    >>> configurations[IFooConfiguration] = data
+    >>> events = getEvents()
+    >>> len(events)
+    1
+
+    >>> event = events.pop()
+    >>> IObjectConfigurationsModifiedEvent.providedBy(event)
+    True
+    >>> [(key.__name__, value) for key, value in event.items()]
+    [('IFooConfiguration', {'foo': u'Foo!', 'optional': u'Bla'})]
+
+If the configuration data is set the first time an oobtree storage is set
+to the __configurations__ attribute of the context:
+
+    >>> configurations.__nonzero__()
+    True
+
+    >>> IFooConfiguration in configurations
+    True
+
+    >>> configurations[IFooConfiguration] == data
+    True
+
+    >>> [iface.__name__ for iface in configurations.keys()]
+    ['IFooConfiguration']
+
+You should update a configuration using the update method instead of setting
+new configuration data. If the change differs from the configuration an object
+configuration modified event is notify else not:
+
+    >>> clearEvents()
+    >>> configurations.update(IFooConfiguration, {'foo': u'Bar!'})
+    >>> events = getEvents()
+    >>> len(events)
+    1
+    >>> event = events.pop()
+    >>> [(key.__name__, value) for key, value in event.items()]
+    [('IFooConfiguration', {'foo': u'Bar!'})]
+
+Also the deletion is notified:
+
+    >>> clearEvents()
+
+    >>> del configurations[IFooConfiguration]
+    >>> IFooConfiguration in configurations
+    False
+
+    >>> events = getEvents()
+    >>> len(events)
+    1
+    >>> event = events.pop()
+    >>> [(key.__name__, value) for key, value in event.items()]
+    [('IFooConfiguration', {})]
+
+
+Configuration Handler
+---------------------
+
+The configurationHandler directive allows to share public configuration handlers.
+Those handlers have to provide a dedicated marker interface. This interface
+can be used for later lookup of such an handler:
+
+	>>> class IMyConfigurationHandler(interface.Interface):
+	...		pass
+
+	>>> def myConfigurationHandler(event, component, configurations=None, annotations=None):
+	...		print event, component, configurations, annotations
+
+    # make available within the testing module
+    >>> testing.IMyConfigurationHandler = IMyConfigurationHandler
+    >>> testing.myConfigurationHandler = myConfigurationHandler
+
+    >>> registerDirective('''
+    ... <generic:configurationHandler
+    ...     interface='zope.generic.configuration.testing.IMyConfigurationHandler'
+    ...     label='My Configuration Handler' hint='Please use it'
+    ...		handler='zope.generic.configuration.testing.myConfigurationHandler'
+    ...     />
+    ... ''')
+
+After the registration we can retrieve this handler by the following function:
+
+	>>> from zope.generic.configuration.api import queryConfigurationHandler
+
+	>>> handler = queryConfigurationHandler(IMyConfigurationHandler)
+	>>> handler('component', 'event', 'configurations', 'annotations')
+	component event configurations annotations


Property changes on: zope.generic/trunk/src/zope/generic/configuration/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/SETUP.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/SETUP.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.configuration-*.zcml
+</data-files>
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/configuration/SETUP.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/configuration/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/__init__.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/__init__.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.generic.configuration.interfaces import *


Property changes on: zope.generic/trunk/src/zope/generic/configuration/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/adapter.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/adapter.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,142 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from BTrees.OOBTree import OOBTree
+import transaction
+from UserDict import DictMixin
+
+from zope.app.location import Location
+from zope.app.location.interfaces import ILocation
+from zope.component import adapts
+from zope.event import notify
+from zope.interface import implements
+
+from zope.generic.configuration import IAttributeConfigurable
+from zope.generic.configuration import IConfigurationType
+from zope.generic.configuration import IConfigurations
+from zope.generic.configuration.event import Configuration
+from zope.generic.configuration.event import ObjectConfigurationsModifiedEvent
+from zope.generic.configuration.helper import configuratonToDict
+from zope.generic.configuration.helper import dottedName
+from zope.generic.configuration.helper import resolveClass
+
+
+
+class AttributeConfigurations(DictMixin, Location):
+    """Store configurations on an object within the __configurations__ attribute.
+
+    """
+
+    implements(IConfigurations)
+
+    adapts(IAttributeConfigurable)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __nonzero__(self):
+        return bool(getattr(self.context, '__configurations__', 0))
+
+    def __conform__(self, interface):
+        configurations = getattr(self.context, '__configurations__', None)
+        if configurations is None:
+            return None
+
+        else:
+            return configurations.get(dottedName(interface), None)
+
+    def __getitem__(self, interface):
+        configurations = getattr(self.context, '__configurations__', None)
+        if configurations is None:
+            raise KeyError(interface)
+
+        return configurations[dottedName(interface)]
+
+    def keys(self):
+        configurations = getattr(self.context, '__configurations__', None)
+        if configurations is None:
+            return []
+
+        return [resolveClass(iface) for iface in configurations.keys()]
+
+    def update(self, interface, data):
+        current_config = self[interface]
+
+        updated_data = {}
+        errors = []
+        
+        savepoint = transaction.savepoint()
+        try:
+            for name, value in data.items():
+                # raise attribute error
+                field = interface[name]
+                if field.readonly:
+                    raise ValueError(name, 'Data is readonly.')
+                else:
+                    if value != getattr(current_config, name, field.missing_value):
+                        setattr(current_config, name, value)
+                        updated_data[name] = value
+
+            # notify update
+            parent = self.__parent__
+            if updated_data and ILocation.providedBy(parent) and parent.__parent__ is not None:
+                notify(ObjectConfigurationsModifiedEvent(parent, 
+                    Configuration(interface, updated_data)))
+
+        except:
+            savepoint.rollback()
+            raise
+
+    def __setitem__(self, interface, value):
+        # preconditions
+        if not IConfigurationType.providedBy(interface):
+            raise KeyError('Interface key %s does not provide %s.' % 
+                (interface.__name__, IConfigurationType.__name__))
+
+        if not interface.providedBy(value):
+            raise ValueError('Value does not provide %s.' % interface.__name__)
+
+        # essentials
+        try:
+            configurations = self.context.__configurations__
+        except AttributeError:
+            configurations = self.context.__configurations__ = OOBTree()
+
+        data = configuratonToDict(interface, value, all=True)
+        configurations[dottedName(interface)] = value
+        # notify setting
+        parent = self.__parent__
+        if ILocation.providedBy(parent) and parent.__parent__ is not None:
+            notify(ObjectConfigurationsModifiedEvent(parent, 
+                Configuration(interface, data)))
+
+    def __delitem__(self, interface):
+        try:
+            configurations = self.context.__configurations__
+        except AttributeError:
+            raise KeyError(interface)
+
+        del configurations[dottedName(interface)]
+        # notify deletion
+        # notify setting
+        parent = self.__parent__
+        if ILocation.providedBy(parent) and parent.__parent__ is not None:
+            notify(ObjectConfigurationsModifiedEvent(parent, 
+                Configuration(interface, {})))


Property changes on: zope.generic/trunk/src/zope/generic/configuration/adapter.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/api.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/api.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,27 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+# usage see README.txt
+from zope.generic.configuration.base import ConfigurationData
+from zope.generic.configuration.interfaces import *
+from zope.generic.configuration.helper import dottedName
+from zope.generic.configuration.helper import provideConfigurationData
+from zope.generic.configuration.helper import queryConfigurationData
+from zope.generic.configuration.helper import queryConfigurationHandler
+from zope.generic.configuration.helper import queryConfigurationInformation
+from zope.generic.configuration.helper import resolveClass


Property changes on: zope.generic/trunk/src/zope/generic/configuration/api.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/base.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/base.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,205 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+from persistent.dict import PersistentDict
+
+from zope.app.annotation import IAnnotations
+from zope.interface import directlyProvides
+from zope.interface import implements
+from zope.interface.interfaces import IMethod
+from zope.schema.interfaces import IField
+from zope.schema.fieldproperty import FieldProperty
+
+from zope.generic.configuration import IConfigurationHandler
+from zope.generic.configuration import IConfigurations
+from zope.generic.configuration import missing
+
+__all__ = ['ConfigurationData']
+_marker = object()
+
+
+
+class ConfigurationData(Persistent):
+    """Generic configuration data.
+
+    Provide a configuration schema:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IFooConfiguration(Interface):
+        ...    foo = TextLine(title=u'Foo')
+        ...    fuu = TextLine(title=u'Fuu', required=False)
+        ...    fii = TextLine(title=u'Fii', required=False, readonly=True)
+
+    Create a corresponding configuration data:
+
+        >>> config_data = ConfigurationData(IFooConfiguration, {'foo': u'Foo!'})
+        >>> IFooConfiguration.providedBy(config_data)
+        True
+        >>> config_data.foo
+        u'Foo!'
+        >>> config_data.fuu
+        
+        >>> config_data.bar
+        Traceback (most recent call last):
+        ...
+        AttributeError: bar
+        
+        >>> config_data.fii = u'Bla bla'
+        Traceback (most recent call last):
+        ...
+        ValueError: ('fii', 'Data is readonly.')
+
+    If a relevant key is missed within the data a key error is raised:
+
+        >>> config_data = ConfigurationData(IFooConfiguration, {})
+        Traceback (most recent call last):
+        ...
+        KeyError: 'Missed keys: foo.'
+
+    The schema should not contain methods:
+
+        >>> class IBarConfiguration(Interface):
+        ...    bar = TextLine(title=u'Bar')
+        ...    def method(self):
+        ...        pass
+
+        >>> config_data = ConfigurationData(IBarConfiguration, {'bar': u'Bar!', 'method': u'Method!'})
+        >>> config_data.bar
+        u'Bar!'
+        >>> config_data.method
+        Traceback (most recent call last):
+        ...
+        RuntimeError: ('Data value is not a schema field', 'method')
+    """
+
+    def __init__(self, schema, data):
+        # preconditions
+        missedKeys = []
+        for name in schema:
+            if name not in data:
+                field = schema[name]
+                if field.required is True:
+                    missedKeys.append(name)
+        
+        if missedKeys:
+            raise KeyError('Missed keys: %s.' % ', '.join(missedKeys))
+    
+        # essentials
+        self.__dict__['_ConfigurationData__data'] = PersistentDict(data)
+        self.__dict__['_ConfigurationData__schema'] = schema
+        directlyProvides(self, schema)
+
+    def __getattr__(self, name):
+        schema = self.__dict__['_ConfigurationData__schema']
+        data = self.__dict__['_ConfigurationData__data']
+        try:
+            field = schema[name]
+        except KeyError:
+            raise AttributeError(name)
+        else:
+            value = data.get(name, _marker)
+            if value is _marker:
+                value = getattr(field, 'default', _marker)
+                if value is _marker:
+                    raise RuntimeError('Data is missing', name)
+
+            if IMethod.providedBy(field):
+                if not IField.providedBy(field):
+                    raise RuntimeError('Data value is not a schema field', name)
+                v = lambda: value
+            else:
+                v = value
+            # setattr(self, name, v)
+            return v
+        raise AttributeError(name)
+
+    def __setattr__(self, name, value):
+        schema = self.__dict__['_ConfigurationData__schema']
+        data = self.__dict__['_ConfigurationData__data']
+
+        if name != '__provides__':
+            try:
+                field = schema[name]
+            except KeyError:
+                raise AttributeError(name)
+            else:
+                if field.readonly is True:
+                    raise ValueError(name, 'Data is readonly.')
+            data['name'] = value
+        else:
+            super(ConfigurationData, self).__setattr__(name, value)
+
+
+
+class ConfigurationHandler(object):
+    """Configuration handler."""
+
+    implements(IConfigurationHandler)
+
+    interface = FieldProperty(IConfigurationHandler['interface'])
+    passConfigurations = FieldProperty(IConfigurationHandler['passConfigurations'])
+    passAnnotations = FieldProperty(IConfigurationHandler['passAnnotations'])
+
+    def __init__(self, callable, interface=None, passConfigurations=False,
+                 passAnnotations=False):
+
+        self.__callable = callable
+
+        # otherwise use IPrivatConfigurationHandler
+        if interface is not None:
+            self.interface = interface
+
+        self.passAnnotations = passAnnotations
+        self.passConfigurations = passConfigurations
+
+    def __call__(self, component, event, configurations=None, annotations=None):
+        if configurations is None and self.passConfigurations is True:
+            configurations = IConfigurations(component, missing)
+
+        if annotations is None and self.passAnnotations is True:
+            annotations = IAnnotations(component, missing)
+
+        self._apply(component, event, configurations, annotations)
+
+    def _apply(self, component, event, configurations, annotations):
+        # this method can be overwritten by subclasses
+        if self.__callable is not None:
+            return self.__callable(component, event, configurations, annotations)
+
+
+
+class ConfigurationHandlerChain(ConfigurationHandler):
+    """Process a chain of configuration handlers."""
+
+    implements(IConfigurationHandler)
+
+    interface = FieldProperty(IConfigurationHandler['interface'])
+
+    def __init__(self, handlers, interface=None, passConfigurations=True,
+                 passAnnotations=True):
+        super(ConfigurationHandlerChain, self).__intit__(None, interface, passConfigurations, passAnnotations)
+        self.__handlers = handlers
+
+    def _apply(self, component, event, configurations, annotations):
+        """Invoke handler in the listed order."""
+        [handler(component, event, configurations, annotations) for handler in self.__handlers]


Property changes on: zope.generic/trunk/src/zope/generic/configuration/base.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,30 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:generic="http://namespaces.zope.org/generic"
+  i18n_domain="zope">
+ 
+ 
+  <generic:information
+      interface=".IConfigurationInformation"
+      label="Configuration Information"
+      registry="zope.generic.information.IInformationRegistryInformation"
+      />
+ 
+   <!-- attribute configurations -->
+  <class class=".adapter.AttributeConfigurations">
+    <allow
+        attributes="__contains__ keys __getitem__ get"
+        />
+    <require
+        permission="zope.ManageSite"
+        attributes="__setitem__ __delitem__"
+        />
+  </class>
+
+  <adapter 
+  	  factory=".adapter.AttributeConfigurations"
+  	  provides="zope.generic.configuration.IConfigurations"
+  	  trusted="True"
+  	  />
+ 
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/configuration/configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/event.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/event.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/event.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,141 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.event.objectevent import ObjectModifiedEvent
+from zope.interface import implements
+
+from zope.generic.configuration import IObjectConfigurationsModifiedEvent
+from zope.generic.configuration import IConfigurationModificationDescription
+
+
+
+class Configuration(object) :
+    """Describes a single modified configuration.
+
+    A possible configuration schema:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IMyConfiguration(Interface):
+        ...     my = TextLine(title=u'My')
+
+    Check interface implementation:
+        
+        >>> description = Configuration(IMyConfiguration, {'my': u'Bla'})
+
+        >>> IConfigurationModificationDescription.providedBy(description)
+        True
+
+        >>> description.interface == IMyConfiguration
+        True
+
+        >>> 'my' in description.data
+        True
+        >>> description.data.get('my')
+        u'Bla'
+
+    If no data argument is set, the data attribute will be set to an empty
+    dict, which implies that the configuration was deleted:
+
+        >>> description = Configuration(IMyConfiguration)
+        >>> description.interface == IMyConfiguration
+        True
+
+        >>> description.data
+        {}
+
+    """
+
+    implements(IConfigurationModificationDescription)
+
+    def __init__(self, interface, data=None) :
+        self.interface = interface
+        if data is not None:
+            self.data = data
+
+        else:
+            self.data = {}
+
+
+
+class ObjectConfigurationsModifiedEvent(ObjectModifiedEvent):
+    """An object's configurations has been modified.
+        
+    A possible configuration schema:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+                
+        >>> class IMyConfiguration(Interface):
+        ...     my = TextLine(title=u'My')
+        
+        >>> class IYourConfiguration(Interface):
+        ...     your = TextLine(title=u'Your')
+         
+        >>> class IRegularInterface(Interface):
+        ...    pass
+ 
+    A possible event:
+ 
+        >>> descriptions = []
+        >>> descriptions.append(Configuration(IMyConfiguration, {'my': u'Bla'}))
+        >>> descriptions.append(Configuration(IYourConfiguration))
+        >>> from zope.app.event.objectevent import Attributes
+        >>> descriptions.append(Attributes(IRegularInterface))
+        >>> context = object()
+        >>> event = ObjectConfigurationsModifiedEvent(context, *descriptions)
+
+    There are two convenience function to introspect configuration modifications
+    specifically:
+
+        >>> len(event.descriptions) is 3
+        True
+
+        >>> items = event.items()
+        >>> len(items) is 2
+        True
+        >>> [(interface.__name__, data) for interface, data in items]
+        [('IMyConfiguration', {'my': u'Bla'}), ('IYourConfiguration', {})]
+
+        >>> event.get(IMyConfiguration)
+        {'my': u'Bla'}
+
+        >>> event.get(IYourConfiguration)
+        {}
+
+        >>> event.get(IRegularInterface, 'default')
+        'default'
+    """
+
+    implements(IObjectConfigurationsModifiedEvent)
+
+    def items(self):
+        return [(d.interface, d.data) for d in self.descriptions 
+                   if IConfigurationModificationDescription.providedBy(d)]
+
+    def get(self, interface, default=None):
+        result = [d.data for d in self.descriptions 
+                   if IConfigurationModificationDescription.providedBy(d) and d.interface is interface]
+        if result:
+            return result[0]
+
+        else:
+            return default


Property changes on: zope.generic/trunk/src/zope/generic/configuration/event.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/helper.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,156 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+
+from zope.dottedname.resolve import resolve
+from zope.component import getUtility
+
+from zope.generic.configuration import IConfigurationHandlerConfiguration
+from zope.generic.configuration import IConfigurationHandlerInformation
+from zope.generic.configuration import IConfigurationInformation
+from zope.generic.configuration import IConfigurations
+
+
+
+def dottedName(klass):
+    if klass is None:
+        return 'None'
+    return klass.__module__ + '.' + klass.__name__
+
+
+
+# cache
+__name_to_klass = {}
+
+def resolveClass(name):
+    try:
+        return __name_to_klass[name]
+    except KeyError:
+        return __name_to_klass.setdefault(name, resolve(name))
+
+
+
+def getConfigurationInformation(interface):
+    return getInformation(interface, IConfigurationInformation)
+
+
+
+def queryConfigurationInformation(interface, default=None):
+    # cyclic import :(
+    from zope.generic.information.api import queryInformation
+    
+    return queryInformation(interface, IConfigurationInformation, default)
+
+
+
+def queryConfigurationData(context, interface, default=None):
+    """Evaluate corresponding configuration data satisfying the interface."""
+
+    configurations = IConfigurations(context, default)
+
+    if configurations is default:
+        return default
+
+    else:
+        return interface(configurations, default)
+
+
+def provideConfigurationData(context, interface, data):
+    """Set configuration data into the context."""
+    from zope.generic.configuration.base import ConfigurationData 
+    if type(data) is dict:
+        data = ConfigurationData(interface, data)
+
+    configurations = IConfigurations(context)
+    configurations[interface] = data
+
+
+
+def queryConfigurationHandler(interface, default=None):
+    # cyclic import :(
+    from zope.generic.information.api import queryInformation
+    
+    info = queryInformation(interface, IConfigurationHandlerInformation, None)
+    
+    if info is None:
+        return default
+    
+    configuration = queryConfigurationData(info, IConfigurationHandlerConfiguration)
+    
+    if configuration is None:
+        return default
+
+    else:
+        return configuration.handler
+
+
+
+_marker = object()
+
+def configuratonToDict(interface, configuration, all=False):
+    """Extract values from configuration to a dictionary.
+
+    First we have to specify a test configurtion interface:
+
+        >>> from zope.interface import Interface
+        >>> from zope.schema import TextLine
+        
+        >>> class IFooConfiguration(Interface):
+        ...    fo = TextLine(title=u'Fo')
+        ...    foo = TextLine(title=u'Foo', required=False)
+        ...    fooo = TextLine(title=u'Fooo', required=False, readonly=True, default=u'fooo bla')
+
+    Minimal data without defaults:
+
+        >>> from zope.generic.configuration.base import ConfigurationData
+        >>> configuration = ConfigurationData(IFooConfiguration, {'fo': 'fo bla'})
+        >>> configuratonToDict(IFooConfiguration, configuration)
+        {'fo': 'fo bla'}
+
+    Including defaults:
+        >>> configuratonToDict(IFooConfiguration, configuration, all=True)
+        {'fooo': u'fooo bla', 'foo': None, 'fo': 'fo bla'}
+
+    """
+    data = {}
+    for name in interface:
+        value = getattr(configuration, name, _marker)
+        field = interface[name]
+
+        if field.required is False:
+            if value is not _marker and value != field.default:
+               data[name] = value
+
+            elif value == field.default:
+                if all:
+                    data[name] = value
+
+            else:
+                if all:
+                    data[name] = field.default
+        
+        elif value is not _marker:
+            data[name] = value
+
+        else:
+            raise RuntimeError('Data is missing', name)
+
+    return data
+        
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/configuration/helper.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/interfaces.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/interfaces.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,270 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.event.interfaces import IModificationDescription
+from zope.app.event.interfaces import IObjectModifiedEvent
+from zope.app.location import ILocation
+from zope.interface import Interface
+from zope.interface import alsoProvides
+from zope.interface import Attribute
+from zope.interface.interfaces import IInterface
+from zope.schema import Bool
+from zope.schema import Dict
+from zope.schema import Object
+from zope.schema import Tuple
+
+from zope.app.i18n import ZopeMessageFactory as _
+
+from zope.generic.information import IInformation
+from zope.generic.information import IInformationDeclaration
+
+__all__ = ['AnnotationKey', 'IConfigurable', 'IAttributeConfigurable',
+           'IAnnotationsConfigurable', 'IConfigurationType', 
+           'IConfigurationModificationDescription', 
+           'IObjectConfigurationsModifiedEvent', 'IReadConfigurations',
+           'IUpdateConfigurations', 'IWriteConfigurations', 'IConfigurations',
+           'IConfigurationInformation', 'IConfigurationHandlerInformation',
+           'IConfigurationHandlerType', 'IPrivateHandler',
+           'IConfigurationHandler', 'missing', 'IConfigurationHandlerConfiguration']
+
+
+
+AnnotationKey = 'zope.generic.configuration.IConfigurations'
+
+
+
+class IConfigurable(Interface):
+    """Marker interface for objects that support storing configuraitons."""
+
+
+
+class IAttributeConfigurable(IConfigurable):
+    """Marker indicating that configurations can be stored on an attribute.
+    
+    This is a marker interface giving permission for an `IConfigurations`
+    adapter to store data in an attribute named `__configurations__`.
+
+    """
+
+
+
+class IAnnotationsConfigurable(IConfigurable):
+    """Marker indicating that configurations can be stored on annotations.
+
+    """
+
+
+
+class IConfigurationType(IInterface):
+    """Mark a configuration data schema.
+    
+    Typed schemas might be rendered to xml to provide a configuration view of an
+    object.
+    """
+
+
+
+class IConfigurationModificationDescription(IModificationDescription):
+    """Declares the modified configuration by its interface and
+    the corresponding data that got modified.
+
+    An empty data dictionary implies that the configuration was deleted."""
+
+    interface = Attribute("The involved configuratoin interface.")
+    data = Attribute("A dict of modified configuration data.")
+
+
+
+class IObjectConfigurationsModifiedEvent(IObjectModifiedEvent):
+    """An object's configurations has been modified.
+    
+    The corresponding modifications will be attached on the description attribute
+    """
+
+    descriptions = Attribute("Sequence of modifiaction descriptions.")
+
+    def items():
+        """List affected configuration interfaces and corresponding data from the descriptions."""
+
+    def get(interface, default=None):
+        """Return affected configuration data from the description or default."""
+
+
+
+class IReadConfigurations(Interface):
+    """Read configurations."""
+
+    def __conform__(interface):
+        """Invoke values that are stored under the interface-key.
+
+        Regularly the interface-key should provide configuration type.
+        If no value could be found None is returned.
+        """
+
+    def __nonzero__():
+        """Test whether there are any configurations."""
+
+    def __getitem__(interface):
+        """Return the configuration stored under interface-key.
+
+        Raises a KeyError if the key is not found.
+        """
+
+    def keys(self):
+        """Return stored configuraitons keys."""
+
+
+
+class IUpdateConfigurations(Interface):
+    """Update configurations."""
+
+    def update(interface, data):
+        """Update configuration partially if nessecary.
+
+        data - dict providing values corresponding to the attribute names of the 
+            interface.
+        
+        The data object itself will not be saved, only the values that
+        differs from the existing configuration data within the configurations.
+        
+        A ValueError is raised if an read-only attribute/value should be set.
+        A AttributeError is raised if a not declared name should be set.
+        A KeyError is raise if there is no corresponding configuration avaiable.
+        
+        A successfull update is notified by a ObjectConfigurationModifiedEvent if
+        any value of the configuration got changed and the parent providing 
+        ILocation.
+        """
+
+
+
+class IWriteConfigurations(Interface):
+    """Set or delete a configuration."""
+
+    def __setitem__(interface, value):
+        """Store a certain configuration data under the interface-key.
+
+        The interface should provide IConfigurationType.
+
+        The value has to provide the declared interface key and this value will
+        be invoked by the __conform__ mechanism if somebody try to adapt the 
+        configuration data to this interface.
+        
+        A successfull setting is notified by a ObjectConfigurationModifiedEvent
+        if the parent providing ILocation.
+        """
+
+    def __delitem__(interface):
+        """Removes the configuration stored under interface-key.
+
+        Raises a KeyError if the key is not found.
+
+        A successfull deletion is notified by a ObjectConfigurationModifiedEvent
+        if the parent providing ILocation.
+        """
+
+
+
+class IConfigurations(IReadConfigurations, IUpdateConfigurations, 
+                      IWriteConfigurations, IConfigurable, ILocation):
+    """United configurations interfaces."""
+
+    
+
+class IConfigurationInformation(IInformation):
+    """Information about a configuration."""
+
+
+
+class IConfigurationHandlerInformation(IInformation):
+    """Information about a configuration handler."""
+
+
+
+class IConfigurationHandlerType(IInterface):
+    """Type a configuration handler marker interface."""
+
+
+
+class IPrivateHandler(Interface):
+    """Mark a private configuration handler.
+
+    Configuration handlers marked by this marker should not be used from
+    other parties.
+
+    """
+
+alsoProvides(IPrivateHandler, IConfigurationHandlerType)
+
+
+
+missing = object()
+
+class IConfigurationHandler(IInformationDeclaration):
+    """A configuration handler.
+
+    A handler marked by this type provides a certain configuration procdure 
+    functionality."""
+
+    interface = Object(
+        title=_('Interface'),
+        description=_('Interface marker that references corresponding informations.'),
+        default=IPrivateHandler,
+        schema=IConfigurationHandlerType)
+
+    passConfigurations = Bool(
+        title=_('Lookup Configurations?'),
+        description=_('Should component configurations be invoked by the handler'),
+        default=False)
+
+    passAnnotations = Bool(
+        title=_('Lookup Annotations?'),
+        description=_('Should component annotations be invoked by the handler'),
+        default=False)
+
+    def __call__(component, event, configurations=None, annotations=None):
+        """Configure the component.
+
+        A None value for annotations or configurations implies, that no 
+        configuration was looked up before.
+
+        If you couldn't look up a configurations or annotations you shoul
+        pass the missing marker object.
+
+        If configurations is missing or passConfigurations is False,
+        the handler should provide its own default configuration itself.
+
+        If annotations is missing or passAnnotations is False, 
+        the handler should provide its own default configuration itself.
+
+        """
+
+
+
+class IConfigurationHandlerConfiguration(Interface):
+    """The configuration for the configuration handler registration."""
+
+    handler = Object(
+        title=_('Configuration Handler'),
+        description=_('Registered configuration handler.'),
+        required=True,
+        schema=IConfigurationHandler)
+
+alsoProvides(IConfigurationHandlerConfiguration, IConfigurationType)


Property changes on: zope.generic/trunk/src/zope/generic/configuration/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/meta.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/meta.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,21 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/generic">
+
+    <meta:directive
+        name="configuration"
+        schema=".metadirectives.IConfigurationDirective"
+        handler=".metaconfigure.configurationDirective"
+        />
+
+    <meta:directive
+        name="configurationHandler"
+        schema=".metadirectives.IConfigurationHandlerDirective"
+        handler=".metaconfigure.configurationHandlerDirective"
+        />
+
+  </meta:directives>
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/configuration/meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/metaconfigure.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/metaconfigure.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,106 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Projekt01 GmbH and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.component.interface import provideInterface
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface import alsoProvides
+
+from zope.generic.information.api import queryInformation
+from zope.generic.information.metaconfigure import provideInformation
+
+from zope.generic.configuration import IConfigurationHandler
+from zope.generic.configuration import IConfigurationHandlerConfiguration
+from zope.generic.configuration import IConfigurationHandlerInformation
+from zope.generic.configuration import IConfigurationHandlerType
+from zope.generic.configuration import IConfigurationInformation
+from zope.generic.configuration import IConfigurationType
+from zope.generic.configuration import IConfigurations
+
+from zope.generic.configuration.base import ConfigurationData
+from zope.generic.configuration.base import ConfigurationHandler
+
+
+
+def configurationDirective(_context, interface, label=None, hint=None):
+    """Provide new configuration information."""
+
+    registry = IConfigurationInformation
+    iface_type = IConfigurationType
+
+    # assert type as soon as possible
+    if not iface_type.providedBy(interface):
+        alsoProvides(interface, iface_type)
+
+    _context.action(
+        discriminator = ('provideInformation', interface, registry),
+        callable = provideInformation,
+        args = (interface, registry, label, hint),
+        )
+
+    _context.action(
+        discriminator = None,
+        callable = provideInterface,
+        args = (None, interface, iface_type),
+        )  
+
+
+def provideConfigurationHandlerConfiguration(interface, handler):
+    """Provide the handler to an configuration information."""
+    
+    registry = IConfigurationHandlerInformation
+    info = queryInformation(interface, IConfigurationHandlerInformation)
+
+    # this should never happen...
+    if info is None:
+        ConfigurationError('No configuration handler information for %s' 
+                           % interface.__name__)
+
+    # Eventually wrap a callable
+    if not IConfigurationHandler.providedBy(handler):
+        handler = ConfigurationHandler(handler, interface)
+
+    configurations = IConfigurations(info)
+    # create configuration data
+    data = ConfigurationData(IConfigurationHandlerConfiguration, {'handler': handler})
+    # set configuration data
+    configurations[IConfigurationHandlerConfiguration] = data
+
+
+
+def configurationHandlerDirective(_context, interface, handler, label=None, hint=None):
+    """Register a public configuration handler."""
+
+    # assert type as soon as possible
+    if not IConfigurationHandlerType.providedBy(interface):
+        alsoProvides(interface, IConfigurationHandlerType)
+
+    registry = IConfigurationHandlerInformation
+
+    _context.action(
+        discriminator = ('provideInformation', interface, registry),
+        callable = provideInformation,
+        args = (interface, registry, label, hint),
+        )
+    
+    _context.action(
+        discriminator = ('provideConfigurationHandlerConfiguration', interface, handler),
+        callable = provideConfigurationHandlerConfiguration,
+        args = (interface, handler),
+        )


Property changes on: zope.generic/trunk/src/zope/generic/configuration/metaconfigure.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/metadirectives.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/metadirectives.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.configuration.fields import GlobalObject
+
+from zope.app.i18n import ZopeMessageFactory as _
+
+from zope.generic.information.metadirectives import IBaseInformationDirective
+
+
+
+class IConfigurationDirective(IBaseInformationDirective):
+    """Declare configuration schema.
+
+    Register configuration schema as interface utility typed by
+    IConfigurationType within the configuration registry utility.    
+    """
+
+
+
+class IConfigurationHandlerDirective(IBaseInformationDirective):
+    """Declare a public configuration handler.
+
+    Register configuration handler as interface utility typed by
+    IConfigurationHandlerType.
+    
+    """
+
+    handler = GlobalObject(
+        title=_('Configuration Handler'),
+        description=_('Configuration handler or callable with the signature' +
+                      '(componet, event, configuration=None, annotations=None).'),
+        required=True
+        )


Property changes on: zope.generic/trunk/src/zope/generic/configuration/metadirectives.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/testing.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/testing.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,87 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.component import provideAdapter
+from zope.configuration.xmlconfig import XMLConfig
+from zope.interface import Interface
+from zope.schema import TextLine
+
+from zope.generic.configuration import IConfigurations
+
+import zope.generic.information.testing
+
+
+################################################################################
+#
+# Public Test implementations
+#
+################################################################################
+
+class IMarker(Interface):
+    """Demo marker."""
+
+
+class IFooConfiguration(Interface):
+
+    foo = TextLine(title=u'Foo')
+    
+    fo = TextLine(title=u'Fo', required=False, readonly=True, default=u'fo default')
+
+
+class IBarConfiguration(Interface):
+
+    bar = TextLine(title=u'Bar')
+
+
+class IInputConfiguration(Interface):
+
+    foo = TextLine(title=u'Foo')
+
+    bar = TextLine(title=u'Bar')
+
+
+
+################################################################################
+#
+# Placeless setup
+#
+################################################################################
+
+
+class PlacelessSetup(zope.generic.information.testing.PlacelessSetup):
+
+    def setUp(self, doctesttest=None):
+        super(PlacelessSetup, self).setUp(doctesttest)
+
+        # register attribute configurations adapter
+        import zope.generic.configuration.adapter
+        provideAdapter(zope.generic.configuration.adapter.AttributeConfigurations,
+            provides=IConfigurations)
+
+        # register the directive of this package
+        import zope.generic.configuration
+        XMLConfig('meta.zcml', zope.generic.configuration)()
+
+    def tearDown(self, doctesttest=None):
+        super(PlacelessSetup, self).tearDown(doctesttest)
+
+
+
+placelesssetup = PlacelessSetup()


Property changes on: zope.generic/trunk/src/zope/generic/configuration/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/tests.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/tests.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,73 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+import unittest
+
+from zope import component
+from zope import interface
+from zope.testing import doctest
+
+from zope.generic.testing.testing import InterfaceBaseTest
+from zope.generic.testing.testing import registerDirective
+
+from zope.generic.configuration import testing
+from zope.generic.configuration.base import ConfigurationData
+
+
+
+class ConfigurationDataTest(InterfaceBaseTest):
+
+    _verify_class = False
+    _test_interface = testing.IFooConfiguration
+    _test_class = ConfigurationData
+    _test_pos = (testing.IFooConfiguration, {'foo': u'Bla bla'})
+
+    def test_readonly_attributes(self):
+        interface = self._test_interface
+        test_obj = self.makeTestObject()
+        for name in interface:
+            field = interface[name]
+            if field.readonly is True:
+                self.assertRaises(ValueError, setattr, test_obj, name, object())
+
+    def test_default_value(self):
+        interface = self._test_interface
+        test_obj = self.makeTestObject()
+        fo_field = interface['fo']
+        self.assertEqual(getattr(test_obj, 'fo'), fo_field.default)
+
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(ConfigurationDataTest),
+        doctest.DocTestSuite('zope.generic.configuration.base'),
+        doctest.DocTestSuite('zope.generic.configuration.adapter'),
+        doctest.DocTestSuite('zope.generic.configuration.event'),
+        doctest.DocTestSuite('zope.generic.configuration.helper'),
+        doctest.DocFileSuite('README.txt',
+                             setUp=testing.placelesssetup.setUp,
+                             tearDown=testing.placelesssetup.tearDown,
+                             globs={'component': component, 'interface': interface,
+                             'registerDirective': registerDirective,
+                             'testing': testing},
+                             optionflags=doctest.NORMALIZE_WHITESPACE+
+                                            doctest.ELLIPSIS),
+                              ))
+
+if __name__ == '__main__': unittest.main()


Property changes on: zope.generic/trunk/src/zope/generic/configuration/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.configuration" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-meta.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-meta.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.configuration" file="meta.zcml" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/configuration/zope.generic.configuration-meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/DEPENDENCIES.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/DEPENDENCIES.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,8 @@
+zope.generic.testing
+zope.app.event
+zope.app.testing
+zope.component
+zope.event
+zope.interface
+zope.schema
+zope.testing


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/directlyprovides/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/PUBLICATION.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/PUBLICATION.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,8 @@
+Metadata-Version: 1.0
+Name: zope.generic.directlyprovides
+Summary: Controllable Directly Provides Mechanism
+Author: Dominik Huber, Perse Engineering GmbH, Switzerland
+Author-email: dominik.huber at perse.ch
+License: ZPL 2.1
+Description:
+        Provide facility to control directly provides mechanism partially.


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/PUBLICATION.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/directlyprovides/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/README.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/README.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,372 @@
+=================
+Directly Provides
+=================
+
+The `zope.interface` package offers the powerful mechanism of directly provided
+interfaces that means instance-specific interfaces.
+
+Directly provided interfaces today have the most important impact to 
+interface-based lookups for example within the adapter registry, therefore the 
+directly provided interface can fully control/determine the behavior of
+applications based on the component architecture.
+
+The problem is that those interface cannot be controlled properly:
+
+- Ordering depends on the chronological order, but often this order
+  cannot asserted properly other a later interface is hidden by an
+  earlier one.
+
+- No event notification even though the whole adaption based behavior might
+  have changed.
+
+- Sometimes an other order that the cronological should be asserted. That
+  means dedicated directly provided interfaces should be prepended someway.
+
+Those lacks might lead to mistaken lookups. The scope of this package
+is to provide better controll over the directly provided mechanism.
+
+Now we will explore this behavior in a small showcase. There are four
+interfaces IA, IB, IC, ID marking instances that will be adapted. The interface
+IResult is the target resp. provided interface. The class A and the adapters 
+ResultForA, ResultForB, ResultForC, ResultForD are representing corresponding 
+sample implementations:
+
+    >>> class IA(interface.Interface):
+    ...     pass
+
+    >>> class IB(interface.Interface):
+    ...     pass
+
+    >>> class IC(interface.Interface):
+    ...     pass
+
+    >>> class ID(interface.Interface):
+    ...     pass
+
+    >>> class IResult(interface.Interface):
+    ...     pass
+
+    >>> class A(object):
+    ...     interface.implements(IA)
+
+    >>> class ResultForA(object):
+    ...     interface.implements(IResult)
+    ...     component.adapts(IA)
+    ...     def __init__(self, context):
+    ...         pass
+
+    >>> class ResultForB(object):
+    ...     interface.implements(IResult)
+    ...     component.adapts(IB)
+    ...     def __init__(self, context):
+    ...         pass
+
+    >>> class ResultForC(object):
+    ...     interface.implements(IResult)
+    ...     component.adapts(IC)
+    ...     def __init__(self, context):
+    ...         pass
+
+    >>> class ResultForD(object):
+    ...     interface.implements(IResult)
+    ...     component.adapts(ID)
+    ...     def __init__(self, context):
+    ...         pass
+
+    >>> component.provideAdapter(ResultForA)
+    >>> component.provideAdapter(ResultForB)
+    >>> component.provideAdapter(ResultForC)
+    >>> component.provideAdapter(ResultForD)
+
+First we adapt an instance of `A` regularly:
+
+    >>> a = A()
+    >>> IResult(a)
+    <ResultForA object at ...>
+
+If we directly provides an interface, for example IB, the
+corresponding adapter `ResultForB` will be looked up:
+
+    >>> interface.directlyProvides(a, IB)
+    >>> IResult(a)
+    <ResultForB object at ...>
+
+    >>> interface.alsoProvides(a, IC)
+    >>> IResult(a)
+    <ResultForB object at ...>
+
+Given the fact that different orthagonal application such as the site
+framework uses the directly provided mechanism it is not possible
+to determine the order of directly provided interfaces in respect to
+the point in time when it will be setted:
+
+    >>> a = A()
+
+    >>> interface.directlyProvides(a, IC) 
+    >>> IResult(a)
+    <ResultForC object at ...>
+
+    >>> interface.alsoProvides(a, IB)
+    >>> IResult(a)
+    <ResultForC object at ...>
+
+As long as different directly provided interfaces do not overlap
+features this unordered aspect is not relevant.
+
+One possibility is to rely heavly on this directly provides mechanism
+to model business domains using generic base classes and marker interfaces
+differing the business types. All features of generic business objects
+could be provided by adaption. In those edge cases it would be more
+comfortable to have partial control over the directly provided mechanism.
+
+The package `zope.generic.directlyprovides` offers the functionality to
+control directly provided interfaces partially. In the next showcase
+we implement a generic class Prependes. The attribute `prepended` offers
+a list of interfaces that should be prepended to the directly provided
+interfaces.
+
+First we define an interface deriving from IProvides:
+
+    >>> from zope.interface.interfaces import IInterface
+    >>> from zope.generic.directlyprovides import api
+
+    >>> class IPrepender(api.IProvides):
+    ...
+    ...     first = schema.Tuple(title=u'First',
+    ...         description=u'Prepend the listed interfaces first.',
+    ...         default=(),
+    ...         value_type=schema.Object(schema=IInterface))
+    ...
+    ...     second = schema.Tuple(title=u'Second',
+    ...         description=u'Prepend the listed interfaces second.',
+    ...         default=(),
+    ...         value_type=schema.Object(schema=IInterface))
+
+Then we have to implement the interface within the class Prepender.
+
+The *provides* defines the relevant attributes that contains the
+interfaces that should be prepented to the directly provided interfaces.
+
+We can use the decorator `updateProvides` or the property UpdateProvides
+to update the directly provide mechanism if the value of the prepended 
+attribute is newly set.
+
+We declare the field that stores the value and we can determine optional
+pre- and post-hooks that should offer three parameters `self`, `new` 
+and `old` as signature:
+
+    >>> def before_hook(self, new, old):
+    ...     print 'before'
+
+    >>> def after_hook(self, new, old):
+    ...     print 'after',
+    ...     print str(tuple([iface.__name__ for iface in old])),
+    ...     print 'to ' + str(tuple([iface.__name__ for iface in new]))
+
+If the directly provided interfaces has changed an directly provides event
+is notified. We register an handler for this event:
+
+    >>> from zope.interface import directlyProvidedBy
+    >>> def notifyDirectlyProvidesModifiedEvent(component, event):
+    ...     print 'directlyProvided changed', str(tuple([iface.__name__  
+    ...         for iface in interface.directlyProvidedBy(event.object)]))
+
+    >>> ztapi.subscribe((api.IProvides, api.IDirectlyProvidesModifiedEvent), None, 
+    ...     notifyDirectlyProvidesModifiedEvent)
+
+    >>> from zope.app.event.interfaces import IObjectModifiedEvent
+
+    >>> def notifyObjectModifiedEvent(first, second=None):
+    ...     if second:
+    ...         print 'Object modified (multi subscriber), ',
+    ...         first = second
+    ...     else:
+    ...         print 'Object modified (single subscriber), ',
+    ...     description = first.descriptions[0]
+    ...     print description.interface.__name__, description.attributes
+    
+
+    >>> ztapi.subscribe((IObjectModifiedEvent,), None, 
+    ...     notifyObjectModifiedEvent)
+
+    >>> ztapi.subscribe((IPrepender, IObjectModifiedEvent,), None, 
+    ...     notifyObjectModifiedEvent)
+
+Now we are implementing an example class using the before- and after-hook.
+For documentation purposes we use for the `first` attribute the decorator and
+for the `second` attribute the property:
+
+    >>> class Prepender(object):
+    ...
+    ...     interface.implements(IPrepender)
+    ...     api.provides('first', 'second')
+    ...
+    ...     def _g_first(self):
+    ...         return self.__dict__.get('prepended', ())
+    ...
+    ...     @api.updateProvides(IPrepender['first'], before_hook, after_hook)
+    ...     def _s_first(self, value):
+    ...         if value:
+    ...             self.__dict__['prepended'] = value
+    ...         else:
+    ...             del self.__dict__['prepended']
+    ...
+    ...     first = property(_g_first, _s_first)
+    ...
+    ...     second = api.UpdateProvides(IPrepender['second'], before_hook, after_hook)
+
+Now, we are going to use our example implementation. At the beginning
+the generic prepended instance does not provide any adaptable interface,
+therefore an error is raised if we try to adapt to IResult:
+
+    >>> p = Prepender()
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    []
+    >>> IResult(p)
+    Traceback (most recent call last):
+    ...
+    TypeError: ('Could not adapt'...)
+
+After that we provide IB directly:
+
+    >>> interface.directlyProvides(p, IB) 
+    directlyProvided changed ('IB',)
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IB']
+    >>> IResult(p)
+    <ResultForB object at ...>
+
+Another assignment is appended:
+
+    >>> interface.alsoProvides(p, IA)
+    directlyProvided changed ('IB', 'IA')
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IB', 'IA']
+
+    >>> IResult(p)
+    <ResultForB object at ...>
+
+But if we use our prepend mechanism the interface is prepended:
+
+    >>> p.second = (ID, )
+    before
+    directlyProvided changed ('ID', 'IB', 'IA')
+    after () to ('ID',)
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['ID', 'IB', 'IA']
+
+    >>> IResult(p)
+    <ResultForD object at ...>
+
+    >>> p.first = (IC, )
+    before
+    directlyProvided changed ('IC', 'ID', 'IB', 'IA')
+    after () to ('IC',)
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IC', 'ID', 'IB', 'IA']
+
+    >>> IResult(p)
+    <ResultForC object at ...>
+
+The value of the decorated attribute or the property will be only set if the
+old and new value differs:
+
+    >>> p.first = (IC, )
+    >>> p.second = (ID, )
+
+We can remove the prepended interface setting an empty tuple:
+
+    >>> p.first = ()
+    before
+    directlyProvided changed ('ID', 'IB', 'IA')
+    after ('IC',) to ()
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['ID', 'IB', 'IA']
+
+    >>> IResult(p)
+    <ResultForD object at ...>
+
+If the twice the same interface is set only the first is accepted. 
+Attention, in this case no directly provides event is notified, because
+the order of the directly provided interfaces did not change:
+
+    >>> p.first = (ID,)
+    before
+    after () to ('ID',)
+    
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['ID', 'IB', 'IA']
+
+We can add more than one or switch them:
+
+    >>> p.first = (ID, IC)
+    before
+    directlyProvided changed ('ID', 'IC', 'IB', 'IA')
+    after ('ID',) to ('ID', 'IC')
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['ID', 'IC', 'IB', 'IA']
+    >>> IResult(p)
+    <ResultForD object at ...>
+
+    >>> p.first = (IC, ID)
+    before
+    directlyProvided changed ('IC', 'ID', 'IB', 'IA')
+    after ('ID', 'IC') to ('IC', 'ID')
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IC', 'ID', 'IB', 'IA']
+    >>> IResult(p)
+    <ResultForC object at ...>
+
+We can remove a regular directly provided:
+
+    >>> interface.directlyProvides(p, interface.directlyProvidedBy(p) - IB)
+    directlyProvided changed ('IC', 'ID', 'IA')
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IC', 'ID', 'IA']
+    >>> IResult(p)
+    <ResultForC object at ...>
+
+But we cannot remove a prepended one. Attention, in this case no directly provides
+event is notified, because the directly provided interfaces
+did not change:
+
+    >>> interface.directlyProvides(p, interface.directlyProvidedBy(p) - IC)
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IC', 'ID', 'IA']
+    >>> IResult(p)
+    <ResultForC object at ...>
+
+If we like to remove prepended one, we have to set the corresponding attribute.
+Take care, sometimes a second prepended still offfers an removed interface:
+
+    >>> p.first = (IA,)
+    before
+    directlyProvided changed ('IA', 'ID')
+    after ('IC', 'ID') to ('IA',)
+
+    >>> [iface.__name__ for iface in interface.directlyProvidedBy(p)]
+    ['IA', 'ID']
+    >>> IResult(p)
+    <ResultForA object at ...>
+
+There is event dispatcher to object modified events provided if the object
+providing IProvides is marked by IObjectModifiedEventDispatchingProvides:
+
+    >>> interface.classImplements(Prepender, 
+    ...     api.IObjectModifiedEventDispatchingProvides)
+
+    >>> p.first = (IB,)
+    before
+    directlyProvided changed ('IB', 'ID')
+    Object modified (multi subscriber),  IProvides ('__provides__',)
+    Object modified (single subscriber),  IProvides ('__provides__',)
+    after ('IA',) to ('IB',)


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/SETUP.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/SETUP.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.directlyprovides-*.zcml
+</data-files>
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/SETUP.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/directlyprovides/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/__init__.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/__init__.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.generic.directlyprovides.interfaces import *
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/api.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/api.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+# usage see README.txt
+
+from zope.generic.directlyprovides.interfaces import *
+from zope.generic.directlyprovides.event import DirectlyProvidesModifiedEvent
+from zope.generic.directlyprovides.decorator import updateProvides
+from zope.generic.directlyprovides.helper import updateDirectlyProvided
+from zope.generic.directlyprovides.property import provides
+from zope.generic.directlyprovides.property import UpdateProvides


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/api.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,10 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  i18n_domain="zope">
+
+  <subscriber
+      for=".IDirectlyProvidesModifiedEvent"
+      handler=".handler.notifyObjectModifiedEvent"
+      />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/decorator.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/decorator.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/decorator.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.generic.directlyprovides.helper import updateDirectlyProvided
+
+
+
+def updateProvides(field, before=None, after=None):
+    def decorator(f):
+        def new_f(self, value):
+            # remember the previous value
+            previous_value = getattr(self, field.__name__)
+
+            if previous_value != value:
+                # invoke before
+                if before:
+                    before(self, value, previous_value)
+
+                # call decorated function
+                result = f(self, value)
+
+                # update directly provides
+                updateDirectlyProvided(self, value, previous_value)
+
+                # invoke after
+                if after:
+                    after(self, value, previous_value)
+
+                return result
+            return None
+
+        new_f.func_name = f.func_name
+        return new_f
+    return decorator


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/decorator.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/event.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/event.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/event.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+
+from zope.generic.directlyprovides import IDirectlyProvidesModifiedEvent
+
+
+
+class DirectlyProvidesModifiedEvent(object):
+    """Directly provides event.
+
+    Event with two marker types:
+
+        >>> obj = object()
+        >>> event = DirectlyProvidesModifiedEvent(obj)
+
+        >>> event.object is obj
+        True
+    
+        >>> IDirectlyProvidesModifiedEvent.providedBy(event)
+        True
+
+    """
+
+    implements(IDirectlyProvidesModifiedEvent)
+
+    def __init__(self, object):
+        self.object = object


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/event.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/handler.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/handler.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/handler.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.component import subscribers
+from zope.app.event.objectevent import Attributes
+from zope.app.event.objectevent import ObjectModifiedEvent
+
+from zope.generic.directlyprovides import IProvides
+from zope.generic.directlyprovides import IObjectModifiedEventDispatchingProvides
+
+
+
+def notifyObjectModifiedEvent(event):
+    
+    if IObjectModifiedEventDispatchingProvides.providedBy(event.object):
+        event = ObjectModifiedEvent(event.object, Attributes(IProvides, '__provides__'))
+
+        for ignored in subscribers((event,), None):
+            pass


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/handler.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/helper.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/helper.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,93 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.interface import directlyProvidedBy
+from zope.interface import directlyProvides
+
+
+
+def assertListOfInterfaces(value):
+    """Assert a list of interfaces.
+
+    This helper function asserts that a list of interfaces is returned:
+
+        >>> from zope.interface import Interface
+
+        >>> class IA(Interface):
+        ...     pass
+
+        >>> class IB(Interface):
+        ...     pass
+
+        >>> class IC(Interface):
+        ...     pass
+
+    An interface is returned as a list of this single interface:
+
+        >>> result = assertListOfInterfaces(IA)
+        >>> [iface.__name__ for iface in result]
+        ['IA']
+
+    A tuple of interface/interfaces is returned as list of interface/
+    interfaces:
+
+        >>> result = assertListOfInterfaces((IA, IB, IC))
+        >>> [iface.__name__ for iface in result]
+        ['IA', 'IB', 'IC']
+
+    A list of interface/interfaces is returned as new list of interface/
+    interfaces:
+
+        >>> input = [IA, IB, IC]
+        >>> result = assertListOfInterfaces(input)
+
+        >>> input is result, input == result
+        (False, True)
+
+        >>> [iface.__name__ for iface in result]
+        ['IA', 'IB', 'IC']
+
+    None is returned as an empty list:
+
+        >>> assertListOfInterfaces(None)
+        []
+
+    """
+
+    if isinstance(value, (tuple, list)):
+        # list/tuple of interfaces
+        return list(value)
+    elif value is None:
+        # None
+        return []
+    else:
+        # interface
+        return [value]
+
+
+
+def updateDirectlyProvided(self, value, previous_value=None):
+    """Update directly provides after a value is set."""
+
+    directlyProvided = list(directlyProvidedBy(self))
+    for iface in assertListOfInterfaces(previous_value):
+        if iface in directlyProvided:
+            directlyProvided.remove(iface)
+
+    directlyProvided = assertListOfInterfaces(value) + directlyProvided
+    directlyProvides(self, *directlyProvided)


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/helper.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/interfaces.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/interfaces.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Attribute
+from zope.interface import Interface
+
+from zope.app.event.interfaces import IObjectEvent
+
+from zope.app.i18n import ZopeMessageFactory as _
+
+
+
+class IProvides(Interface):
+    """Prependes important interfaces within the directly provides mechanism."""
+
+    __provides__ = Attribute(_('Provides'),
+        _('Return directly provided interfaces respecting a partial order of ' +
+          'important interfaces that should be prepended any time.')
+        )
+
+
+
+class IDirectlyProvidesModifiedEvent(IObjectEvent):
+    """Reference an object where the directly provided interfaces were modified."""
+
+
+
+class IObjectModifiedEventDispatchingProvides(IProvides):
+    """Marked objects will be notify an additional ObjectModifiedEvent.
+
+    This interface is used for subscriber-based event dispatching.
+    """


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/property.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/property.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/property.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,251 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+import sys
+from zope.event import notify
+from zope.interface import directlyProvidedBy
+from zope.interface import directlyProvides
+from zope.interface import implementedBy
+from zope.interface.declarations import Declaration
+
+from zope.generic.directlyprovides.event import DirectlyProvidesModifiedEvent
+from zope.generic.directlyprovides.helper import assertListOfInterfaces
+from zope.generic.directlyprovides.helper import updateDirectlyProvided
+
+_marker = object()
+
+
+def hack_checker(value, length, inst):
+    from zope.interface.declarations import Declaration
+    flattened = [i for i in value.flattened()]
+
+    # precondition for the hack checker
+    for iface in implementedBy(inst.__class__):
+        if iface in flattened:
+            return True
+
+    iterated = [i for i in value]
+    if not flattened[0:length] == iterated[0:length]:
+        declaration = Declaration(*iterated)
+        if [i for i in declaration.flattened()][0:length] == flattened[0:length]:
+            return True
+        else:
+            return False
+    return True
+
+
+class ProvidesProperty(object):
+    """Prepend the values of the declared names to the directly provided interfaces."""
+
+    def __init__(self, *names):
+        self.__names = names
+
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+
+        value = inst.__dict__.get('__provides__', _marker)
+        if value is _marker:
+            raise AttributeError('__provides__')
+
+        return value
+
+    def __set__(self, inst, value):
+        # remove a provides declaration
+        if value is None:
+            if '__provides__' in inst.__dict__:
+                del inst.__dict__['__provides__']
+
+        # evaluate interfaces that should be prepended
+        prepended = self._evaluatePrepended(inst)
+
+        if value:
+            ifaces = list(value)
+        else:
+            ifaces = []
+
+        is_ok = (len(ifaces) >= len(prepended) and ifaces[0:len(prepended)] == prepended)
+
+        # XXX: An exception that I do not understand???
+        # Problem if a interface is directly provided by the regular mechanism
+        # and afterward is set by our mechanism
+        if is_ok and not hack_checker(value, len(prepended), inst):
+            directlyProvides(inst)
+            directlyProvides(inst, *ifaces)
+
+        # everything prepended correctly   
+        elif is_ok:
+            if list(Declaration(value.__bases__[:-1])) != list(directlyProvidedBy(inst)):
+                value.changed()
+                inst.__dict__['__provides__'] = value
+                
+                notify(DirectlyProvidesModifiedEvent(inst))
+
+        # order the interfaces first
+        elif len(ifaces) > 0:
+            # remove duplicates
+            for iface in prepended:
+                while iface in ifaces:
+                    ifaces.remove(iface)
+            
+            for iface in implementedBy(inst.__class__):
+                while iface in ifaces:
+                    ifaces.remove(iface)
+
+            # put pretended and other interfaces together and asign it again
+            ordered = prepended + ifaces
+            directlyProvides(inst, *ordered)
+
+        # no other directly provided interface
+        else:
+            directlyProvides(inst, *prepended)
+
+    def _evaluatePrepended(self, inst):
+        prependes = []
+        for name in self.__names:
+            for iface in assertListOfInterfaces(getattr(inst, name)):
+                if iface not in prependes:
+                    prependes.append(iface)
+
+        return prependes
+
+
+
+def provides(*names):
+    """Declare the attributes which should be asserted by the directly provided mechnism.
+
+    This is used within a class suite defining an attribute __provides__:
+
+        >>> from zope.interface import Interface
+        >>> class IFoo(Interface):
+        ...     pass
+
+        >>> class Bar(object):
+        ...     provides('foo')
+        ...     foo = IFoo
+
+        >>> Bar.__provides__._ProvidesProperty__names
+        ('foo',)
+
+    It is invalid to call contains outside a class suite:
+
+        >>> provides('foo')
+        Traceback (most recent call last):
+        ...
+        TypeError: provides not called from suite
+
+    Each time when attribute __provides__ is set an directly provides event
+    is notified:
+
+        >>> from zope.app.testing import placelesssetup
+        >>> placelesssetup.setUp()
+    
+        >>> from zope.app.event.tests.placelesssetup import events
+        >>> from zope.interface import directlyProvidedBy
+
+        >>> class IA(Interface):
+        ...     pass
+
+        >>> len(events)
+        0
+
+        >>> bar = Bar()
+        >>> directlyProvides(bar, IA)
+        
+        >>> len(events)
+        1
+        >>> events.pop() # doctest: +ELLIPSIS
+        <zope.generic.directlyprovides.event.DirectlyProvidesModifiedEvent...>
+
+        >>> placelesssetup.tearDown()
+    """
+
+    frame = sys._getframe(1)
+    f_locals = frame.f_locals
+    f_globals = frame.f_globals
+
+    if not (f_locals is not f_globals
+            and f_locals.get('__module__')):
+        raise TypeError('provides not called from suite')
+
+    f_locals['__provides__'] = ProvidesProperty(*names)
+
+
+
+class UpdateProvides(object):
+    """Update the provides attribute after a new value is set.
+    
+    Note that UpdateProvides cannot be used with slots. They can only
+    be used for attributes stored in instance dictionaries.
+    """
+
+    def __init__(self, field, before=None, after=None, value_hook=None, ):
+        self.__field = field
+        self.__name = field.__name__
+        self.__before = before
+        self.__after = after
+        self.__value_hook = value_hook
+
+    def __get__(self, inst, klass):
+        if inst is None:
+            return self
+
+        value = inst.__dict__.get(self.__name, _marker)
+        if value is _marker:
+            field = self.__field.bind(inst)
+            value = getattr(field, 'default', _marker)
+            if value is _marker:
+                value = getattr(field, 'missing_value', _marker)
+
+                if value is _marker:
+                    raise AttributeError(self.__name)
+
+        return value
+
+    def __set__(self, inst, value):
+
+        previous_value = getattr(inst, self.__name)
+
+        # hook to rearrange values -> ordered features
+        if self.__value_hook:
+            value = self.__value_hook(inst, value, previous_value)
+
+        if value != previous_value:
+            # validate the value
+            field = self.__field.bind(inst)
+            field.validate(value)
+
+            # invoke before
+            if self.__before:
+                self.__before(inst, value, previous_value)
+
+            # store value within __dict__
+            if value is not getattr(field, 'missing_value', _marker):
+                inst.__dict__[self.__name] = value
+            else:
+                if self.__name in inst.__dict__:
+                    del inst.__dict__[self.__name]
+
+            # update directly provides
+            updateDirectlyProvided(inst, value, previous_value)
+
+            # invoke after
+            if self.__after:
+                self.__after(inst, value, previous_value)
+
+    def __getattr__(self, name):
+        return getattr(self.__field, name)


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/property.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/testing.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/testing.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.testing import ztapi
+import zope.generic.testing.testing
+
+
+################################################################################
+#
+# Public Test implementations
+#
+################################################################################
+
+
+
+################################################################################
+#
+# Placeless setup
+#
+################################################################################
+
+
+
+class PlacelessSetup(zope.generic.testing.testing.PlacelessSetup):
+
+    def setUp(self, doctesttest=None):
+        super(PlacelessSetup, self).setUp(doctesttest)
+
+        # handlers
+        from zope.generic.directlyprovides.handler import notifyObjectModifiedEvent
+        from zope.generic.directlyprovides import IDirectlyProvidesModifiedEvent
+        ztapi.subscribe([IDirectlyProvidesModifiedEvent], 
+            None, notifyObjectModifiedEvent)
+        
+    def tearDown(self, doctesttest=None):
+        super(PlacelessSetup, self).tearDown()
+
+
+
+placelesssetup = PlacelessSetup()


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/tests.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/tests.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""Package zope.generic.directlyprovides.
+
+$Id$
+"""
+
+import unittest
+
+from zope import component
+from zope import interface
+from zope import schema
+from zope.testing import doctest
+
+from zope.generic.directlyprovides.testing import placelesssetup, ztapi 
+from zope.generic.testing.testing import registerDirective
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite('zope.generic.directlyprovides.helper'),
+        doctest.DocTestSuite('zope.generic.directlyprovides.property'),
+        doctest.DocTestSuite('zope.generic.directlyprovides.event'),
+        doctest.DocFileSuite('README.txt',
+                             setUp=placelesssetup.setUp,
+                             tearDown=placelesssetup.tearDown,
+                             globs={'component': component, 'interface': interface,
+                                'schema': schema, 'ztapi': ztapi,
+                                'registerDirective': registerDirective},
+                             optionflags=doctest.NORMALIZE_WHITESPACE+
+                                            doctest.ELLIPSIS),
+        ))
+
+if __name__ == '__main__': unittest.main()


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/directlyprovides/zope.generic.directlyprovides-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/directlyprovides/zope.generic.directlyprovides-configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/directlyprovides/zope.generic.directlyprovides-configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.directlyprovides" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/directlyprovides/zope.generic.directlyprovides-configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/doc/CHANGES.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/CHANGES.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/CHANGES.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,4 @@
+=======
+CHANGES
+=======
+


Property changes on: zope.generic/trunk/src/zope/generic/doc/CHANGES.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/doc/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/README.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/README.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,20 @@
+============
+zope.generic
+============
+
+Software models problem domains. Often we model domain components as object
+of corresponding implementations (classes). Those classes combine generic 
+behavior and domain-specific behavior. This packages should help to model problem
+domains using generic implementations that do not provide any domain-specific 
+behavior directly but mark instances of those generic implementations 
+domain-specifically relying heavily on the directly provide mechanism of the
+zope.interface package.
+
+-   .directlyprovides: Better control of the directly provides mechanism
+
+-   .configuration: n/a
+
+-   .information: Interface-based registrations and registries
+
+-   .type: Type generic base classes by marker interfaces.
+


Property changes on: zope.generic/trunk/src/zope/generic/doc/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/doc/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/SETUP.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/SETUP.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.doc-*.zcml
+</data-files>


Property changes on: zope.generic/trunk/src/zope/generic/doc/SETUP.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/doc/TODO.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/TODO.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/TODO.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,7 @@
+====
+TODO
+====
+
+Things to do for the next release (sorted by importance):
+
+


Property changes on: zope.generic/trunk/src/zope/generic/doc/TODO.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/doc/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/__init__.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/__init__.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,17 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""


Property changes on: zope.generic/trunk/src/zope/generic/doc/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/doc/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,35 @@
+<configure 
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:apidoc="http://namespaces.zope.org/apidoc"
+  xmlns:zcml="http://namespaces.zope.org/zcml"
+  i18n_domain="zope">
+
+  <apidoc:bookchapter zcml:condition="have apidoc"
+      id="zope.generic"
+      title="Zope Generic"
+      />
+
+  <!-- Register documentation with API Doc -->
+
+  <apidoc:bookchapter zcml:condition="have apidoc"
+      id="zope.generic.readme"
+      title="README"
+      doc_path="README.txt"
+      parent="zope.generic"
+      />
+
+  <apidoc:bookchapter zcml:condition="have apidoc"
+      id="zope.generic.changes"
+      title="CHANGES"
+      doc_path="CHANGES.txt"
+      parent="zope.generic"
+      />
+
+  <apidoc:bookchapter zcml:condition="have apidoc"
+      id="zope.generic.todo"
+      title="TODO"
+      doc_path="TODO.txt"
+      parent="zope.generic"
+      />
+
+</configure>
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/doc/configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/doc/zope.generic.doc-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/doc/zope.generic.doc-configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/doc/zope.generic.doc-configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.doc" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/doc/zope.generic.doc-configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/information/DEPENDENCIES.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/DEPENDENCIES.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,9 @@
+zope.generic.configuration
+zope.generic.testing
+zope.app.annotation
+zope.app.component
+zope.component
+zope.configuration
+zope.interface
+zope.schema
+zope.testing


Property changes on: zope.generic/trunk/src/zope/generic/information/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/information/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/information/PUBLICATION.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/PUBLICATION.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,11 @@
+Metadata-Version: 1.0
+Name: zope.generic.information
+Summary: Information about interface based registrations
+Author: Dominik Huber, Perse Engineering GmbH, Switzerland
+Author-email: dominik.huber at perse.ch
+License: ZPL 2.1
+Description:
+        Provide facility for reusable information registry. The information
+        registries are implemented as utility providing IInformationRegistry.
+        The name of the registry is given by the dotted name of the interface
+        of the deciated information collected by the information registry.


Property changes on: zope.generic/trunk/src/zope/generic/information/PUBLICATION.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/information/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/information/README.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/README.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,182 @@
+===========
+Information
+===========
+
+The generic package relies heavily on interfaces. Often we have relation between
+different interfaces. Informations provides dedicated data about an certain 
+marker interface. Informations are implemented as utility. The package provides
+some convenience functions and directives.
+
+An information offers annotations and configurations.
+
+Example
+-------
+
+You can use the information directive to register an information as utiliy 
+under registry-interface using the dotted name of the interface as utility name:
+
+    >>> from zope.generic.information import api
+
+    >>> class ISpecialInformation(api.IInformation):
+    ...    pass
+
+    >>> from zope.interface import Interface
+    >>> class IFooMarker(Interface):
+    ...    pass
+
+    # make available within the testing module
+    >>> testing.ISpecialInformation, testing.IFooMarker = ISpecialInformation, IFooMarker
+    >>> IFooMarker.__module__ = ISpecialInformation.__module = 'zope.generic.information.testing'
+
+    >>> registerDirective('''
+    ... <generic:information
+    ...     interface="zope.generic.information.testing.IFooMarker"
+    ...     registry="zope.generic.information.testing.ISpecialInformation"
+    ...     label='Foo Specials' hint='Bla bla foo.'
+    ...     />
+    ... ''')
+
+Afterward the information can be queried using the following method:
+
+    >>> info = api.queryInformation(IFooMarker, ISpecialInformation)
+
+    >>> info.interface == IFooMarker
+    True
+    >>> ISpecialInformation.providedBy(info)
+    True
+    >>> info.label = u'Foo Specials'
+    >>> info.hint = u'Bla bla foo.'
+
+	>>> listing = list(api.registeredInformations(ISpecialInformation))
+	>>> len(listing) is 1
+	True
+	>>> listing[0][1] == info
+	True
+	>>> listing[0][0] == IFooMarker
+	True
+
+If no information is available for a certain interface the defined default
+value is returned:
+
+    >>> class IBarMarker(Interface):
+    ...    pass
+
+    >>> default = object()
+    >>> info = api.queryInformation(IBarMarker, ISpecialInformation, default)
+    >>> info is default
+    True
+
+    >>> info = api.queryInformation(IBarMarker, ISpecialInformation)
+    >>> info is None
+    True
+
+Annotatable Informations
+------------------------
+
+Informations are annotable. The annotations mechanism is used to provide
+additional information in a generic manner by adaption:
+
+    >>> from zope.app.annotation.interfaces import IAnnotations
+
+    >>> info = api.queryInformation(IFooMarker, ISpecialInformation)
+
+    >>> annotations = IAnnotations(info)
+    >>> annotations.get('test.annotation')
+    >>> annotations['test.annotation']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'test.annotation'
+    >>> list(annotations.keys())
+    []
+    >>> del annotations['test.annotation']
+    Traceback (most recent call last):
+    ...
+    KeyError: 'test.annotation'
+    >>> annotations['test.annotation'] = 'a'
+    >>> annotations.get('test.annotation')
+    'a'
+    >>> annotations['test.annotation']
+    'a'
+    >>> list(annotations.keys())
+    ['test.annotation']
+    >>> del annotations['test.annotation']
+
+
+Congigurable Informations
+-------------------------
+
+Informations are configurable. The configurations mechanism is used to provide 
+additional configurations information in a generic manner. A configuration
+is declared by a configuration schema. This is a regular schema that will be
+typed a IConfigurationType after its registration (see zope.generic.configuration):
+
+	>>> from zope.schema import TextLine
+		
+    >>> class IMyConfiguration(interface.Interface):
+    ...     my = TextLine(title=u'My')
+
+    # make available within the testing module
+    >>> testing.IMyConfiguration = IMyConfiguration
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="zope.generic.information.testing.IMyConfiguration"
+    ...     label='My' hint='My bla.'
+    ...     />
+    ... ''') 
+
+	>>> from zope.generic.configuration import IConfigurationType
+	>>> IConfigurationType.providedBy(IMyConfiguration)
+	True
+
+For the further exploration we query this information:
+
+    >>> from zope.generic.configuration.api import queryConfigurationInformation
+    >>> from zope.generic.configuration.api import IConfigurationInformation
+
+	>>> my_configuration_information = queryConfigurationInformation(IMyConfiguration)
+	>>> my_configuration_information.interface == IMyConfiguration
+	True
+	>>> IConfigurationInformation.providedBy(my_configuration_information)
+	True
+
+We now use this configuration to extend our information about our IFooMarker. 
+Before that there will be no configuration:
+
+	>>> from zope.generic.configuration.api import IConfigurations
+
+	>>> info_configurations = IConfigurations(info)
+	>>> IMyConfiguration(info_configurations, None) is None
+	True
+	
+	or simply:
+	>>> from zope.generic.configuration.api import queryConfigurationData
+
+	>>> queryConfigurationData(info, IMyConfiguration)is None
+	True
+
+The configuration subdirective of the information directive provides a mechanism
+to register further configurations to an information:
+
+	>>> from zope.generic.configuration.api import ConfigurationData
+	>>> my_information_config = ConfigurationData(IMyConfiguration, {'my': u'My!'})
+
+    # make available within the testing module
+    >>> testing.my_information_config = my_information_config
+
+    >>> registerDirective('''
+    ... <generic:information
+    ...     interface="zope.generic.information.testing.IFooMarker"
+    ...     registry="zope.generic.information.testing.ISpecialInformation"
+    ...     label='Foo Specials' hint='Bla bla foo.'
+    ...     >
+    ...		<configuration
+    ...		    interface="zope.generic.information.testing.IMyConfiguration"
+    ...			data="zope.generic.information.testing.my_information_config"
+    ...			/>
+    ...	 </generic:information>
+    ... ''')
+
+    >>> info = api.queryInformation(IFooMarker, ISpecialInformation)
+	>>> queryConfigurationData(info, IMyConfiguration) is my_information_config
+	True


Property changes on: zope.generic/trunk/src/zope/generic/information/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/information/SETUP.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/SETUP.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.information-*.zcml
+</data-files>
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/information/SETUP.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/information/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/__init__.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/__init__.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.generic.information.interfaces import *
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/information/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/api.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/api.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,26 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+# usage see README.txt
+from zope.generic.information.interfaces import *
+
+from zope.generic.information.base import Information
+from zope.generic.information.helper import dottedName
+from zope.generic.information.helper import queryInformation
+from zope.generic.information.helper import registeredInformations
+from zope.generic.information.metaconfigure import provideInformation


Property changes on: zope.generic/trunk/src/zope/generic/information/api.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/base.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/base.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,101 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.annotation.interfaces import IAttributeAnnotatable
+from zope.interface import alsoProvides
+from zope.interface import implements
+
+from zope.generic.configuration import IAttributeConfigurable
+from zope.app.i18n import ZopeMessageFactory as _
+
+from zope.generic.information import IInformation
+from zope.generic.information import IInformationDescription
+from zope.generic.information.helper import dottedName
+
+
+
+class InformationDescription(object):
+    """Information description."""
+
+    implements(IInformationDescription)
+
+    def __init__(self, interface, label=None, hint=None):
+        self.interface = interface
+
+        if label is None:
+            self.label = _(dottedName(interface))
+        else:
+            self.label = label
+
+        if hint is None:
+            self.hint = _('No hint available.')
+        else:
+            self.hint = hint
+
+
+
+class Information(InformationDescription, dict):
+    """Default information.
+
+    Information do relate a dedicated type of information marked as an interface
+    extending IInformation and another marker interface:
+
+        >>> class ISpecialInformation(IInformation):
+        ...    pass
+
+        >>> from zope.interface import Interface
+        >>> class IFooMarker(Interface):
+        ...    pass
+
+        >>> info = Information(IFooMarker, ISpecialInformation)
+
+    The information will provide the interface of the dedicated information:
+
+        >>> ISpecialInformation.providedBy(info)
+        True
+
+    The information is related to the interface declared by the interface
+    attribute:
+
+        >>> info.interface == IFooMarker
+        True
+        >>> info.label
+        u'zope.generic.information.base.IFooMarker'
+        
+        >>> info.hint
+        u'No hint available.'
+
+
+    Often you will provide a specific label and hint for the end-user:
+
+        >>> info = Information(IFooMarker, ISpecialInformation, u'Foo', u'Bla bla.')
+        >>> info.label
+        u'Foo'
+        
+        >>> info.hint
+        u'Bla bla.'
+    """
+
+    implements(IInformation, IAttributeConfigurable, IAttributeAnnotatable)
+
+    def __init__(self, interface, provides, label=None, hint=None):
+        super(Information, self).__init__(interface, label, hint)
+        alsoProvides(self, provides)
+


Property changes on: zope.generic/trunk/src/zope/generic/information/base.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/information/configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,12 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:generic="http://namespaces.zope.org/generic"
+  i18n_domain="zope">
+
+  <generic:information
+      interface=".IInformationRegistryInformation"
+      label="Information Registry Information"
+      registry=".IInformationRegistryInformation"
+      />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/information/configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/helper.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/helper.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.component import getUtility
+from zope.component import getUtilitiesFor
+
+from zope.generic.configuration.api import resolveClass
+
+
+
+def dottedName(klass):
+    if klass is None:
+        return 'None'
+    return klass.__module__ + '.' + klass.__name__
+
+
+
+def getInformation(interface, registry):
+    return getUtility(registry, dottedName(interface))
+
+
+
+def queryInformation(interface, registry, default=None):
+    try:
+        return getInformation(interface, registry)
+
+    except:
+        return default
+
+
+def registeredInformations(registry, default=None):
+    for name, information in getUtilitiesFor(registry):
+        yield (resolveClass(name), information)


Property changes on: zope.generic/trunk/src/zope/generic/information/helper.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/interfaces.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/interfaces.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,73 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import Interface
+from zope.interface.interfaces import IInterface
+from zope.schema import Object
+from zope.schema import Text
+from zope.schema import TextLine
+
+from zope.app.i18n import ZopeMessageFactory as _
+
+
+
+__all__ = ['IInformationDeclaration', 'IInformationDescription', 'IInformation',
+           'IInformationRegistryInformation']
+
+
+
+class IInformationDeclaration(Interface):
+    """Declare an interface as information-specific-key."""
+
+    interface = Object(
+        title=_('Interface'),
+        description=_('Interface marker that references corresponding informations.'),
+        required=True,
+        schema=IInterface)
+
+
+
+class IInformationDescription(IInformationDeclaration):
+    """Describe the associated information declaration."""
+
+    label = TextLine(title=_('Label'),
+        description=_('Label for the registered interface marker.'),
+        required=True
+        )  
+
+    hint = Text(title=_('Hint'),
+        description=_('Hint explaning the properties of the registered interface marker.'),
+        required=True
+        )
+
+
+
+class IInformation(IInformationDescription):
+    """Inform about an subject referenced by an interface-key.
+
+    Additional information can be stored within the information's annotations
+    or configurations.
+    
+    Implementation should be adaptable to IConfigurations and IAnnotations."""
+
+
+
+class IInformationRegistryInformation(IInformation):
+    """Provide information about registered information registries."""


Property changes on: zope.generic/trunk/src/zope/generic/information/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/information/meta.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/meta.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,22 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/generic">
+
+    <meta:complexDirective
+        name="information"
+        schema=".metadirectives.IInformationDirective"
+        handler=".metaconfigure.InformationDirective"
+        >
+
+      <meta:subdirective
+          name="configuration"
+          schema=".metadirectives.IConfigurationSubdirective"
+          />
+
+    </meta:complexDirective>
+
+  </meta:directives>
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/information/meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/metaconfigure.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/metaconfigure.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,133 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Projekt01 GmbH and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.app.component.interface import provideInterface
+from zope.component import provideUtility
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface import alsoProvides
+
+from zope.generic.configuration.api import IConfigurations
+
+from zope.generic.information import IInformation
+from zope.generic.information.base import Information
+from zope.generic.information.helper import dottedName
+from zope.generic.information.helper import queryInformation
+
+
+
+def provideInformation(interface, registry, label=None, hint=None, factory=None):
+    """Provide new information for the given registry-interface.
+
+    Register an information as utiliy under registry-interface using
+    the dotted name of the interface as utility name:
+
+        >>> class ISpecialInformation(IInformation):
+        ...    pass
+
+        >>> from zope.interface import Interface
+        >>> class IFooMarker(Interface):
+        ...    pass
+
+        >>> provideInformation(IFooMarker, ISpecialInformation)
+
+    The information can be queried using the following method:
+
+        >>> from zope.generic.information.helper import queryInformation
+        >>> info = queryInformation(IFooMarker, ISpecialInformation)
+        >>> info.interface == IFooMarker
+        True
+        >>> ISpecialInformation.providedBy(info)
+        True
+
+    """
+
+    # precondition
+    if not registry.extends(IInformation):
+        raise ValueError('Registry must extend %s.' % IInformation.__name__)
+
+    if factory is None:
+        factory = Information
+    
+    component = factory(interface, registry, label, hint)
+
+    if not registry.providedBy(component):
+        raise ValueError('Factory must implement %s.' % registry.__name__)
+    
+    provideUtility(component, provides=registry, name=dottedName(interface))
+
+
+
+def provideConfiguration(interface, registry, configuration, data):
+    """Provide configuration for a certain type marker."""
+
+    info = queryInformation(interface, registry)
+    
+    configurations = IConfigurations(info)
+    configurations[configuration] = data
+
+
+
+class InformationDirective(object):
+    """Provide a new information of a certain information registry."""
+    
+    _interface_type = None
+
+    def __init__(self, _context, interface, registry, label=None, hint=None):
+        self._interface = interface
+        self._context = _context
+        self._registry = registry
+    
+        # assert type as soon as possible
+        if self._interface_type is not None:
+            alsoProvides(interface, self._interface_type)
+    
+        _context.action(
+            discriminator = ('provideInformation', self._interface, self._registry),
+            callable = provideInformation,
+            args = (self._interface, self._registry, label, hint),
+            )
+    
+        _context.action(
+            discriminator = None,
+            callable = provideInterface,
+            args = (None, self._interface),
+            )
+    
+        _context.action(
+            discriminator = None,
+            callable = provideInterface,
+            args = (None, self._registry),
+            )
+
+    def __call__(self):
+        "Handle empty/simple declaration."
+        return ()
+
+    def configuration(self, _context, interface, data):
+        # preconditions
+        if not interface.providedBy(data):
+            raise ConfigurationError('Data attribute must provide %s.' % interface.__name__)
+
+        _context.action(
+            discriminator = (
+            'InformationConfiguration', self._interface, self._registry, interface),
+            callable = provideConfiguration,
+            args = (self._interface, self._registry, interface, data),
+            )


Property changes on: zope.generic/trunk/src/zope/generic/information/metaconfigure.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/metadirectives.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/metadirectives.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.configuration.fields import GlobalInterface
+from zope.configuration.fields import GlobalObject
+from zope.configuration.fields import MessageID
+from zope.interface import Interface
+
+from zope.app.i18n import ZopeMessageFactory as _
+
+from zope.generic.information import IInformation
+
+
+
+class IBaseInformationDirective(Interface):
+    """Base information attributes."""
+
+    interface = GlobalInterface(
+        title=_('Interface'),
+        description=_('Interface that represents an information.'),
+        required=True
+        )
+
+    label = MessageID(
+        title=_('Label'),
+        description=_('Label of the information.'),
+        required=False
+        )
+
+    hint = MessageID(
+        title=_('Hint'),
+        description=_('Hint of the informtion.'),
+        required=False
+        )
+
+
+
+class IInformationDirective(IBaseInformationDirective):
+    """Directive for informations and information registries."""
+
+    registry = GlobalInterface(
+        title=_('Information Registry Key'),
+        description=_('A registry key is a dedicated interface which should extend' +
+                      'IInformation.'),
+        required=True,
+        constraint=lambda v: v.extends(IInformation)
+        )
+
+
+
+class IConfigurationSubdirective(Interface):
+    """Declare a certain configuration of a type."""
+
+    interface = GlobalInterface(
+        title=_('Interface'),
+        description=_('Interface referencing a configuraiton.'),
+        required=True
+        )
+
+    data = GlobalObject(
+        title=_('Data'),
+        description=_('Configuration data component providing the configuraiton interface.'),
+        required=True
+        )
+


Property changes on: zope.generic/trunk/src/zope/generic/information/metadirectives.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/testing.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/testing.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.configuration.xmlconfig import XMLConfig
+
+import zope.generic.testing.testing
+
+
+
+################################################################################
+#
+# Public Test implementations
+#
+################################################################################
+
+
+
+################################################################################
+#
+# Placeless setup
+#
+################################################################################
+
+
+class PlacelessSetup(zope.generic.testing.testing.PlacelessSetup):
+
+    def setUp(self, doctesttest=None):
+        super(PlacelessSetup, self).setUp(doctesttest)
+
+        # register the directive of this package
+        import zope.generic.information
+        XMLConfig('meta.zcml', zope.generic.information)()
+        
+
+    def tearDown(self, doctesttest=None):
+        super(PlacelessSetup, self).tearDown(doctesttest)
+
+
+
+placelesssetup = PlacelessSetup()


Property changes on: zope.generic/trunk/src/zope/generic/information/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/information/tests.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/tests.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+import unittest
+
+from zope import component
+from zope import interface
+from zope.testing import doctest
+
+from zope.generic.configuration.testing import placelesssetup
+from zope.generic.testing.testing import registerDirective
+
+from zope.generic.information import testing
+
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite('zope.generic.information.base'),
+        doctest.DocTestSuite('zope.generic.information.metaconfigure'),
+        doctest.DocFileSuite('README.txt',
+                             setUp=placelesssetup.setUp,
+                             tearDown=placelesssetup.tearDown,
+                             globs={'component': component, 'interface': interface,
+                             'registerDirective': registerDirective,
+                             'testing': testing},
+                             optionflags=doctest.NORMALIZE_WHITESPACE+
+                                            doctest.ELLIPSIS),
+        ))
+
+if __name__ == '__main__': unittest.main()


Property changes on: zope.generic/trunk/src/zope/generic/information/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/zope.generic.information-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/information/zope.generic.information-configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/zope.generic.information-configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.information" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/information/zope.generic.information-configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/information/zope.generic.information-meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/information/zope.generic.information-meta.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/information/zope.generic.information-meta.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.information" file="meta.zcml" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/information/zope.generic.information-meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/testing/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/DEPENDENCIES.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/DEPENDENCIES.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,7 @@
+zope.app.annotation
+zope.app.component
+zope.app.security
+zope.app.testing
+zope.component
+zope.configuration
+zope.interface


Property changes on: zope.generic/trunk/src/zope/generic/testing/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/testing/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/PUBLICATION.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/PUBLICATION.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,8 @@
+Metadata-Version: 1.0
+Name: zope.generic.testing
+Summary: Basic Testing Facility for zope.generic
+Author: Dominik Huber, Perse Engineering GmbH, Switzerland
+Author-email: dominik.huber at perse.ch
+License: ZPL 2.1
+Description:
+        Basic Testing Facility for zope.generic


Property changes on: zope.generic/trunk/src/zope/generic/testing/PUBLICATION.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/testing/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/README.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/README.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+=======
+Testing
+=======
+
+Provide basic testing facility for the zope.generic namespace.
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/testing/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/testing/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/SETUP.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/SETUP.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.testing-*.zcml
+</data-files>
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/testing/SETUP.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/testing/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/__init__.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/__init__.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,17 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""


Property changes on: zope.generic/trunk/src/zope/generic/testing/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/testing/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,6 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:generic="http://namespaces.zope.org/generic"
+  i18n_domain="zope">
+ 
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/testing/configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/testing/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/testing.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/testing.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+
+from cStringIO import StringIO
+from zope.configuration.xmlconfig import XMLConfig
+from zope.configuration.xmlconfig import xmlconfig
+from zope.interface.verify import verifyClass
+from zope.interface.verify import verifyObject
+import unittest
+
+from zope.component import provideAdapter
+import zope.app.testing.placelesssetup
+
+
+################################################################################
+#
+# Base Test implementations
+#
+################################################################################
+
+
+
+_marker_pos = object()
+_marker_kws = object()
+
+class InterfaceBaseTest(unittest.TestCase):
+    """Base class for interface based unit tests."""
+
+    _test_interface = None
+    _test_class = None
+    _test_pos = None
+    _test_kws = None
+    _verify_class = True
+    _verify_object = True
+
+    def makeTestObject(self, *pos, **kws):
+        # assert defaults for positional or keyword arguments
+        if not pos and self._test_pos is not None:
+            pos = self._test_pos
+
+        if not kws and self._test_kws is not None:
+            kws = self._test_kws
+       
+        return self._test_class(*pos, **kws)
+
+    def test_verify_class(self):
+        if self._verify_class:
+            self.assert_(verifyClass(self._test_interface, self._verify_class)) 
+
+    def test_verify_object(self):
+        if self._verify_object:
+            self.assert_(verifyObject(self._test_interface, self.makeTestObject()))
+
+
+
+################################################################################
+#
+# Placeless setup
+#
+################################################################################
+    
+# helper for directive testing
+template = """<configure
+   xmlns='http://namespaces.zope.org/zope'
+   xmlns:generic='http://namespaces.zope.org/generic'
+   xmlns:test='http://www.zope.org/NS/Zope3/test'
+   i18n_domain='zope'>
+   %s
+   </configure>"""
+
+
+def registerDirective(direcitive):
+        xmlconfig(StringIO(template % direcitive))
+
+
+
+class PlacelessSetup(zope.app.testing.placelesssetup.PlacelessSetup):
+
+    def setUp(self, doctesttest=None):
+        super(PlacelessSetup, self).setUp(doctesttest)
+
+        # zope.app.annotations
+        from zope.app.annotation.interfaces import IAnnotations
+        from zope.app.annotation.interfaces import IAttributeAnnotatable
+        from zope.app.annotation.attribute import AttributeAnnotations
+
+        provideAdapter(AttributeAnnotations, adapts=[IAttributeAnnotatable], 
+                       provides=IAnnotations)
+
+        # zcml configurations
+        import zope.app.component
+        XMLConfig('meta.zcml', zope.app.component)()
+        import zope.app.security
+        XMLConfig('meta.zcml', zope.app.security)()
+
+    def tearDown(self, doctesttest=None):
+        super(PlacelessSetup, self).tearDown()
+
+
+
+placelesssetup = PlacelessSetup()


Property changes on: zope.generic/trunk/src/zope/generic/testing/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/testing/zope.generic.testing-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/testing/zope.generic.testing-configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/testing/zope.generic.testing-configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.testing" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/testing/zope.generic.testing-configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,15 @@
+persistent
+zope.generic.configuration
+zope.generic.directlyprovides
+zope.generic.information
+zope.generic.testing
+zope.app.annotation
+zope.app.component
+zope.app.container
+zope.app.folder
+zope.component
+zope.configuration
+zope.interface
+zope.schema
+zope.security
+zope.testing


Property changes on: zope.generic/trunk/src/zope/generic/type/DEPENDENCIES.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/type/PUBLICATION.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/type/PUBLICATION.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/PUBLICATION.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,9 @@
+Metadata-Version: 1.0
+Name: zope.generic.informed
+Summary: Provide a logical type facility
+Author: Dominik Huber, Perse Engineering GmbH, Switzerland
+Author-email: dominik.huber at perse.ch
+License: ZPL 2.1
+Description:
+      	An object provides often serval interfaces. This package provides a
+      	interace based type assoziation in a way like *classes* or *types* do.


Property changes on: zope.generic/trunk/src/zope/generic/type/PUBLICATION.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/type/README.txt
===================================================================
--- zope.generic/trunk/src/zope/generic/type/README.txt	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/README.txt	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,240 @@
+====
+Type
+====
+
+An object provides often serval interfaces. This package provides a interace 
+based type assoziation in a way like *classes* or *types* do. Typeable object
+provides by adaption or implementation access to a type marker. This type
+marker can be used to lookup further information about the referenced type.
+
+For each interface typed by our type marker type (ITypeType) we provied a type 
+factory that can create instaces of this certain *logical* type.
+
+Furthermore a type information utility will be provided. This type information
+allows to annotate additonal stuff like using the annotations and configurations
+mechanism.
+
+Informations provided by the type information should be accounted by the handling
+of instances marked by a certain type marker interface.
+
+The type directive does extend the information directive
+(see zope.generic.information).
+
+
+Base type directive
+-------------------
+
+In our example we register type using the generic:type directive. Therefore we
+need an type marker:
+
+    >>> class IFooMarker(interface.Interface):
+    ...     pass
+
+    # make available within the testing module
+    >>> testing.IFooMarker = IFooMarker 
+
+The only thing to register a specific logical type is this type marker interface.
+The package offers four different generic implementation such as Object,
+Contained, Container and Folder (Site) that you might use as implementation of
+your logical type. Certainly you can provide your own implementation. Such an
+implementation should implement at least the marker ITypeable and a corresponding
+adapter to ITyped.
+
+In our example we will use a simple generic object:
+
+	>>> from zope.generic.type import api
+	>>> api.ITypeable.implementedBy(api.Object)
+	True
+	>>> api.IDirectlyTyped.implementedBy(api.Object)
+	True
+
+    >>> registerDirective('''
+    ... <generic:type
+    ...     interface="zope.generic.type.testing.IFooMarker"
+    ...     label='Foo Type' hint='Bla bla bla.'
+    ...	    class='zope.generic.type.api.Object'
+    ...     />
+    ... ''')
+
+After the typed is registered the type marker will provide ITypeType:
+
+	>>> from zope.generic.type import api
+
+    >>> api.ITypeType.providedBy(IFooMarker)
+    True
+
+You can create instances of the registered logical type:
+
+	>>> foo = api.createObject(IFooMarker)
+	>>> typed = api.ITyped(foo)
+	>>> typed.interface == IFooMarker
+	True
+
+In our example we use a generic directly typed implementation. In those cases
+the instance will provide the type marker too:
+
+	>>> IFooMarker.providedBy(foo)
+	True
+
+A corresponding type information utility will be available. Your can
+retrieve this utility using the conventional utility api:
+
+    >>> from zope.component import queryUtility
+    >>> from zope.generic.configuration.api import dottedName
+
+    >>> info = queryUtility(api.ITypeInformation, dottedName(IFooMarker))
+
+    >>> info.interface == IFooMarker
+    True
+    >>> info.label
+    u'Foo Type'
+    >>> info.hint
+    u'Bla bla bla.'
+
+There is convenience function for the lookup of corresponding type information.
+You can lookup the type information by the type marker interface or an object
+providing ITyped by implementation or adaption:
+
+	>>> api.queryTypeInformation(IFooMarker) == info
+	True
+
+    >>> api.queryTypeInformation(foo) == info
+    True
+
+
+Type subdirectives
+------------------
+
+There are serveral subdirectives like:
+
+-	configurations (see zope.generic.information)
+-	initializer
+
+You can extend type informations by the annotations and configurations mechanism
+like the information will do.
+
+First we will provide a new bar type including an additional configuration:
+
+    >>> class IBarMarker(interface.Interface):
+    ...     pass
+
+    # make available within the testing module
+    >>> testing.IBarMarker = IBarMarker 
+
+Then we provide two example configurations for our example:
+
+	>>> from zope.schema import TextLine
+
+    >>> class IAnyConfiguration(interface.Interface):
+    ...     any = TextLine(title=u'Any')
+
+    >>> class IOtherConfiguration(interface.Interface):
+    ...		other = TextLine(title=u'Other')
+    ...		optional = TextLine(title=u'Other', required=False, default=u'Default bla.')
+
+    # make available within the testing module
+    >>> testing.IAnyConfiguration = IAnyConfiguration
+    >>> testing.IOtherConfiguration = IOtherConfiguration
+    >>> IAnyConfiguration.__module__ = IOtherConfiguration.__module__ = 'zope.generic.type.testing'
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="zope.generic.type.testing.IAnyConfiguration"
+    ...     label='Any' hint='Any bla.'
+    ...     />
+    ... ''') 
+
+    >>> registerDirective('''
+    ... <generic:configuration
+    ...     interface="zope.generic.type.testing.IOtherConfiguration"
+    ...     />
+    ... ''') 
+
+	>>> from zope.generic.configuration.api import ConfigurationData
+	>>> typedata = ConfigurationData(IAnyConfiguration, {'any': u'Guguseli from Type!'})
+	>>> IAnyConfiguration.providedBy(typedata)
+	True
+
+    # make available within the testing module
+    >>> testing.typedata = typedata
+
+We can provide a specific intializer:
+
+	>>> def barInitializer(context, *pos, **kws):
+	...		print 'Initializing ...'
+
+    # make available within the testing module
+    >>> testing.barInitializer = barInitializer
+
+After all we register our component using the type directive:
+
+    >>> registerDirective('''
+    ... <generic:type
+    ...     interface="zope.generic.type.testing.IBarMarker"
+    ...     label='Bar Type' hint='Bla bla bla.'
+    ...	    class='zope.generic.type.api.Object'
+    ...     >
+    ...    <initializer
+    ...			interface='zope.generic.type.testing.IOtherConfiguration'
+    ...			handler='zope.generic.type.testing.barInitializer'
+    ...	   />
+    ...	   <configuration
+    ...	       interface='zope.generic.type.testing.IAnyConfiguration'
+    ...        data='zope.generic.type.testing.typedata'
+    ...	   />
+    ... </generic:type>
+    ... ''')
+
+Now we can create an instance of the logical type. We defined an initializer
+interface. Doing the **kws parameter are stored as configuration to the object.
+If we do not satify the declaration an KeyError is raised:
+
+	>>> api.createParameter(IBarMarker) == IOtherConfiguration
+	True
+
+	>>> bar = api.createObject(IBarMarker)
+	Traceback (most recent call last):
+	...
+	KeyError: 'Missed keys: other.'
+
+	>>> bar = api.createObject(IBarMarker, **{'other': u'Specific initialization data.'})
+	Initializing ...
+
+This registration attached the specific configuration to the type information.
+You can retrieve type information by a typed instance or the marker type itself
+using the following convenience function:
+
+	>>> api.queryTypeConfiguration(IBarMarker, IAnyConfiguration).any
+	u'Guguseli from Type!'
+
+	>>> api.queryTypeConfiguration(bar, IAnyConfiguration).any
+	u'Guguseli from Type!'
+
+	>>> api.queryTypeConfiguration(IBarMarker, IOtherConfiguration) is None
+	True
+
+This configuration is type specific. You cannot lookup any object- or 
+instance-specific configuration, but you can use a function that `acquires`
+different configurations:
+
+	>>> api.queryObjectConfiguration(bar, IAnyConfiguration) is None
+	True
+
+	>>> api.queryObjectConfiguration(bar, IOtherConfiguration).other
+	u'Specific initialization data.'
+
+	>>> api.acquireObjectConfiguration(bar, IAnyConfiguration).any
+	u'Guguseli from Type!'
+
+	>>> api.acquireObjectConfiguration(bar, IOtherConfiguration).other
+	u'Specific initialization data.'
+
+    >>> from zope.generic.configuration.api import IConfigurations
+	>>> objectdata = ConfigurationData(IAnyConfiguration, {'any': u'Guguseli from Object!'})
+	>>> IConfigurations(bar)[IAnyConfiguration] = objectdata
+	
+	>>> api.queryObjectConfiguration(bar, IAnyConfiguration).any
+	u'Guguseli from Object!'
+
+	>>> api.acquireObjectConfiguration(bar, IAnyConfiguration).any
+	u'Guguseli from Object!'


Property changes on: zope.generic/trunk/src/zope/generic/type/README.txt
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/SETUP.cfg
===================================================================
--- zope.generic/trunk/src/zope/generic/type/SETUP.cfg	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/SETUP.cfg	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+  zope.generic.type-*.zcml
+</data-files>
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/type/SETUP.cfg
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zope.generic/trunk/src/zope/generic/type/__init__.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/__init__.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/__init__.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+from zope.generic.type.interfaces import *
\ No newline at end of file


Property changes on: zope.generic/trunk/src/zope/generic/type/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/adapter.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/adapter.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/adapter.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from BTrees.OOBTree import OOBTree
+import transaction
+from UserDict import DictMixin
+
+from zope.app.location import Location
+from zope.app.location.interfaces import ILocation
+from zope.component import adapts
+from zope.event import notify
+from zope.interface import implements
+
+from zope.generic.configuration.api import provideConfigurationData
+
+from zope.generic.type import IInitializer
+from zope.generic.type import IInitializerConfiguration
+from zope.generic.type import ITypeable
+from zope.generic.type.api import queryTypeConfiguration
+
+
+
+class Initializer(object):
+    """Initialize an object."""
+
+    implements(IInitializer)
+    
+    adapts(ITypeable)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, *pos, **kws):
+        config = queryTypeConfiguration(self.context, IInitializerConfiguration)
+        if config:
+            # store initialization data
+            if config.interface:
+                provideConfigurationData(self.context, config.interface, kws)
+
+            # invoke initialization handler
+            if config.handler:
+                config.handler(self.context, *pos, **kws)


Property changes on: zope.generic/trunk/src/zope/generic/type/adapter.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/api.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/api.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/api.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,31 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+# usage see README.txt
+from zope.generic.type.interfaces import *
+from zope.generic.type.base import Object
+from zope.generic.type.base import Contained
+from zope.generic.type.base import Container
+from zope.generic.type.base import Folder
+
+from zope.generic.type.helper import acquireObjectConfiguration
+from zope.generic.type.helper import createObject
+from zope.generic.type.helper import createParameter
+from zope.generic.type.helper import queryObjectConfiguration
+from zope.generic.type.helper import queryTypeConfiguration
+from zope.generic.type.helper import queryTypeInformation


Property changes on: zope.generic/trunk/src/zope/generic/type/api.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/base.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/base.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/base.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,112 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from persistent import Persistent
+
+from zope.interface import implements
+
+from zope.app.annotation.interfaces import IAttributeAnnotatable
+from zope.app.container import contained
+from zope.app.container import btree
+from zope.app import folder
+
+from zope.generic.configuration.api import IAttributeConfigurable
+from zope.generic.directlyprovides.api import provides
+from zope.generic.directlyprovides.api import UpdateProvides
+from zope.generic.directlyprovides.api import updateDirectlyProvided
+
+from zope.generic.type import IDirectlyTyped
+from zope.generic.type import IInitializer
+
+
+
+class Object(object):
+    """Default implementation for simple objects."""
+
+    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+
+    def __init__(self, interface, *pos, **kws):
+        super(Object, self).__init__()
+        self.__dict__['interface'] = interface
+        updateDirectlyProvided(self, interface)
+        initializer = IInitializer(self, None)
+        if initializer:
+            initializer(*pos, **kws)
+
+    provides('interface')
+
+    interface = UpdateProvides(IDirectlyTyped['interface'])
+
+
+
+class Contained(contained.Contained, Persistent):
+    """Default implementation local, persistend and contained objects."""
+
+    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+
+    def __init__(self, interface, *pos, **kws):
+        super(Contained, self).__init__()
+        self.__dict__['interface'] = interface
+        updateDirectlyProvided(self, interface)
+        initializer = IInitializer(self, None)
+        if initializer:
+            initializer(*pos, **kws)
+
+    provides('interface')
+
+    interface = UpdateProvides(IDirectlyTyped['interface'])
+
+
+
+class Container(btree.BTreeContainer):
+    """Default implementation local, persistend and containerish objects."""
+
+    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+
+    def __init__(self, interface, *pos, **kws):
+        super(Container, self).__init__()
+        self.__dict__['interface'] = interface
+        updateDirectlyProvided(self, interface)
+        initializer = IInitializer(self, None)
+        if initializer:
+            initializer(*pos, **kws)
+
+    provides('interface')
+
+    interface = UpdateProvides(IDirectlyTyped['interface'])
+
+
+
+class Folder(folder.Folder):
+    """Default implementation local, persistend and containerish possible sites."""
+
+    implements(IDirectlyTyped, IAttributeConfigurable, IAttributeAnnotatable)
+
+    def __init__(self, interface, *pos, **kws):
+        super(Folder, self).__init__()
+        self.__dict__['interface'] = interface
+        updateDirectlyProvided(self, interface)
+        initializer = IInitializer(self, None)
+        if initializer:
+            initializer(*pos, **kws)
+
+    provides('interface')
+
+    interface = UpdateProvides(IDirectlyTyped['interface'])


Property changes on: zope.generic/trunk/src/zope/generic/type/base.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,12 @@
+<configure
+  xmlns="http://namespaces.zope.org/zope"
+  xmlns:generic="http://namespaces.zope.org/generic"
+  i18n_domain="zope">
+
+  <generic:information
+      interface="zope.generic.information.IInformationRegistryInformation"
+      label="Type Information Registry"
+      registry=".ITypeInformation"
+      />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/type/configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/factory.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/factory.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/factory.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,120 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import implements
+
+from zope.component.factory import Factory
+from zope.component.interfaces import IFactory
+
+from zope.generic.type import ITypeable
+from zope.generic.type import ITyped
+from zope.generic.type import IDirectlyTyped
+from zope.generic.type import ITypeType
+        
+
+
+class TypeFactory(Factory):
+    """Type factory implementation.
+
+    Preset the type interface for generic directly typed implementation 
+    of its __init__ method.
+
+    The type factory constructs directly typed objects of a given generic 
+    implementation (class).
+
+    First we declare a type marker:
+
+        >>> from zope.interface import Interface
+
+        >>> class IMyMarker(Interface):
+        ...     pass
+
+        >>> from zope.app.component.interface import provideInterface
+        >>> provideInterface('', IMyMarker, ITypeType)
+
+    Afterward we build a generic implementation implementing ITyped or a
+    regular typeable class:
+
+        >>> from zope.generic.type import ITyped
+        >>> from zope.generic.directlyprovides.api import provides
+        >>> from zope.generic.directlyprovides.api import UpdateProvides
+        >>> from zope.generic.directlyprovides.api import updateDirectlyProvided
+
+        >>> class Object(object):
+        ...     implements(IDirectlyTyped)
+        ...
+        ...     def __init__(self, interface, **kws):
+        ...         super(Object, self).__init__()
+        ...         self.__dict__['interface'] = interface
+        ...         updateDirectlyProvided(self, interface)
+        ...
+        ...     provides('interface')
+        ...     interface = UpdateProvides(ITyped['interface'])
+
+        >>> class Foo(object):
+        ...    implements(ITypeable)
+
+    Now we make a factory instance and check it:
+
+        >>> myFactory = TypeFactory(Object, IMyMarker)
+
+        >>> my = myFactory()
+        >>> isinstance(my, Object)
+        True
+        >>> IMyMarker.providedBy(my)
+        True
+
+        >>> ITyped in myFactory.getInterfaces().flattened()
+        False
+        >>> IMyMarker in myFactory.getInterfaces().flattened()
+        True
+
+        >>> myFactory
+        <TypeFactory for <class 'zope.generic.type.factory.Object'>>
+        
+    """
+
+    implements(IFactory)
+
+    def __init__(self, callable, interface):
+        # preconditions
+        if not ITypeable.implementedBy(callable):
+            raise ValueError('Callable must implement %s.' % ITypeable.__name__)
+
+        if not ITypeType.providedBy(interface):
+            raise ValueError('Interface must provide %s.' % ITypeType.__name__)
+
+        super(TypeFactory, self).__init__(callable, title='', description='', interfaces=(interface,))
+
+        # essentials
+        self._interface = interface
+
+    def __call__(self, *pos, **kws):
+        if IDirectlyTyped.implementedBy(self._callable):
+            instance = self._callable(self._interface, *pos, **kws)
+        
+        else:
+            instance = self._callable(*pos, **kws)
+
+        # TODO: query type information look for InitConfiguration and invoke the
+        # handler if possible
+        
+        return instance
+


Property changes on: zope.generic/trunk/src/zope/generic/type/factory.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/helper.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/helper.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/helper.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,119 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope import component
+
+from zope.generic.configuration.api import dottedName
+from zope.generic.configuration.api import queryConfigurationData
+from zope.generic.information.api import queryInformation
+
+from zope.generic.type import IInitializerConfiguration
+from zope.generic.type import ITypeInformation
+from zope.generic.type import ITyped
+from zope.generic.type import ITypeType
+
+
+
+def createObject(interface, *pos, **kws):
+    """Create an instance of a logical type using the type marker."""
+    return component.createObject(dottedName(interface), *pos, **kws)
+
+
+def createParameter(interface):
+    config = queryTypeConfiguration(interface, IInitializerConfiguration)
+    if config:
+        return config.interface
+    
+    else:
+        return None
+
+
+
+def getType(object):
+    """Evaluate relevant type marker interface of an object."""
+
+    if ITypeType.providedBy(object):
+        interface = object
+
+    elif ITyped.providedBy(object):
+        interface = object.interface
+
+    else:
+        interface = ITyped(object).interface
+
+    return interface
+
+
+
+def queryType(object, default=None):
+    try:
+        return getType(object)
+    
+    except:
+        return default
+
+
+
+def getTypeInformation(object):
+    return queryInformation(getType(object), ITypeInformation)
+
+
+
+def queryTypeInformation(object, default=None):
+    """Lookup an type information of any object."""
+
+    try:
+        return getTypeInformation(object)
+
+    except:
+        return default
+
+
+
+def queryObjectConfiguration(object, configuration, default=None):   
+    return queryConfigurationData(object, configuration, default)
+
+
+
+def queryTypeConfiguration(object, configuration, default=None):
+    info = queryTypeInformation(object)
+    return queryConfigurationData(info, configuration, default)
+
+
+
+def acquireTypeConfiguration(object, configuration, default=None):
+    try:
+        interface = getType(object, default)
+
+    except:
+        return default
+
+
+def acquireObjectConfiguration(object, configuration, default=None):
+    # first try to evaluate object configuration data
+    data = queryObjectConfiguration(object, configuration, default)
+
+    if data is not default:
+        return data
+    
+    # return type configuration data
+    else:
+        return queryTypeConfiguration(object, configuration, default)
+


Property changes on: zope.generic/trunk/src/zope/generic/type/helper.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/interfaces.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/interfaces.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/interfaces.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,124 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.interface import alsoProvides
+from zope.interface import Interface
+from zope.interface.interfaces import IInterface
+from zope.schema import Bool
+from zope.schema import Object
+
+from zope.generic.configuration import IConfigurationHandler
+from zope.generic.configuration import IConfigurationType
+from zope.generic.directlyprovides import IProvides
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.generic.information import IInformation
+from zope.generic.information import IInformationDeclaration
+
+__all__ = ['ITypeType', 'ITypeable', 'ITyped', 'IDirectlyTyped', 
+           'ITypeInformation', 'IInitializer', 'IInitializationHandler', 
+           'IInitializerConfiguration']
+
+
+
+class ITypeType(IInterface):
+    """An abstract interface marker marker type.
+
+    An interface marked by this marker type will provide an typed information
+    within the corresponding ITypeInformation registry.
+    """
+
+
+
+class ITypeable(Interface):
+    """Assert ITyped by adaption or by implementation."""
+
+
+
+class ITyped(ITypeable, IInformationDeclaration):
+    """Provid an information within the."""
+
+    interface = Object(
+        title=_('Interface'),
+        description=_('Interface marker that references corresponding type informations.'),
+        required=True,
+        schema=ITypeType)
+
+
+
+class IDirectlyTyped(ITyped, IProvides, IInformationDeclaration):
+    """Directly provide the declared interface."""
+
+    def __init__(interface, *pos, **kws):
+        """Directly provide the type interface during the __init__ call."""
+
+    interface = Object(
+        title=_('Interface'),
+        description=_('The declared interface must be directly provided too.'),
+        required=True,
+        readonly=True,
+        schema=ITypeType)
+
+
+
+class ITypeInformation(IInformation):
+    """Provide information for the declared type interface."""
+
+
+
+class IInitializer(Interface):
+    """Initialize an object."""
+
+    def __call__(*pos, **kws):
+        """Invoke initialization handler declared by the initializer configuration."""
+
+
+
+class IInitializationHandler(Interface):
+    """Initialize an object."""
+
+    def __call__(context, *pos, **kws):
+        """Initialize the object referenced by self."""
+
+
+
+class IInitializerConfiguration(Interface):
+    """Provide initialization handler.
+
+    At least a handler or an interface must be defined.
+
+    If the interface is defined, **kws are stored as configuration defined by
+    the interface.
+
+    If the **kws does not satify the interface a KeyError is raised.
+    """
+
+    interface = Object(
+        title=_('Configuration interface'),
+        description=_('Configuration interface defining the signature.'),
+        required=False,
+        schema=IConfigurationType)
+
+    handler = Object(
+        title=_('Initialization Handler'),
+        description=_('Callable (context, *pos, **kws).'),
+        required=False,
+        schema=IInitializationHandler)
+
+alsoProvides(IInitializerConfiguration, IConfigurationType)


Property changes on: zope.generic/trunk/src/zope/generic/type/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/meta.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/meta.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,27 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta">
+
+  <meta:directives namespace="http://namespaces.zope.org/generic">
+
+    <meta:complexDirective
+        name="type"
+        schema=".metadirectives.ITypeDirective"
+        handler=".metaconfigure.TypeDirective"
+        >
+
+      <meta:subdirective
+          name="configuration"
+          schema="zope.generic.information.metadirectives.IConfigurationSubdirective"
+          />
+
+      <meta:subdirective
+          name="initializer"
+          schema="zope.generic.type.metadirectives.IInitializerSubdirective"
+          />
+
+    </meta:complexDirective>
+
+  </meta:directives>
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/type/meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/metaconfigure.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/metaconfigure.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/metaconfigure.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,130 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from types import ModuleType
+
+from zope.app.component.metaconfigure import proxify
+from zope.app.component.metaconfigure import adapter
+from zope.component import provideAdapter
+from zope.component import provideUtility
+from zope.component.interfaces import IFactory
+from zope.configuration.exceptions import ConfigurationError
+from zope.interface import implements
+from zope.security.checker import CheckerPublic
+from zope.security.checker import InterfaceChecker
+
+from zope.generic.configuration.api import ConfigurationData
+from zope.generic.configuration.api import dottedName
+from zope.generic.configuration.api import provideConfigurationData
+from zope.generic.information.metaconfigure import InformationDirective
+
+from zope.generic.type import IInitializationHandler
+from zope.generic.type import IInitializerConfiguration
+from zope.generic.type import ITypeInformation
+from zope.generic.type import ITypeType
+from zope.generic.type.adapter import Initializer
+from zope.generic.type.factory import TypeFactory
+from zope.generic.type.helper import queryTypeInformation
+
+
+
+def provideTypeConfiguration(interface, configuration, data):
+    """Set configuration data into the context."""
+
+    info = queryTypeInformation(interface)
+    provideConfigurationData(info, configuration, data)
+
+
+
+class InitializationHandler(object):
+    """Initialization handler.
+    
+    Wrap a callable:
+
+        >>> def callable(context, *pos, **kws):
+        ...     print context, pos, kws
+        
+        >>> init_handler = InitializationHandler(callable)
+        
+        >>> init_handler(1, 2, 3, x=4)
+        1 (2, 3) {'x': 4}
+    
+    """
+
+    implements(IInitializationHandler)
+
+    def __init__(self, callable):
+        self.__callable = callable
+
+    def __call__(self, context, *pos, **kws):
+        self.__callable(context, *pos, **kws)
+
+
+
+class TypeDirective(InformationDirective):
+    """Provide a new logical type."""
+
+    # mark types with a type marker type
+    _interface_type = ITypeType
+
+
+    def __init__(self, _context, interface, class_, label=None, hint=None):
+        # preconditions
+        if isinstance(class_, ModuleType):
+            raise ConfigurationError('Implementation attribute must be a class')
+        
+        # register types within the type information registry
+        registry = ITypeInformation
+        super(TypeDirective, self).__init__(_context, interface, registry, label, hint)
+
+        # create and proxy type factory
+        factory = TypeFactory(class_, self._interface) 
+        component = proxify(factory, InterfaceChecker(IFactory, CheckerPublic))
+
+        _context.action(
+            discriminator = ('provideUtility', self._interface),
+            callable = provideUtility,
+            args = (component, IFactory, dottedName(self._interface)),
+            )
+
+    def initializer(self, _context, interface=None, handler=None):
+        """Add initializer."""
+        # preconditions
+        if interface is None and handler is None:
+            raise ConfigurationError('Attribute interface or handler must be defined')
+
+        data = {}
+        if handler is not None:
+            if not IInitializationHandler.providedBy(handler):
+                handler = InitializationHandler(handler)
+
+            data['handler'] = handler
+
+        if interface is not None:
+            data['interface'] = interface
+
+        adapter(self._context, [Initializer], None, [self._interface], None, '', True, False)
+
+        _context.action(
+            discriminator = (
+            'initializer', self._interface),
+            callable = provideTypeConfiguration,
+            args = (self._interface, IInitializerConfiguration, data),
+            )


Property changes on: zope.generic/trunk/src/zope/generic/type/metaconfigure.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/metadirectives.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/metadirectives.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/metadirectives.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.configuration.fields import Bool
+from zope.configuration.fields import GlobalInterface
+from zope.configuration.fields import GlobalObject
+from zope.interface import Interface
+
+from zope.app.i18n import ZopeMessageFactory as _
+from zope.generic.information.metadirectives import IBaseInformationDirective
+
+    
+
+class ITypeDirective(IBaseInformationDirective):
+    """Declare attriubtes of the type directive.
+
+    Register an type information and a type factory.
+    """
+
+    class_ = GlobalObject(
+        title=_('Class'),
+        description=_('Generic class implementation.'),
+        required=True
+        )
+
+
+
+class IInitializerSubdirective(Interface):
+    """Provide an initializer configuration for the type."""
+
+    interface = GlobalInterface(
+        title=_('Configuration interface'),
+        description=_('Configuration interface defining the signature.'),
+        required=False
+        )
+
+    handler = GlobalObject(
+        title=_('Initializiation handler'),
+        description=_('Callable (context, *pos, **kws).'),
+        required=False
+        )


Property changes on: zope.generic/trunk/src/zope/generic/type/metadirectives.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/testing.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/testing.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/testing.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+__docformat__ = 'restructuredtext'
+
+from zope.configuration.xmlconfig import XMLConfig
+
+import zope.generic.configuration.testing
+
+################################################################################
+#
+# Public Test implementations
+#
+################################################################################
+
+def testInitializer(context, *pos, **kws):
+    print context, pos, kws
+
+
+
+################################################################################
+#
+# Placeless setup
+#
+################################################################################
+    
+# helper for directive testing
+class PlacelessSetup(zope.generic.configuration.testing.PlacelessSetup):
+
+    def setUp(self, doctesttest=None):
+        super(PlacelessSetup, self).setUp(doctesttest)
+        # register the directive of this package
+        import zope.generic.type
+        XMLConfig('meta.zcml', zope.generic.type)()
+
+    def tearDown(self, doctesttest=None):
+        super(PlacelessSetup, self).tearDown(doctesttest)
+
+
+
+placelesssetup = PlacelessSetup()


Property changes on: zope.generic/trunk/src/zope/generic/type/testing.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/tests.py
===================================================================
--- zope.generic/trunk/src/zope/generic/type/tests.py	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/tests.py	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,45 @@
+##############################################################################
+#
+# Copyright (c) 2005, 2006 Zope Corporation and Contributors.
+# 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.
+#
+##############################################################################
+
+"""
+$Id$
+"""
+
+import unittest
+
+from zope import component
+from zope import interface
+from zope.testing import doctest
+
+
+from zope.generic.type import testing
+from zope.generic.testing.testing import registerDirective
+
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite('zope.generic.type.factory'),
+        doctest.DocTestSuite('zope.generic.type.metaconfigure'),
+        doctest.DocFileSuite('README.txt',
+                             setUp=testing.placelesssetup.setUp,
+                             tearDown=testing.placelesssetup.tearDown,
+                             globs={'component': component, 'interface': interface,
+                             'registerDirective': registerDirective,
+                             'testing': testing},
+                             optionflags=doctest.NORMALIZE_WHITESPACE+
+                                            doctest.ELLIPSIS),
+        ))
+
+if __name__ == '__main__': unittest.main()


Property changes on: zope.generic/trunk/src/zope/generic/type/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/zope.generic.type-configure.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/zope.generic.type-configure.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/zope.generic.type-configure.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.type" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/type/zope.generic.type-configure.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.generic/trunk/src/zope/generic/type/zope.generic.type-meta.zcml
===================================================================
--- zope.generic/trunk/src/zope/generic/type/zope.generic.type-meta.zcml	2006-04-08 20:00:06 UTC (rev 66688)
+++ zope.generic/trunk/src/zope/generic/type/zope.generic.type-meta.zcml	2006-04-08 20:32:57 UTC (rev 66689)
@@ -0,0 +1,5 @@
+<configure xmlns="http://namespaces.zope.org/zope">
+
+  <include package="zope.generic.type" file="meta.zcml" />
+
+</configure>


Property changes on: zope.generic/trunk/src/zope/generic/type/zope.generic.type-meta.zcml
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the Checkins mailing list