Logo Search packages:      
Sourcecode: zope-loginmanager version File versions

PlugIns.py

from Globals import HTMLFile, default__class_init__, Persistent
from OFS.Folder import Folder; from OFS.PropertySheets import PropertySheets
from OFS.ObjectManager import ObjectManager; from OFS.SimpleItem import Item
from AccessControl.PermissionRole import PermissionRole
from App.ProductContext import ProductContext
import Acquisition, operator, string, Products; from Acquisition import aq_base

"""What are PlugIns, and what does this pattern do?

PROBLEM -- You are creating an object which you want to be end-user
configurable and extensible.  You need to manage one or more sets of
user-selected collaborator objects which extend your base object.  These
collaborator objects may be of multiple types, although within a given set,
they must all support the same collaboration interface.  You don't know in
advance what types these objects will be, since you want users to be able
to create arbitrary implementations of your collaboration interface.  You
also want to store, add, and manage these collaborators like regular Zope
sub-objects (so that acquistion, etc. still work), but don't want the
collaborators to show up on the Folder add list.  Finally, for clarity,
you'd like each set of collaborators to have their own management tab
(ala Contents), but not show up on your Contents tab (if you have one).

SOLUTION -- PlugInContainers are Folder-derived objects which can have
specialized collaborators, namely PlugIns.  PlugInContainers have management
tabs (implemented by PlugInGroups) for each collaboration interface
(__plugin_kind__).  PlugIn classes are registered by kind, and
PlugInContainer classes have PlugInGroups which determine what kind(s)
of PlugIns can be added on each management tab.

EXAMPLE APPLICATIONS -- LoginManager has PlugInGroups for LoginMethods and
UserSources.  If ZCatalog used a PlugInGroup for Indexes using a plugin
kind of "ZCatalog Index", users could create arbitrary kinds of index
objects without touching ZCatalog itself.  And so on.

LIMITATIONS -- Due to the way PlugIn classes register their permissions
and constructors, they must be implemented directly in Python.  It is
theoretically possible to create specialized constructors that would do
the same magic for ZClasses, but it would appear to require Fulton-like
Zen to do so.  As Jim would say, "waaaa!"
"""

# XXX Replaceability support - temporary until Zope supports it natively
import ts_regex
bad_id=ts_regex.compile('[^a-zA-Z0-9-_~\,\. ]').search #TS

# Global constants: __replaceable__ flags (see PlugInContainer._checkId):
NOT_REPLACEABLE = 0
REPLACEABLE = 1
UNIQUE = 2

































00083 class PlugInBase:
    """
PlugIns are objects which collaborate with their container in some way.  They
notify their container when they are added or removed.  PlugIns have a 'kind'
(__plugin_kind__) which is a string that identifies their collaboration role.
    """
        
    __plugin_kind__ = ""

    def isAPlugIn(self):
        return self.__plugin_kind__

    def __init__(self,id='',title=''):
        self.id = id
        self.title = title

    def _setup(self):
        pass    # easy subclass extension stub
        
    def manage_afterAdd(self, item, container):
        self._setup()
        container = self.aq_parent
        if self.__plugin_kind__ and hasattr(container,'_addPlugIn'):
            container._addPlugIn(self)

    def manage_beforeDelete(self, item, container):
        container = self.aq_parent
        if self.__plugin_kind__ and hasattr(container,'_removePlugIn'):
            container._removePlugIn(self)


00114 class PlugIn(PlugInBase, Item, Acquisition.Implicit, Persistent):
    """PlugIn that is compatible w/Zope management framework"""
    pass







