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

DataSkins.py

from DynPersist import DynPersist
from Globals import Persistent
from ComputedAttribute import ComputedAttribute
from Acquisition import ImplicitAcquisitionWrapper,aq_base
from DataManagers import DefaultDataManager
from PropertySheets import VirtualSheets, DataSkinSheet
from Globals import default__class_init__
from OFS.ObjectManager import ObjectManager
from OFS.CopySupport import CopySource
from AttributeProviders import NOT_FOUND
from ZClasses.Property import ZInstanceSheetsSheet
from ZClasses.ZClass import ZClassSheets
from Products.PlugIns import genericAddForm
from Transactions import Kept
_marker = []

_v_dm_ = '_v_dm_'
_v_status_ = '_v_status_'

ChangedStatus = 'Changed'
DeletedStatus = 'Deleted'
AddedStatus   = 'Added'

manage_afterAdd     = ObjectManager.manage_afterAdd.im_func
manage_beforeDelete = ObjectManager.manage_beforeDelete.im_func
manage_afterClone   = ObjectManager.manage_afterClone.im_func


class Token:
    status = memento = None

    def __init__(self,client,agent):
        self._p_jar = agent
        self.client = client
        get_transaction().register(self)






00042 class DataSkin(DynPersist,Persistent,Kept):

    """Mixin for objects that want to delegate storage issues externally"""

    _rackMounted = 0
    _isRackMountable = 1

    def __init__(self, id):
        # Bypass attribute providers for setting up initial id, 
        # since they need the id in order to work!
        self.__dict__['id']=id; self._p_changed = 1


00055     def _setRack(self, rack):
        """Called by the rack before returning the object"""
        d = self.__dict__
        d[_v_dm_] = rack; d['_rackMounted'] = 1


00061     def _setSlot(self, slot):
        """
        Set up the slot object for persistent storage of object
        'baggage' (e.g. WebDAV property sheets, etc.).  Called by
        ZODB-based racks at object retrieval, or by non-ZODB based
        racks at the object's request.
        """
        self._v_readableSlot = self._v_writeableSlot = slot


    def commitSubtransaction(self): return get_transaction().commit(1)

00073     def _getTokenFor(self,agent):
        """Return a transaction state monitor for this DataSkin/agent combo"""
        t,a = self._v_Tokens, id(agent.aq_base)
        if not t.has_key(a): t[a]=Token(self,agent)
        return t[a]




        
    # Computed attributes to handle on-demand slot retrieval/allocation, etc.
    __per_transaction_cache_attrs__ = (
        '_v_currentSheets', '_v_attrCache', '_v_status_',
        '_v_changedAttrs_', '_v_Tokens'
    )

00089     def _getCache(self):
        """Return attribute cache"""
        return self._v_attrCache
        
    def _v_readableSlot(self,_v_dm_=_v_dm_):
        return self.__dict__[_v_dm_]._readableSlotFor(self)

    def _v_writeableSlot(self,_v_dm_=_v_dm_):
        return self.__dict__[_v_dm_]._writeableSlotFor(self)

00099     def _v_attrCache(self):
        """Cache of external attribute values"""
        v = self._v_attrCache = {}; return v

00103     def _v_Tokens(self):
        """Cache of agent transaction monitoring tokens"""
        v = self._v_Tokens = {}; return v

    _v_readableSlot = ComputedAttribute(_v_readableSlot)
    _v_writeableSlot = ComputedAttribute(_v_writeableSlot)
    _v_attrCache = ComputedAttribute(_v_attrCache)
    _v_Tokens = ComputedAttribute(_v_Tokens)







        





    # Event management (avoids sequential repeats of same events)

