[Zope3-checkins] CVS: Zope3/src/zope/app/schemacontent -
__init__.py:1.1 configure.zcml:1.1 content.py:1.1
instance.py:1.1 interfaces.py:1.1
Stephan Richter
srichter at cosmos.phy.tufts.edu
Tue Mar 9 19:58:00 EST 2004
Update of /cvs-repository/Zope3/src/zope/app/schemacontent
In directory cvs.zope.org:/tmp/cvs-serv28963/src/zope/app/schemacontent
Added Files:
__init__.py configure.zcml content.py instance.py
interfaces.py
Log Message:
Moved mutable schemas out of zope.app.utilities to zope.app.schema. Also,
seperated it from the mutable schema content definition/instance code, which
now lives in zope.app.schemacontent.
=== Added File Zope3/src/zope/app/schemacontent/__init__.py ===
# import this
=== Added File Zope3/src/zope/app/schemacontent/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<!-- Content Component Definition -->
<content class=".content.ContentComponentDefinition">
<factory
id="utility.ContentComponentDefinition"
title="Content Component Definition"
description="A Persistent Content Component Definition" />
<implements
interface="zope.app.interfaces.services.utility.ILocalUtility" />
<implements
interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
<require
permission="zope.ManageServices"
interface=".interfaces.IContentComponentDefinition"
set_schema=".interfaces.IContentComponentDefinition" />
</content>
<content class=".content.ContentComponentDefinitionRegistration">
<require
permission="zope.ManageServices"
interface="zope.app.interfaces.services.utility.IUtilityRegistration
zope.app.container.interfaces.IAddNotifiable
zope.app.container.interfaces.IRemoveNotifiable"
set_schema="zope.app.interfaces.services.utility.IUtilityRegistration"
/>
</content>
<!-- Content Component Menu Item -->
<content class=".content.ContentComponentDefinitionMenuItem">
<require
permission="zope.ManageServices"
interface=".interfaces.IContentComponentMenuItem"
set_schema=".interfaces.IContentComponentMenuItem" />
</content>
<adapter
for=".interfaces.IContentComponentDefinition"
provides=".interfaces.IContentComponentMenuItem"
factory=".content.ContentComponentDefinitionMenuItem" />
<!-- Content Component Instance -->
<content class=".content.ContentComponentInstance">
<implements
interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
</content>
<include package=".browser" />
</configure>
=== Added File Zope3/src/zope/app/schemacontent/content.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Content Component Definition and Instance
$Id: content.py,v 1.1 2004/03/10 00:57:59 srichter Exp $
"""
from persistent import Persistent
from persistent.dict import PersistentDict
from zope.app import zapi
from zope.app.i18n import ZopeMessageIDFactory as _
from zope.app.interfaces.annotation import IAnnotations
from zope.app.container.interfaces import IAdding
from zope.app.interfaces.services.menu import \
ILocalBrowserMenu, ILocalBrowserMenuService
from zope.app.interfaces.services.registration import ActiveStatus
from zope.app.container.contained import Contained
from zope.app.services.menu import \
LocalBrowserMenuService, LocalBrowserMenu, LocalBrowserMenuItem
from zope.app.services.service import ServiceRegistration
from zope.app.services.servicenames import BrowserMenu
from zope.app.services.utility import UtilityRegistration
from zope.component.exceptions import ComponentLookupError
from zope.interface import directlyProvides, implements
from zope.schema import getFields
from zope.security.checker import CheckerPublic, Checker, defineChecker
from interfaces import IContentComponentDefinition, IContentComponentMenuItem
from interfaces import IContentComponentInstance
MenuItemKey = 'http://www.zope.org/utilities/content/menuitem'
class ContentComponentDefinition(Persistent, Contained):
implements(IContentComponentDefinition)
def __init__(self, name=u'', schema=None, copySchema=True):
self.name = name
self.schema = schema
self.copySchema = copySchema
self.permissions = PersistentDict()
## # This will set up the menu item entry.
## IContentComponentMenuItem(self)
class ContentComponentDefinitionMenuItem(object):
"""An adapter that takes a Content Component Defintion and provides all
necessary information to create a menu item for the content component."""
implements(IContentComponentMenuItem)
__used_for__ = IContentComponentDefinition
def __init__(self, context):
self.context = context
ann = IAnnotations(context)
if not ann.has_key(MenuItemKey):
ann[MenuItemKey] = PersistentDict(
{'interface': IAdding,
'title': self.context.name,
'description': '',
'permission': 'zope.ManageContent',
'filter_string': '',
'menuId': 'add_content',
'create': True,
# This is not part of the interface, but we need to store
# that information.
'menuItemId': None,
'menu': None}
)
self._data = ann[MenuItemKey]
self._menu = self._data['menu']
if self._menu:
self._menuItem = self._data['menu'][self._data['menuItemId']]
else:
self._menuItem = None
def _createMenuService(self):
"""Create a browser menu service for the menu item."""
# Get the local service manager; not that we know it must exist,
# otherwise this object would not be called.
sm = zapi.getServiceManager(self.context)
# Get the default package and add a menu service called 'Menus-1'
default = zapi.traverse(sm, 'default')
default['Menus-1'] = LocalBrowserMenuService()
# Register the service and set it to active
path = "%s/default/%s" % (zapi.getPath(sm), 'Menus-1')
reg = ServiceRegistration(BrowserMenu, path, sm)
key = default.getRegistrationManager().addRegistration(reg)
reg = zapi.traverse(default.getRegistrationManager(), key)
reg.status = ActiveStatus
return zapi.traverse(default, 'Menus-1')
def _createMenu(self):
"""Create a menu."""
# Create a menu and add it to the default package
menu = LocalBrowserMenu()
sm = zapi.getServiceManager(self.context)
default = zapi.traverse(sm, 'default')
default[self.menuId] = menu
# Register th emenu as a utility and activate it.
path = "%s/default/%s" % (zapi.getPath(sm), self.menuId)
reg = UtilityRegistration(self.menuId, ILocalBrowserMenu, path)
key = default.getRegistrationManager().addRegistration(reg)
reg = zapi.traverse(default.getRegistrationManager(), key)
reg.status = ActiveStatus
return zapi.traverse(default, self.menuId)
def createMenuItem(self):
"See .interfaces.IContentComponentMenuItem"
# If 'create' is set to true, we must generate the necessary objects
# locally
if self.create:
# Get the servicem manager and the default package
sm = zapi.getServiceManager(self.context)
default = zapi.traverse(sm, 'default')
service = sm.queryService(BrowserMenu)
# Check whether the service really exists locally; if not, create
# one for this service manager
if (service is None or
not ILocalBrowserMenuService.providedBy(service) or
not zapi.name(service) in default):
service = self._createMenuService()
# Check whether the menu exists locally; if not create one.
menu = service.queryInheritedMenu(self.menuId, True)
if (menu is None or
not ILocalBrowserMenu.providedBy(menu) or
not zapi.name(menu) in default):
menu = self._createMenu()
else:
# Find a browser menu service and make sure it is a local one.
service = zapi.getService(self, BrowserMenu)
if not ILocalBrowserMenuService.providedBy(service):
raise ComponentLookupError, \
_('No local/peristent Browser Menu Service found.')
# Find the browser menu and make sure it is a local one
menu = service.queryInheritedMenu(self.menuId, True)
if menu is None or not ILocalBrowserMenu.providedBy(menu):
error = _('No local Browser Menu called "${name}" found.')
error.mapping = {'name': self.menuId}
raise ComponentLookupError, error
self._data['menu'] = menu
# Creating the menu item
item = LocalBrowserMenuItem()
for name in ('interface', 'action', 'title', 'description',
'permission', 'filter_string'):
setattr(item, name, getattr(self, name))
self._data['menuItemId'] = menu.addItem(item)
def removeMenuItem(self):
"See .interfaces.IContentComponentMenuItem"
self._data['menu'].__delitem__(self._data['menuItemId'])
self._data['menu'] = None
self._data['menuItemId'] = None
def _setMenuId(self, value):
if self._data['menuId'] != value:
self._data['menuId'] = value
# This is the path of least reistence
self.removeMenuItem()
self.createMenuItem()
menuId = property(lambda self: self._data['menuId'], _setMenuId)
def _setInterface(self, value):
if self._data['interface'] != value:
self._data['interface'] = value
# If a menu item exists, make sure it gets updated.
if self._menuItem is not None:
self._menuItem.interface = value
interface = property(lambda self: self._data['interface'], _setInterface)
def _getAction(self):
return 'AddContentComponent/' + self.context.name
action = property(_getAction)
def _getTitle(self):
return self._data['title'] or self.context.name
def _setTitle(self, value):
if self._data['title'] != value:
self._data['title'] = value
# If a menu item exists, make sure it gets updated.
if self._menuItem is not None:
self._menuItem.title = value
title = property(_getTitle, _setTitle)
def _setDescription(self, value):
if self._data['description'] != value:
self._data['description'] = value
# If a menu item exists, make sure it gets updated.
if self._menuItem is not None:
self._menuItem.description = value
description = property(lambda self: self._data['description'],
_setDescription)
def _setPermission(self, value):
if self._data['permission'] != value:
self._data['permission'] = value
# If a menu item exists, make sure it gets updated.
if self._menuItem is not None:
self._menuItem.permission = value
permission = property(lambda self: self._data['permission'],
_setPermission)
def _setFilterString(self, value):
if self._data['filter_string'] != value:
self._data['filter_string'] = value
# If a menu item exists, make sure it gets updated.
if self._menuItem is not None:
self._menuItem.filter = value
filter_string = property(lambda self: self._data['filter_string'],
_setFilterString)
def _setCreate(self, value):
if self._data['create'] != value:
self.removeMenuItem()
self._data['create'] = value
self.createMenuItem()
create = property(lambda self: self._data['create'],
_setCreate)
class ContentComponentDefinitionRegistration(UtilityRegistration):
"""Content Component Registration"""
def activated(self):
"""Once activated, we have to register the new Content Object with the
appropriate menu.
"""
component = self.getComponent()
component.name = self.name
IContentComponentMenuItem(component).createMenuItem()
def deactivated(self):
"""Once activated, we have to unregister the new Content Object with
the appropriate menu."""
component = self.getComponent()
component.name = None
IContentComponentMenuItem(component).removeMenuItem()
class ContentComponentInstance(Persistent):
implements(IContentComponentInstance)
def __init__(self, name, schema, schemaPermissions=None):
super(ContentComponentInstance, self).__init__()
# Save the name of the object
self.__name__ = name
# XXX: We really should make a copy of the schema first, so that it
# cannot be changed.
self.__schema = schema
# Add the new attributes, if there was a schema passed in
if schema is not None:
for name, field in getFields(schema).items():
setattr(self, name, field.default)
directlyProvides(self, schema)
# Build up a Checker rules and store it for later
if schemaPermissions is None:
schemaPermissions = {}
self.__checker_getattr = PersistentDict()
self.__checker_setattr = PersistentDict()
for name in getFields(schema):
get_perm, set_perm = schemaPermissions.get(name, (None, None))
self.__checker_getattr[name] = get_perm or CheckerPublic
self.__checker_setattr[name] = set_perm or CheckerPublic
# Always permit our class's public methods
self.__checker_getattr['getSchema'] = CheckerPublic
def __setattr__(self, key, value):
if (key in ('getSchema',) or
key.startswith('_p_') or
key.startswith('__') or
key.startswith('_ContentComponentInstance__')):
return super(ContentComponentInstance, self).__setattr__(key,
value)
is_schema_field = self.__schema is not None and \
key in getFields(self.__schema).keys()
if is_schema_field:
super(ContentComponentInstance, self).__setattr__(key, value)
else:
raise AttributeError, 'Attribute "%s" not available' %key
def getSchema(self):
return self.__schema
def __repr__(self):
return '<ContentComponentInstance called %s>' %self.__name__
def ContentComponentInstanceChecker(instance):
"""A function that can be registered as a Checker in defineChecker()"""
return Checker(instance.__checker_getattr.get,
instance.__checker_setattr.get)
defineChecker(ContentComponentInstance, ContentComponentInstanceChecker)
=== Added File Zope3/src/zope/app/schemacontent/instance.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Content Object Instance
$Id: instance.py,v 1.1 2004/03/10 00:57:59 srichter Exp $
"""
from persistent import Persistent
from persistent.dict import PersistentDict
from zope.app.component.interfacefield import InterfaceField
from zope.interface import directlyProvides, implements, Interface
from zope.schema import getFields, TextLine
from zope.security.checker import CheckerPublic, Checker, defineChecker
class IContentComponentInstance(Interface):
"""Interface describing a Conten Object Instance"""
__name__ = TextLine(
title=u"Name of Content Component Type",
description=u"""This is the name of the document type.""",
required=True)
__schema__ = InterfaceField(
title=u"Schema",
description=u"Specifies the schema that characterizes the document.",
required=True)
class ContentComponentInstance(Persistent):
implements(IContentComponentInstance)
def __init__(self, name, schema, schemaPermissions=None):
super(ContentComponentInstance, self).__init__()
# Save the name of the object
self.__name__ = name
# XXX: We really should make a copy of the schema first, so that it
# cannot be changed.
self.__schema = schema
# Add the new attributes, if there was a schema passed in
if schema is not None:
for name, field in getFields(schema).items():
setattr(self, name, field.default)
directlyProvides(self, schema)
# Build up a Checker rules and store it for later
if schemaPermissions is None:
schemaPermissions = {}
self.__checker_getattr = PersistentDict()
self.__checker_setattr = PersistentDict()
for name in getFields(schema):
get_perm, set_perm = schemaPermissions.get(name, (None, None))
self.__checker_getattr[name] = get_perm or CheckerPublic
self.__checker_setattr[name] = set_perm or CheckerPublic
# Always permit our class's public methods
self.__checker_getattr['getSchema'] = CheckerPublic
def __setattr__(self, key, value):
if (key in ('getSchema',) or
key.startswith('_p_') or
key.startswith('__') or
key.startswith('_ContentComponentInstance__')):
return super(ContentComponentInstance, self).__setattr__(key,
value)
is_schema_field = self.__schema is not None and \
key in getFields(self.__schema).keys()
if is_schema_field:
super(ContentComponentInstance, self).__setattr__(key, value)
else:
raise AttributeError, 'Attribute not available'
def getSchema(self):
return self.__schema
def __repr__(self):
return '<ContentComponentInstance called %s>' %self.__name__
def ContentComponentInstanceChecker(instance):
"""A function that can be registered as a Checker in defineChecker()"""
return Checker(instance.__checker_getattr.get,
instance.__checker_setattr.get)
defineChecker(ContentComponentInstance, ContentComponentInstanceChecker)
=== Added File Zope3/src/zope/app/schemacontent/interfaces.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Content Component Definition and Instance Interfaces
$Id: interfaces.py,v 1.1 2004/03/10 00:57:59 srichter Exp $
"""
from zope.app.container.interfaces import IAdding
from zope.app.component.interfacefield import InterfaceField
from zope.app.i18n import ZopeMessageIDFactory as _
from zope.app.publisher.interfaces.browser import IBrowserMenuItem
from zope.interface import Interface, Attribute
from zope.schema import TextLine, Bool
class IContentComponentMenuItem(IBrowserMenuItem):
"""This is a schema that specifies the information needed to create a menu
item for the Content Component.
This reflects mainly the IBrowserMenuItem interface, except that the
interface's default is set to IAdding, which should be the usual case. I
also had to add a menuId field that specifies the menu (obviously).
If the 'create' attribute is set to True, then the necessary components
will be created locally.
"""
interface = InterfaceField(
title=_('interface-component', "Interface"),
description=_("Specifies the interface this menu item is for."),
default=IAdding,
required=True)
menuId = TextLine(
title=_("Menu Id"),
description=_("Specifies the menu this menu item will be added to."),
default=u"add_content",
required=True)
create = Bool(
title=_("Create Menu"),
description=_("If set to True, the system will create a local Browser "
"Menu Service and local Browser Menu for you. If this "
"option is set to False, the system will try to find "
"the next local browser menu service that has a menu "
"with the specifed id. If no menu was found or the menu "
"is a global menu, then an error is created."),
default=True,
required=True)
def createMenuItem():
"""Create a menu item from the information in this object."""
def removeMenuItem():
"""Remove the specified menu item."""
class IContentComponentDefinition(Interface):
"""Content Component Definitions describe simple single-schema based
content components including their security declarations."""
name = TextLine(
title=_("Name of Content Component Type"),
description=_("This is the name of the document type."),
required=True)
schema = InterfaceField(
title=_('schema-component', "Schema"),
description=_("Specifies the schema that characterizes the document."),
required=True)
copySchema = Bool(
title=_("Copy Schema"),
description=_("If this field is set to True, a copied version of the "
"schema will be used in the Content Component "
"instance. This has the advantage that an existing "
"Content Component's schema is set in stone and can "
"never change, even when a mutable schema evolves. If "
"the value is False, then the Content Component's "
"can change (which is desirable in some cases - i.e. "
"during development.)"),
default=True,
required=True)
permissions = Attribute(
u"A dictionary that maps set/get permissions on the schema's"
u"fields. Entries looks as follows: {fieldname:(set_perm, get_perm)}")
class IContentComponentInstance(Interface):
"""Interface describing a Content Component Instance"""
__name__ = TextLine(
title=_("Name of Content Component Type"),
description=_("This is the name of the document type."),
required=True)
__schema__ = InterfaceField(
title=_('schema-component', "Schema"),
description=_("Specifies the schema that characterizes the document."),
required=True)
More information about the Zope3-Checkins
mailing list