00124 class PlugInContainer(PlugInBase, Folder):
    """
PlugInContainers are Folders which can have specialized collaborators known as
PlugIns, managed under management tabs provided by PlugInGroups.

This base class is useless in and of itself, as you must subclass it
to create a particular kind of PlugInContainer.  Your subclass must
define attributes for each PlugInGroup you want to have, plus a
__plugin_groups__ attribute which contains all of the PlugInGroups.  Example:

 class MyPIC(PlugInContainer):
     UserSources  = PlugInGroup('UserSources',
         ['User Source'],attr='userSourcesList'
     )
     LoginMethods = PlugInGroup('LoginMethods',
         ['Login Method'], attr='loginMethodsList'
     )
     __plugin_groups__ = (UserSources, LoginMethods)
     ...
"""

    manage_main = HTMLFile('www/main', globals())

00147     def _addPlugIn(self, plugin):

        """Register a plugin with its group"""

        plugin = getattr(plugin, 'aq_base', plugin)
        kind = plugin.__plugin_kind__

        for group in self.__plugin_groups__:
            if kind in group.kinds:
                group._addPlugIn(self, plugin)
                break        
        else:
            raise TypeError,("Unsupported plugin kind '%s'" % plugin.__plugin_kind__)

        self.manage_refreshPlugIns()



00165     def _removePlugIn(self, plugin):

        """Unregister plugin from any supporting group(s)"""

        plugin = getattr(plugin, 'aq_base', plugin)
        kind = plugin.__plugin_kind__

        for group in self.__plugin_groups__:
            if kind in group.kinds:
                group._removePlugIn(self, plugin)
        self.manage_refreshPlugIns()
        

00178     def _findGroupFor(self, plugin):

        """Return the group a plugin belongs to"""

        for group in self.__plugin_groups__:
            group = group.__of__(self)
            if plugin in group._objectValues():
                return group


00188     def _installPlugIn(self, plugin, message="", REQUEST=None):

        """Install a plugin (called by plugin constructors)"""

        self._setObject(plugin.id, plugin)

        if REQUEST is not None:
            group = self._findGroupFor(plugin)
            return group.manage_main(group, REQUEST, update_menu=1,
                manage_tabs_message=message, URL='%s/%s/manage_workspace' % (REQUEST.URL1,group.id))








00206     def manage_refreshPlugIns(self, REQUEST=None):
        """Update plugin registries"""
        for group in self.__plugin_groups__:
            group.__of__(self).manage_refreshPlugIns()
            
        if REQUEST is not None:
            return self.manage_main(self, REQUEST,
                manage_tabs_message="PlugIns refreshed.")

    manage_options_left = {'label':'Methods', 'action':'manage_main'},

    manage_options_right = tuple(Folder.manage_options[1:])

00219     def manage_options(self):

        """Construct manage_options (tabs) from left+plugin groups+right"""

        def as_option(group):
            d = {'label':group.title, 'action': group.id+'/manage_workspace'}
            if hasattr(group,'help_info'): d['help']=group.help_info
            return d
            
        return self.manage_options_left + \
            tuple(map(as_option,self.__plugin_groups__))+ \
            self.manage_options_right


    def all_meta_types(self,exclude_plugins=0):
        mt = Folder.all_meta_types.im_func(self)
        if not exclude_plugins:
            mt=list(mt)
            for g in self.__plugin_groups__:
                mt.extend(g.__of__(self).all_meta_types())
        return mt

    def filtered_meta_types(self,user=None,exclude_plugins=0):
        mt = Folder.filtered_meta_types.im_func(self,user)
        if exclude_plugins:
            return filter(lambda x: not x.has_key('plugin_add_method'), mt)
        return mt

    # Replaceability support (temporary, till Zope supports it as standard...)

    def _checkId(self, id, allow_dup=0):
        # If allow_dup is false, an error will be raised if an object
        # with the given id already exists. If allow_dup is true,
        # only check that the id string contains no illegal chars;
        # _checkId() will be called again later with allow_dup
        # set to false before the object is added.
        if not id or (type(id) != type('')):
            raise 'Bad Request', 'Empty or invalid id specified.'
        if bad_id(id) != -1:
            raise 'Bad Request', (
            'The id "%s" contains characters illegal in URLs.' % id)
        if id[0]=='_': raise 'Bad Request', (
            'The id "%s" is invalid - it begins with an underscore.'  % id)
        if not allow_dup:
            obj = getattr(self, id, None)
            if obj is not None:
                # An object by the given id exists either in this
                # ObjectManager or in the acquisition path.
                flags = getattr(obj, '__replaceable__', NOT_REPLACEABLE)
                if hasattr(aq_base(self), id):
                    # The object is located in this ObjectManager.
                    if not flags & REPLACEABLE:
                        raise 'Bad Request', ('The id "%s" is invalid - ' \
                              'it is already in use.' % id)
                    # else the object is replaceable even if the UNIQUE
                    # flag is set.
                elif flags & UNIQUE:
                    raise 'Bad Request', \
                          ('The id "%s" is reserved.' % id)
        if id == 'REQUEST':
            raise 'Bad Request', 'REQUEST is a reserved name.'
        if '/' in id:
            raise 'Bad Request', (
                'The id "%s" contains characters illegal in URLs.' % id
                )




    def manage_beforeDelete(self,item,container):
        PlugInBase.manage_beforeDelete.im_func(self,item,container)
        Folder.manage_beforeDelete(self,item,container)

    def manage_afterAdd(self,item,container):
        Folder.manage_afterAdd(self,item,container)
        PlugInBase.manage_afterAdd.im_func(self,item,container)
        

    __ac_permissions__ = (
        ('View management screens', ('manage_main','manage_refreshPlugIns')
        ),
    )