00126     def _v_changedAttrs_(self):
        """Cache of changed attribute names"""
        v = self._v_changedAttrs_ = {}
        return v
        
    _v_changedAttrs_ = ComputedAttribute(_v_changedAttrs_)

    def _objectChanging(self,name,_v_status_=_v_status_,_v_dm_=_v_dm_):
        d=self.__dict__
        c=self._v_changedAttrs_
        v=self._v_attrCache
        
        if self._v_status_ is not ChangedStatus:
            d[_v_dm_]._objectChanging(self)
            d[_v_status_] = ChangedStatus
        
        if not c.has_key(name):
            c[name]=getattr(self,name,NOT_FOUND)

        if d.has_key(name):
            del d[name]; self._p_changed=1

        if v.has_key(name): del v[name]

    def _objectAdding(self,_v_status_=_v_status_,_v_dm_=_v_dm_):
        if self._v_status_ is not AddedStatus:
            d=self.__dict__
            d[_v_dm_]._objectAdding(self)
            d[_v_status_] = AddedStatus
        
    def _objectCreating(self,_v_dm_=_v_dm_):
        self.__dict__[_v_dm_]._objectCreating(self)
        
    def _objectDeleting(self,_v_status_=_v_status_,_v_dm_=_v_dm_):
        if self._v_status_ is not DeletedStatus:
            d=self.__dict__
            d[_v_dm_]._objectDeleting(self)
            d[_v_status_] = DeletedStatus

    # Attribute handling

    def __get_attr__(self,name,_v_dm_=_v_dm_):

        cache = self._v_attrCache
        v = cache.get(name,_marker)

        if v is _marker:
            v = getattr(self.__class__,'class_default_for_'+name,NOT_FOUND)
            cache[name] = v
            
            dm = self.__dict__[_v_dm_]
            self = self._canonicalForm()

            for ap in dm._getProvidersFor(self,'getattr',(name,'*')):
            
                v = ap._AttributeFor(self,name,NOT_FOUND)
                
                if v is not NOT_FOUND:
                    cache[name]=v
                    return v

            v = cache[name]
    
        if v is not NOT_FOUND:
            return v

        raise AttributeError, name


    def _canonicalForm(self):
        self._v_Keeper      # force existence of a keeper
        return ImplicitAcquisitionWrapper(
            aq_base(self),
            self.__dict__['_v_parent']
        )





    def __set_attr__(self,name,val,_v_dm_=_v_dm_):
        try:
            dm = self.__dict__[_v_dm_]
        except KeyError:
            if name=='id' and val==self.__dict__['id']: return
            raise

        self = self._canonicalForm()
        self._objectChanging(name)

        for ap in dm._getProvidersFor(self,'setattr',(name,'*')):
            if ap._SetAttributeFor(self,name,val):
                return

        if not self._rackMounted:
            self.__dict__[name]=val
            self._p_changed = 1
            return

        # XXX default behavior for rackmounted?
        raise AttributeError, name


    def __del_attr__(self,name,_v_dm_=_v_dm_):
    
        dm = self.__dict__[_v_dm_]
        self = self._canonicalForm()
        self._objectChanging(name)
        
        for ap in dm._getProvidersFor(self,'delattr',(name,'*')):
            if ap._DelAttributeFor(self,name):
                return
                
        if not self._rackMounted:
            if self._v_changedAttrs_[name] is NOT_FOUND:
                del self._v_changedAttrs_[name]        
            return
            
        # XXX default behavior for rackmounted?
        raise AttributeError, name

    # DataManager hookup

    _DefaultDataManager = DefaultDataManager()
    
    def __of__(self,parent,
        _iaw=ImplicitAcquisitionWrapper,_v_dm_=_v_dm_,type=type
        ):

        # Bound to unwrapped parent, just try again

        if type(parent) is not _iaw or not hasattr(parent,'REQUEST'):
            return self

        # Create our canonical form
        new_self = _iaw(self,parent)

        if type(self) is _iaw:  # Been wrapped already?
            return new_self     # No special handling

        self.__dict__['_v_parent'] = parent # save our canonical parent

        # Rackmounted? just save/return canonical form
        
        if self._rackMounted:
            return new_self

        # Otherwise, find our data manager
        dm = self._DefaultDataManager
        
        try:    _gdmf  = parent.aq_acquire('_getDataManagerFor')
        except: pass
        else:   dm = _gdmf(new_self, dm)
            
        self.__dict__[_v_dm_] = dm
        return new_self






    # ObjectManager Hooks to ensure event generation

    def manage_afterAdd(self,item,container):
        self._objectAdding()
        if hasattr(self.aq_base,'objectValues'):
            manage_afterAdd(self,item,container)

    def manage_beforeDelete(self,item,container):
        if hasattr(self.aq_base,'objectValues'):
            manage_beforeDelete(self,item,container)
        self._objectDeleting()


    # Copy Support

    def _getCopy(self, container):
        self = getattr(self,'aq_base',self).__of__(container)
        ob = CopySource._getCopy.im_func(self,container)
        ob.__of__(container)    # force DM hookup
        return ob

    def manage_afterClone(self,item,_v_dm_=_v_dm_):
        self = getattr(self,'aq_base',self)
        self = self._canonicalForm()
        if hasattr(self.aq_base,'objectValues'):
            manage_afterClone(self,item)















    # Propertysheets
    
    propertysheets = VirtualSheets()

