Back to index

plone3  3.1.7
utilities.py
Go to the documentation of this file.
00001 #########################################################################
00002 # Copyright (c) 2004, 2005 Alberto Berti, Gregoire Weber.
00003 # All Rights Reserved.
00004 #
00005 # This file is part of CMFEditions.
00006 #
00007 # CMFEditions is free software; you can redistribute it and/or modify
00008 # it under the terms of the GNU General Public License as published by
00009 # the Free Software Foundation; either version 2 of the License, or
00010 # (at your option) any later version.
00011 #
00012 # CMFEditions is distributed in the hope that it will be useful,
00013 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 # GNU General Public License for more details.
00016 #
00017 # You should have received a copy of the GNU General Public License
00018 # along with CMFEditions; if not, write to the Free Software
00019 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 #########################################################################
00021 """Utilities
00022 
00023 $Id: utilities.py,v 1.1 2005/01/06 14:25:44 gregweb Exp $
00024 """
00025 
00026 import random
00027 
00028 from Persistence import Persistent
00029 from Acquisition import aq_base
00030 from Products.CMFCore.utils import getToolByName
00031 
00032 STUB_OBJECT_PREFIX = '_CMFEditionsTempId'
00033 
00034 class KwAsAttributes(Persistent):
00035     """Class attaching to itself passed keyword attributes.
00036     """
00037     def __init__(self, **kw):
00038         for key, val in kw.items():
00039             setattr(self, key, val)
00040 
00041 
00042 def dereference(obj=None, history_id=None, zodb_hook=None):
00043     """Dereference an object.
00044 
00045     Works with either an obj or a history_id or both.
00046 
00047     If only a history_id is used, then a 'zodb_hook' is required to obtain
00048     the uid tool.
00049 
00050     Returns a tuple consisting of the derefrenced object and
00051     the unique id of the object: ``(obj, uid)``
00052 
00053     If an object or history_id cannot be found None will be returned for
00054     one or both values.
00055     """
00056 
00057     if zodb_hook is None:
00058         # try to use the reference as zodb hook
00059         zodb_hook = obj
00060 
00061     portal_uidhandler = getToolByName(zodb_hook, 'portal_historyidhandler')
00062 
00063     if history_id is None:
00064         if obj is None:
00065             raise TypeError, "This method requires either an obj or a history_id"
00066         else:
00067             history_id = portal_uidhandler.queryUid(obj, None)
00068     elif obj is None:
00069         try:
00070             obj = portal_uidhandler.queryObject(history_id, None)
00071         except AttributeError:
00072             # We may get an attribute error in some cases, just return None
00073             pass
00074 
00075     return obj, history_id
00076 
00077 
00078 def generateId(parent, prefix='', volatile=False):
00079     """Generate an unused id (optionaly a volatile one).
00080     """
00081     existingIds = parent.objectIds()
00082     idTemplate = '%s%s_%%s' % (volatile * '__v_', prefix + STUB_OBJECT_PREFIX)
00083     while 1:
00084         id =  idTemplate % random.randrange(1000000)
00085         if id not in existingIds:
00086             return id
00087 
00088 
00089 def wrap(obj, parent):
00090     """Copy the context and containment from one object to another.
00091 
00092     This is needed to allow acquiring attributes. Containment and context
00093     is setup only in direction to the parents but not from the parent
00094     to itself. So doing the following raises an ``AttributeError``::
00095 
00096         getattr(wrapped.aq_parent, tempAttribute)
00097     """
00098     # be sure the obj is unwraped before wrapping it (argh, having
00099     # caused pulling my hair out until I realized it is wrapped)
00100     obj = aq_base(obj).__of__(parent)
00101 
00102     # set containment temporarly
00103     tempAttribute = generateId(parent, volatile=True)
00104     changed = parent._p_changed
00105     setattr(parent, tempAttribute, obj)
00106     wrapped = getattr(parent, tempAttribute)
00107     delattr(parent, tempAttribute)
00108     parent._p_changed = changed
00109 
00110     return wrapped