default__class_init__(PlugInContainer)


PluggableContainer = PlugInContainer    # Backward compatibility























def genericAddForm(pluginClass, globalDict=None):

    """Return a customized HTMLFile of the generic plugin Add form"""
    
    className = pluginClass.__name__
    formName = 'manage_add%sForm' % className
    
    f = HTMLFile(
        'genericAddForm', globals(),
        title_       = pluginClass.meta_type,
        constructor_ = ('manage_add%s'     % className),
        __name__     = formName
    )

    if globalDict is not None: globalDict[formName] = f
    return f


_defaultConstructor = '''
def manage_add%(name)s(self, id, title='', REQUEST=None):
    """Add %(meta_type)s"""
    ob = %(name)s(id, title)
    return self.Destination()._installPlugIn(ob, "%(meta_type)s added", REQUEST)
'''


def simpleConstructor(pluginClass,globalDict):
    name=pluginClass.__name__; meta_type = pluginClass.meta_type
    exec _defaultConstructor % locals() in globalDict
    return globalDict['manage_add%s' % name]


def defaultConstructors(pluginClass,globalDict):
    return (
        genericAddForm(pluginClass,globalDict),
        simpleConstructor(pluginClass,globalDict)
    )




00370 class PlugInGroup(Acquisition.Implicit):
    """
PlugInGroups manage PlugIns of specific Kind(s) on behalf of a PlugInContainer.
The PlugIns are actually stored in the PlugInContainer, but the PlugInGroup
helps manage them as a group.
    """

00377     def __init__(self, id, kinds, attr, title='', help=()):
        """
Create a PlugIn group to manage a registry of PlugIns of the specified kinds.
Registry will be stored in the PlugInContainer attribute specified by attr.
If attr is not specified, registry will be stored in the PlugInContainer's
__plugins__ attribute as a dictionary mapping kinds to lists of plugins.
        """

        self.id,self.kinds,self.attr,self.title = id,tuple(kinds),attr,title
        if help: self.help_info=help

00388     def all_meta_types(self):
        """Return meta_types which can be added to this group"""
        return unifiedPlugInRegistry(self, self.kinds)

    # We need filtered meta types, but we don't want to be an ObjectManager
    filtered_meta_types = ObjectManager.filtered_meta_types.im_func     # Hack!

00395     def _PlugInsChanged(self, container, pluginslist):
        """This is just a hookpoint for subclasses"""
        pass