00333     def _addPropertySheet(self,name='',xmlns='',_v_dm_=_v_dm_):
        """
        Return new propertysheet matching name or xmlns, if possible.
        Otherwise return None.
        """
        d=self.__dict__
        if d.has_key('_v_currentSheets'):
            del d['_v_currentSheets']

        return self._delegateToSheetProviders(name,xmlns,'_addPropertySheetFor')

00344     def _delPropertySheet(self,name='',xmlns='',_v_dm_=_v_dm_):
        """
        Delete propertysheet matching name or xmlns, if present.  Always
        returns None (unless an unexpected error occurs, of course)
        """
        d=self.__dict__
        if d.has_key('_v_currentSheets'):
            del d['_v_currentSheets']

        return self._delegateToSheetProviders(name,xmlns,'_delPropertySheetFor')


    def _delegateToSheetProviders(self,name,xmlns,mname):
        dm = self.__dict__[_v_dm_]
        self = self._canonicalForm()
        
        if name:
            for sp in dm._getProvidersFor(self,'sheet_names',(name,'*')):
                s = getattr(sp,mname)(self, name=name, xmlns=xmlns)
                if s is not None: return s
        if xmlns:
            for sp in dm._getProvidersFor(self,'sheet_xmlns',(xmlns,'*')):
                s = getattr(sp,mname)(self, name=name, xmlns=xmlns)
                if s is not None: return s
        return None

00370     def _v_currentSheets(self,_v_dm_=_v_dm_):

        """PropertySheets tuple (analagous to __propsets__)"""

        l = []
        
        for sp in self.__dict__[_v_dm_]._uniqueProviders(('sheets',)):
            l.extend(list(sp._PropertySheetsFor(self)))

        self._v_currentSheets = tuple(l)
        return self._v_currentSheets

    _v_currentSheets = ComputedAttribute(_v_currentSheets)


    

00387     def manage_delete(self,_v_dm_=_v_dm_):
        """Delete this object"""
        if self._rackMounted:
            self.__dict__[_v_dm_]._objectDeleting(self)
            return 'OK'
        raise TypeError, "Not rack-mounted; please use container to delete"

    meta_type = "Data Skin"

    __ac_permissions__ = (
        ('Delete rack-mounted objects', ('manage_delete',)),
    )












    # DEPRECATED STUFF 

00413     def PropertySheets(self):
        """
        Returns a 'propertysheets'-type object
        
        DEPRECATED - use 'propertysheets' attribute instead.
        """
        return self.propertysheets


00422     def PropertySheet(self, name='', xmlns=''):
        """
        Return a specific property sheet (DEPRECATED)
        
        Doesn't work w/ZClass sheets!  Use propertysheets.get() instead.
        """
        return self._delegateToSheetProviders(name,xmlns,'_PropertySheetFor')

    _v_status_ = ''

default__class_init__(DataSkin)



















class SkinZISS(ZInstanceSheetsSheet):
    manage_addDataSkinSheetForm = genericAddForm(DataSkinSheet)

    def manage_addDataSkinSheet(self, id, title, REQUEST=None):
        """Add a DataSkin sheet"""
        o=DataSkinSheet(id, title)
        self._setObject(id, o)
        if REQUEST is not None: return self.manage_main(self, REQUEST)

    meta_types = (
        {'name':DataSkinSheet.meta_type, 'action':'manage_addDataSkinSheetForm'},
    ) + ZInstanceSheetsSheet.meta_types

00465 class SZHolder:
    """ """
    def __init__(self):
        ZClassSheets.__init__.im_func(self)
        self.common=SkinZISS('common')

class _ZClass_for_DataSkin:
    propertysheets = SZHolder()
    _zclass_       = DataSkin
    manage_options = ()

def initialize(context):
    context.registerZClass(_ZClass_for_DataSkin)


Generated by  Doxygen 1.6.0   Back to index