00411     def manage_refreshPlugIns(self, REQUEST=None):
        """Refresh plugin registry"""
        container = self.aq_inner.aq_parent
        self._PlugInsChanged(container, getattr(container, self.attr, []))
        if REQUEST is not None:
            return self.manage_main(self, REQUEST,
                manage_tabs_message="PlugIns refreshed.",
                URL=REQUEST.URL1+'/manage_workspace')

    def _objectValues(self):
        container = self.aq_inner.aq_parent
        return getattr(container, self.attr, [])
        
00424     def objectValues(self):
        """Get objects contained within the group"""
        container = self.aq_inner.aq_parent
        return map (lambda x,c=container: x.__of__(c), self._objectValues())
        
00429     def objectItems(self):
        """get (id, object) tuples of items in the group"""
        return map(lambda x: (x.id, x), self.objectValues())
        
    manage_main = manage_workspace = \
        HTMLFile('www/PlugInGroup', globals())

    manage_above = manage_below = ''

00438     def _addPlugIn(self, container, plugin):
        """Register plug-in with group"""
        l = getattr(container, self.attr, None) or []
        if plugin not in l: l.append(plugin)
        setattr(container, self.attr, l)

00444     def _removePlugIn(self, container, plugin):
        """Unregister plug-in from group"""
        l = getattr(container, self.attr, None) or []
        l = filter(lambda x,p=plugin: x is not p, l)
        setattr(container, self.attr, l)



    def tabs_path_info(self, script, path):
        path = self.absolute_url(relative=1) + '/foo'
        return self.aq_inner.aq_parent.tabs_path_info(script, path)

00456     def manage_first(self, ids=[], REQUEST=None):
        """Re-sort plugins, moving selected ones first"""

        container = self.aq_inner.aq_parent

        l = getattr(container, self.attr, None) or []

        l = filter(lambda x,ids=ids: x.id in ids, l) + \
            filter(lambda x,ids=ids: x.id not in ids, l)

        setattr(container, self.attr, l)
        container.manage_refreshPlugIns()

        if REQUEST:
            return self.manage_main(self,REQUEST,update_menu=1,
                URL=REQUEST.URL1+'/manage_workspace')
            
00473     def manage_cutObjects(self, ids, REQUEST=None):
        """Put a reference to the objects named in ids in the clip board"""
        cp = self.aq_inner.aq_parent.manage_cutObjects(ids,REQUEST)
        if REQUEST is not None:
            return self.manage_main(self, REQUEST, cb_dataValid=1,
                URL=REQUEST.URL1+'/manage_workspace')
        return cp
    
00481     def manage_copyObjects(self, ids, REQUEST=None, RESPONSE=None):
        """Put a reference to the objects named in ids in the clip board"""
        cp = self.aq_inner.aq_parent.manage_copyObjects(ids,REQUEST)
        if REQUEST is not None:
            return self.manage_main(self, REQUEST, cb_dataValid=1,
                URL=REQUEST.URL1+'/manage_workspace')
        return cp





00493     def manage_renameObject(self, id, new_id, REQUEST=None):
        """Rename a particular sub-object"""
        self.aq_inner.aq_parent.manage_renameObject(id,new_id)
        if REQUEST is not None:
            return self.manage_main(self, REQUEST, update_menu=1,
                URL=REQUEST.URL1+'/manage_workspace')

00500     def manage_renameObjects(self, ids, new_ids, REQUEST=None):
        """Rename several sub-objects"""
        self.aq_inner.aq_parent.manage_renameObjects(ids,new_ids)
        if REQUEST is not None:
            return self.manage_main(self, REQUEST, update_menu=1,
                URL=REQUEST.URL1+'/manage_workspace')

00507     def manage_delObjects(self, ids=[], REQUEST=None):
        """Delete subordinate objects"""
        self.aq_inner.aq_parent.manage_delObjects(ids,REQUEST)        
        if REQUEST is not None:
            return self.manage_main(self, REQUEST, update_menu=1,
                URL=REQUEST.URL1+'/manage_workspace')


00515     def _constructPlugIn(self,name,*args,**kwargs):

        """Create a plug-in - used when container wants defaults plugins"""

        # Use filtered meta types so users can't bypass create permissions
        for meta in self.filtered_meta_types(self.REQUEST.AUTHENTICATED_USER):
            if meta['name']==name:
                method = meta['plugin_add_method']
                product = self.aq_inner.aq_parent.manage_addProduct[meta['product']]
                method = getattr(product, method) # XXX 2.1.x compat
                if not hasattr(method,'im_self'): args = (product,)+args
                return apply(method, args, kwargs)







    # XXX should have different permission for manage_first, but what?

    __ac_permissions__ = (
        ('View management screens',
            ('manage_first','manage_main','manage_workspace',
                'manage_above', 'manage_below', 'manage_refreshPlugIns')
        ),
    )

default__class_init__(PlugInGroup)


def PlugInFinder(PIG):
    return lambda self,PIG=PIG: PIG.__of__(self).filtered_meta_types()


def MakePICBase(PIC):
    import sys
    d = sys.modules[PIC.__module__].__dict__
    c = """
from Products.PlugIns.PlugIns import ZClass_for_PlugInContainer

class %(id)s_ZClassBase(%(id)s):
    __name__ = "%(id)s"
    manage_options = %(id)s.manage_options.im_func(%(id)s)

class ZClass_for_%(id)s(ZClass_for_PlugInContainer):
    _zclass_ = %(id)s_ZClassBase
""" % {'id':PIC.__name__}

    exec c in d










# Global PlugIn class registry
# key: kind name; value: lists of meta-type dicts for classes of kind
PlugInKinds = {}

class _ProductContextPatch:

    def registerPlugInClass(self, instance_class=None, meta_type='',
                              permission=None, constructors=(),
                              icon=None, permissions=None, legacy=(),):
        """
        Register a plug-in class.  The class registered will not be included in the
        master Products.meta_types registry, but only in the PlugInKinds registry.
        To register a plug-in class, create an initialize() method in your product's
        __init__.py.  In it, call context.registerPlugInClass() with the parameters
        you would use for a context.registerClass() call.
        """

        result = self.registerClass(instance_class,meta_type,
            permission,constructors,icon,permissions,legacy)

        meta = Products.meta_types[-1]
        Products.meta_types = Products.meta_types[:-1]

        if len(constructors)>1:
            method = constructors[1]
            if type(method) is type(()):
                name,method = method
            else: name = method.__name__
            meta['plugin_add_method'] = name

        kind = instance_class.__plugin_kind__

        l = PlugInKinds.get(kind, [])
        l.append(meta)
        PlugInKinds[kind] = l

        return result    




    def registerPIContainerBase(self, PIC):
        import sys
        d = sys.modules[PIC.__module__].__dict__
        self.registerZClass(d['ZClass_for_'+PIC.__name__])
        

# Patch ourselves in so we look like part of the Zope registration API
ProductContext.__dict__.update(_ProductContextPatch.__dict__)

































class _ProductRegistryMixinPatch:

    def _manage_add_plugin_meta_type(self, product, kind, meta_type, constructor_names,
                                      permission=''):
        pid = product.id
        id, constructor_name = constructor_names

        meta_types = self.aq_maybe('_getProductRegistryData')('plugins')

        for mt in meta_types:
            if mt['name']==meta_type:
                raise 'Type Exists', (
                    'The type <em>%s</em> is already defined as a plug-in.' 
                    % meta_type)

        mt={
            'name':    meta_type,
            'action':  ('%s%s' % (self._constructor_prefix_string(pid), id)),
            'product': pid,

            'plugin_kind':       kind,
            'plugin_add_method': constructor_name,
        }

        if permission: mt['permission']=permission
        
        meta_types = meta_types+(mt,)

        self.aq_maybe('_setProductRegistryData')('plugins',meta_types)












    def _manage_remove_plugin_meta_type(self, product, meta_type=None):
        r=[]
        pid=product.id

        for mt in self.aq_maybe('_getProductRegistryData')('plugins'):

            if mt.has_key('product'):
                if mt['product']==pid and (
                    meta_type is None or meta_type==mt['name']):
                    continue
                elif meta_type==mt['name']:
                    continue

                r.append(mt)
            
        self.aq_maybe('_setProductRegistryData')('plugins',tuple(r))



from App.ProductRegistry import ProductRegistry, ProductRegistryMixin

# default empty list
ProductRegistry._product_plugins=() 

# Patch methods
ProductRegistryMixin.__dict__.update(_ProductRegistryMixinPatch.__dict__)















def unifiedZClassRegistry(context, filterfunc=None):

    """Return a sanely unified registry of ZClasses and ZClass bases"""

    z = Products.meta_classes
    i = Products.meta_class_info

    r = {}
    for k in z.keys():
        r[k] = i[k], z[k]

    for data in context.aq_acquire('_getProductRegistryData')('zclasses'):
        path = '%(product)s/%(id)s' % data
        r[path] = '%(product)s: %(id)s' % data, data['meta_class']

    if filterfunc is not None:
        for k,(i,z) in r.items():
            if not filterfunc(z): del r[k]

    return r


def unifiedPlugInRegistry(context, kinds):

    r=[]

    # Python plug-ins
    for k in kinds: r.extend(PlugInKinds.get(k,[]))

    # ZClass plug-ins
    r.extend(list(
        filter(
            lambda x,kinds=kinds: x['plugin_kind'] in kinds,
            context.aq_acquire('_getProductRegistryData')('plugins')
        )
    ))

    return r



from App.Factory import Factory
from App.Product import Product

00783 class PlugInFactory(Factory):
    """Like a regular factory, but for PlugIns"""

    __ac_permissions__ = Factory.__ac_permissions__

    meta_type = "PlugIn Factory"
    icon = "misc_/PlugIns/PlugInFactory_icon"

    def __init__(self, id, title, meta_type, kind, initial, constructor, permission=''):
        self.id=id
        self.title=title
        self.object_type=meta_type
        self.kind=kind
        self.initial=initial
        self.constructor=constructor
        self.permission=permission

    def manage_edit(self, title, meta_type, kind, initial, constructor, permission='',
                    REQUEST=None):
        "Modify factory properties."

        self._unregister()

        self.title=title
        self.object_type=meta_type
        self.kind=kind
        self.initial=initial
        self.constructor=constructor
        self.permission=permission
        self.manage_setPermissionMapping(('Use Factories',), (permission,))

        self._register()
        if REQUEST is not None: return self.manage_main(self, REQUEST)






    def _register(self):
        # Register with the product folder
        product=self.aq_parent

        product.aq_acquire('_manage_add_plugin_meta_type')(
            product, self.kind, self.object_type, (self.initial,self.constructor), 
            self.permission
        )

    def _unregister(self):
        # Unregister with the product folder
        product=self.aq_parent

        product.aq_acquire('_manage_remove_plugin_meta_type')(
            product, self.object_type
        )

    manage_main=HTMLFile('editFactory',globals())

default__class_init__(PlugInFactory)


Product.manage_addPlugInFactoryForm = HTMLFile('addFactory',globals())

def manage_addPlugInFactory(
    self, id, title, meta_type, kind, initial, constructor, permission=None,
    REQUEST=None):
    ' '
    i=PlugInFactory(id, title, meta_type, kind, initial, constructor, permission)
    self._setObject(id,i)
    if REQUEST is not None:
        return self.manage_main(self,REQUEST,update_menu=1)

Product.manage_addPlugInFactory = manage_addPlugInFactory

Product.meta_types = Product.meta_types + (
    {'name': PlugInFactory.meta_type, 'action':'manage_addPlugInFactoryForm'},
)



from ZClasses.ZClass import addFormDefault, addDefault
from ZClasses.ZClassOwner import ZClassOwner

import ZClasses.ZClass

def manage_addZClass(self, id, title='', baseclasses=[],
                         meta_type='', CreateAFactory=0,
                         REQUEST=None, zope_object=0):
    "Add a ZClass"

    ZClasses.ZClass.manage_addZClass(
            self, id, title, baseclasses, meta_type, 0,
            zope_object=zope_object
    )

    if CreateAFactory:

        Z=self._getOb(id)   # The meta-class
        z=Z._zclass_        # The real class

        meta_type = z.meta_type

        self.manage_addDTMLMethod(
            id+'_addForm', 
            id+' constructor input form', 
            addFormDefault % {'id': id, 'meta_type': meta_type},
            )

        self.manage_addPermission(
            id+'_add_permission',
            id+' constructor permission',
            'Add %ss' % meta_type 
            )








        if getattr(z,'__plugin_kind__',None):

            self.manage_addDTMLMethod(
                id+'_add',
                id+' constructor',
                addDefault % {'id': id},  # XXX change to our own template?
                )
            self.manage_addPlugInFactory(
                id+'_factory',
                id+' factory',
                meta_type,
                z.__plugin_kind__,
                id+'_addForm',
                id+'_add',
                'Add %ss' % meta_type 
            )

        else:
            self.manage_addDTMLMethod(
                id+'_add',
                id+' constructor',
                addDefault % {'id': id},
                )
            self.manage_addPrincipiaFactory(
                id+'_factory',
                id+' factory',
                meta_type,
                id+'_addForm',
                'Add %ss' % meta_type 
            )

        Z.propertysheets.permissions.manage_edit(
            selected=['Add %ss' % id])
        Z.manage_setPermissionMapping(
            permission_names=['Create class instances'],
            class_permissions=['Add %ss' % meta_type]
        ) 

    if REQUEST is not None:
        return self.manage_main(self,REQUEST, update_menu=1)

Product.manage_addZClass = ZClassOwner.manage_addZClass = manage_addZClass

from OFS.PropertySheets import PropertySheet,View
from ZClasses.Property import ClassCaretaker

class PIKCaretaker(ClassCaretaker):
    def __getattr__(self,name):
        return ClassCaretaker.__getattr__(self,'__%s__' % name)

    def __setattr__(self,name,value):
        ClassCaretaker.__setattr__(self,('__%s__' % name),value)

    def __delattr__(self,name):
        ClassCaretaker.__delattr__(self,'__%s__' % name)


00961 class PlugInKindSheet(PropertySheet,View):
    """ZClass class sheet for setting plug-in kind"""

    _getZClass = Acquisition.Acquired

    def p_self(self): return self

    def v_self(self):
        return PIKCaretaker(self._getZClass()._zclass_)

    _properties = ({'id':'plugin_kind', 'type':'string', 'mode':'w'},)

    def propertyLabel(self, id):
        return {'plugin_kind':'Plug-In Kind'}.get(id,id)

    def property_extensible_schema__(self): return 0

    __ac_permissions__=(
        ('Manage Z Classes', ('', 'manage')),
        )

default__class_init__(PlugInKindSheet)



class PlugInZClassSheets:
    pluginKind = PlugInKindSheet('pluginKind')


class ZClass_for_PlugInBase:
    propertysheets = PlugInZClassSheets()

    manage_options = (
        {'label': 'Plug-in Kind', 'action': 'propertysheets/pluginKind/manage'},
    )

    _zclass_ = PlugInBase


class ZClass_for_PlugInContainer(ZClass_for_PlugInBase):
    _zclass_ = PlugInContainer


def initialize(context):
    #context.registerZClass(ZClass_for_PlugInBase)
    #context.registerZClass(ZClass_for_PlugInContainer)
    pass







   


Generated by  Doxygen 1.6.0   Back to index