[Erp5-report] r12767 - in /spec/debian/unstable/erp5-cmfuid: ./ CMFUid/ CMFUid/debian/ CMFU...

nobody at svn.erp5.org nobody at svn.erp5.org
Thu Feb 15 18:15:48 CET 2007


Author: yusei
Date: Thu Feb 15 18:15:44 2007
New Revision: 12767

URL: http://svn.erp5.org?rev=12767&view=rev
Log:
added debian package and workspace.

Added:
    spec/debian/unstable/erp5-cmfuid/
    spec/debian/unstable/erp5-cmfuid/CMFUid/
    spec/debian/unstable/erp5-cmfuid/CMFUid/DEPENDENCIES.txt
    spec/debian/unstable/erp5-cmfuid/CMFUid/README.txt
    spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdAnnotationTool.py
    spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdGeneratorTool.py
    spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdHandlerTool.py
    spec/debian/unstable/erp5-cmfuid/CMFUid/__init__.py
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/changelog
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/compat
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/control
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/copyright
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/dzproduct
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/postinst
    spec/debian/unstable/erp5-cmfuid/CMFUid/debian/rules   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/interfaces.py
    spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/
    spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/default/
    spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/default/toolset.xml
    spec/debian/unstable/erp5-cmfuid/CMFUid/tests/
    spec/debian/unstable/erp5-cmfuid/CMFUid/tests/__init__.py   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_all.py   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidannotation.py   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidgeneration.py   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidhandling.py   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/tool.gif   (with props)
    spec/debian/unstable/erp5-cmfuid/CMFUid/version.txt
    spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.diff.gz   (with props)
    spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.dsc
    spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_all.deb   (with props)
    spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.build
    spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.changes
    spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4.orig.tar.gz   (with props)

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/DEPENDENCIES.txt
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/DEPENDENCIES.txt?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/DEPENDENCIES.txt (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/DEPENDENCIES.txt Thu Feb 15 18:15:44 2007
@@ -1,0 +1,2 @@
+Zope >= 2.7.0
+CMFCore

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/README.txt
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/README.txt?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/README.txt (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/README.txt Thu Feb 15 18:15:44 2007
@@ -1,0 +1,52 @@
+CMFUid Readme
+
+    CMFUid introduces a unique id implementation to the CMF 1.5.0 and newer.
+    
+    Implementation
+    
+        The supplied tools attach the unique ids to the objects. The objects
+        do not have to be aware of unique ids.
+        
+        The current implementation depends on the portal catalog to find an 
+        object of a given unique id. The interfaces do not imply the use
+        of the catalog (except the IUniqueIdBrainQuery).
+        
+        Which Tool does What?
+        
+            The 'portal_uidgenerator' tools responsibility is to generate 
+            unique ids. The 'portal_uidannotation' tool is responsible to 
+            attach unique ids to a content object. The 'portal_uidhandler' 
+            manages registering and accessing unique ids. 
+            
+            This design was chosen to allow users replacing only parts of
+            the functionality without having to understand the whole thing.
+        
+        Unique Id API
+        
+            'portal_uidhandler' implementing 'IUniqueIdHandler' is the main 
+            API for playing with unique ids.
+        
+    Dependencies
+    
+        Object lookup by unique id depends on CMFCore (especially on 
+        portal_catalog). 
+    
+    Usage
+    
+        'portal_uidhandler' fully implements IUniqueIdHandler (IUniqueIdSet
+        for registering/unregistering unique ids, IUniqueIdQuery for queries
+        and IUniqueIdBrainQuery for more efficient queries by returning 
+        catalog brains instead of objects).
+        
+        The current implementation of get/queryBrain and get/queryObject 
+        do not return invisible objects (and brains of invisible objects).
+        
+        Have a look at the interfaces.
+        
+        CMFUid's functionality is used by CMFDefault's favorite content type 
+        to follow linked objects. The favorite content type works as before if 
+        CMFUid is not installed. 
+        
+        See 'CMFDefault.Favorite.Favorite'.
+    
+    gregweb/2004-08-05

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdAnnotationTool.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdAnnotationTool.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdAnnotationTool.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdAnnotationTool.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,145 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Unique Id Annotation Tool
+
+Provides support for managing unique id annotations.
+
+$Id: UniqueIdAnnotationTool.py 36482 2004-08-27 08:16:22Z yuppie $
+"""
+
+from Globals import InitializeClass, Persistent
+from AccessControl import ClassSecurityInfo
+from Acquisition import aq_base, aq_inner, aq_parent
+from Acquisition import Implicit
+
+from OFS.PropertyManager import PropertyManager
+from OFS.SimpleItem import SimpleItem
+
+from Products.CMFCore.utils import getToolByName, UniqueObject
+from Products.CMFCore.ActionProviderBase import ActionProviderBase
+
+from Products.CMFUid.interfaces import IUniqueIdAnnotation
+from Products.CMFUid.interfaces import IUniqueIdAnnotationManagement
+
+
+class UniqueIdAnnotation(Persistent, Implicit):
+    """Unique id object used as annotation on (content) objects.
+    """
+
+    __implements__ = (
+        IUniqueIdAnnotation,
+    )
+
+    def __init__(self, obj, id):
+        """See IUniqueIdAnnotation.
+        """
+        self._uid = None
+        self.id = id
+        setattr(obj, id, self)
+
+    def __call__(self):
+        """See IUniqueIdAnnotation.
+        """
+        return self._uid
+
+    def getId(self):
+        """See IUniqueIdAnnotation.
+        """
+        return self.id
+
+    def setUid(self, uid):
+        """See IUniqueIdAnnotation.
+        """
+        self._uid = uid
+
+    def manage_afterClone(self, item):
+        """See IUniqueIdAnnotation.
+        """
+        # Duplicated unique ids on the copied object have to be avoided.
+        # the uid object may already be removed by the 'manage_afterAdd'.
+        # To be independent of the implementation of 'manage_afterAdd'
+        # the unique id object probably gets removed another time.
+        anno_tool = getToolByName(item, 'portal_uidannotation')
+        if anno_tool.remove_on_clone:
+            try:
+                delattr( aq_parent( aq_inner(self) ), self.id )
+            except (KeyError, AttributeError):
+                pass
+
+    def manage_beforeDelete(self, item, container):
+        """See IUniqueIdAnnotation.
+        """
+        # This helps in distinguishing renaming from copying/adding and
+        # importing in 'manage_afterAdd' (see below)
+        anno_tool = getToolByName(item, 'portal_uidannotation')
+        if anno_tool.remove_on_add:
+            self._cmf_uid_is_rename = True
+
+    def manage_afterAdd(self, item, container):
+        """See IUniqueIdAnnotation.
+        """
+        # 'is_rename' is set if deletion was caused by a rename/move.
+        # The unique id is deleted only if the call is not part of
+        # a rename operation.
+        # This way I the unique id gets deleted on imports.
+        _is_rename = getattr(aq_base(self), '_cmf_uid_is_rename', None)
+        anno_tool = getToolByName(item, 'portal_uidannotation')
+        if anno_tool.remove_on_add and anno_tool.remove_on_clone \
+           and not _is_rename:
+            try:
+                delattr( aq_parent( aq_inner(self) ), self.id )
+            except (KeyError, AttributeError):
+                pass
+        if _is_rename is not None:
+            del self._cmf_uid_is_rename
+
+InitializeClass(UniqueIdAnnotation)
+
+
+class UniqueIdAnnotationTool(UniqueObject, SimpleItem, PropertyManager, ActionProviderBase):
+    __doc__ = __doc__ # copy from module
+
+    __implements__ = (
+        IUniqueIdAnnotationManagement,
+        ActionProviderBase.__implements__,
+        SimpleItem.__implements__,
+    )
+
+    manage_options = (
+        PropertyManager.manage_options +
+        ActionProviderBase.manage_options +
+        SimpleItem.manage_options
+    )
+
+    id = 'portal_uidannotation'
+    alternative_id = "portal_standard_uidannotation"
+    meta_type = 'Unique Id Annotation Tool'
+
+    security = ClassSecurityInfo()
+
+    remove_on_add = True
+    remove_on_clone = True
+    _properties = (
+    {'id': 'remove_on_add', 'type': 'boolean', 'mode': 'w',
+     'label': "Remove the objects unique id on add (and import)"},
+    {'id': 'remove_on_clone', 'type': 'boolean', 'mode': 'w',
+     'label': 'Remove the objects unique id on clone (CAUTION !!!)'},
+    )
+
+    security.declarePrivate('__call__')
+    def __call__(self, obj, id):
+        """See IUniqueIdAnnotationManagement.
+        """
+        return UniqueIdAnnotation(obj, id)
+
+InitializeClass(UniqueIdAnnotationTool)

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdGeneratorTool.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdGeneratorTool.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdGeneratorTool.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdGeneratorTool.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,75 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Uid Generator.
+
+Provides support for generating unique ids.
+
+$Id: UniqueIdGeneratorTool.py 37148 2005-07-14 09:33:42Z gregweb $
+"""
+
+from AccessControl import ClassSecurityInfo
+from BTrees.Length import Length
+from Globals import InitializeClass
+from OFS.SimpleItem import SimpleItem
+
+from Products.CMFCore.ActionProviderBase import ActionProviderBase
+from Products.CMFCore.utils import UniqueObject
+from Products.CMFUid.interfaces import IUniqueIdGenerator
+
+
+class UniqueIdGeneratorTool(UniqueObject, SimpleItem, ActionProviderBase):
+    """Generator of unique ids.
+    
+    This is a dead simple implementation using a counter. May cause
+    ConflictErrors under high load and the values are predictable.
+    """
+
+    __implements__ = (
+        IUniqueIdGenerator,
+        ActionProviderBase.__implements__,
+        SimpleItem.__implements__,
+    )
+
+    id = 'portal_uidgenerator'
+    alternative_id = 'portal_standard_uidgenerator'
+    meta_type = 'Unique Id Generator Tool'
+
+    security = ClassSecurityInfo()
+
+    security.declarePrivate('__init__')
+    def __init__(self):
+        """Initialize the generator
+        """
+        # The previous ``BTrees.Length.Length`` implementation may cause 
+        # double unique ids under high load. So for the moment we just use 
+        # a simple counter.
+        self._uid_counter = 0
+
+    security.declarePrivate('__call__')
+    def __call__(self):
+        """See IUniqueIdGenerator.
+        """
+        # For sites that have already used CMF 1.5.1 (and older) the
+        # BTrees.Length.Length object has to be migrated to an integer.
+        if isinstance(self._uid_counter, Length):
+            self._uid_counter = self._uid_counter()
+        self._uid_counter += 1
+        return self._uid_counter
+
+    security.declarePrivate('convert')
+    def convert(self, uid):
+        """See IUniqueIdGenerator.
+        """
+        return int(uid)
+
+InitializeClass(UniqueIdGeneratorTool)

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdHandlerTool.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdHandlerTool.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdHandlerTool.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/UniqueIdHandlerTool.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,245 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Unique Id Handler Tool
+
+Provides support for accessing unique ids on content object.
+
+$Id: UniqueIdHandlerTool.py 37149 2005-07-14 09:52:37Z gregweb $
+"""
+
+import Missing
+
+import zLOG
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+from Acquisition import Implicit, aq_base
+
+from OFS.SimpleItem import SimpleItem
+
+from Products.CMFCore.utils import getToolByName, UniqueObject
+from Products.CMFCore.ActionProviderBase import ActionProviderBase
+from Products.CMFCore.permissions import ManagePortal
+
+from Products.CMFUid.interfaces import IUniqueIdHandler
+from Products.CMFUid.interfaces import IUniqueIdBrainQuery
+from Products.CMFUid.interfaces import IUniqueIdUnrestrictedQuery
+from Products.CMFUid.interfaces import UniqueIdError
+
+UID_ATTRIBUTE_NAME = 'cmf_uid'
+
+class UniqueIdHandlerTool(UniqueObject, SimpleItem, ActionProviderBase):
+    __doc__ = __doc__ # copy from module
+
+    __implements__ = (
+        IUniqueIdHandler,
+        IUniqueIdBrainQuery,
+        IUniqueIdUnrestrictedQuery,
+        ActionProviderBase.__implements__,
+        SimpleItem.__implements__,
+    )
+
+    id = 'portal_uidhandler'
+    alternative_id = "portal_standard_uidhandler"
+    meta_type = 'Unique Id Handler Tool'
+    
+    # make the uid attribute name available for the unit tests
+    # not meant to be altered as long you don't know what you do!!!
+    UID_ATTRIBUTE_NAME = UID_ATTRIBUTE_NAME
+    
+    # make the exception class available through the tool
+    UniqueIdError = UniqueIdError
+    
+    security = ClassSecurityInfo()
+    
+    def _reindexObject(self, obj):
+        # add uid index and colums to catalog if not yet done
+        UID_ATTRIBUTE_NAME = self.UID_ATTRIBUTE_NAME
+        catalog = getToolByName(self, 'portal_catalog')
+        if UID_ATTRIBUTE_NAME not in catalog.indexes():
+            catalog.addIndex(UID_ATTRIBUTE_NAME, 'FieldIndex')
+            catalog.addColumn(UID_ATTRIBUTE_NAME)
+        
+        # reindex
+        catalog.reindexObject(obj)
+
+    def _setUid(self, obj, uid):
+        """Attaches a unique id to the object and does reindexing.
+        """
+        # attach a unique id annotation to the object
+        anno_tool = getToolByName(self, 'portal_uidannotation')
+        annotation = anno_tool(obj, self.UID_ATTRIBUTE_NAME)
+        annotation.setUid(uid)
+        
+        # reindex the object
+        self._reindexObject(obj)
+
+    security.declarePublic('register')
+    def register(self, obj):
+        """See IUniqueIdSet.
+        """
+        uid = self.queryUid(obj, default=None)
+        if uid is None:
+            # generate a new unique id and set it
+            generator = getToolByName(self, 'portal_uidgenerator')
+            uid = generator()
+            self._setUid(obj, uid)
+            
+        return uid
+    
+    security.declareProtected(ManagePortal, 'unregister')
+    def unregister(self, obj):
+        """See IUniqueIdSet.
+        """
+        UID_ATTRIBUTE_NAME = self.UID_ATTRIBUTE_NAME
+        if getattr(aq_base(obj), UID_ATTRIBUTE_NAME, None) is None:
+            raise UniqueIdError, \
+                  "No unique id available to be unregistered on '%s'" % obj
+            
+        # delete the uid and reindex
+        delattr(obj, UID_ATTRIBUTE_NAME)
+        self._reindexObject(obj)
+    
+    
+    security.declarePublic('queryUid')
+    def queryUid(self, obj, default=None):
+        """See IUniqueIdQuery.
+        """
+        uid = getattr(aq_base(obj), self.UID_ATTRIBUTE_NAME, None)
+        # If 'obj' is a content object the 'uid' attribute is usually a
+        # callable object. If 'obj' is a catalog brain the uid attribute 
+        # is non callable and possibly equals the 'Missing.MV' value.
+        if uid is Missing.MV or uid is None:
+            return default
+        if callable(uid):
+            return uid()
+        return uid
+    
+    security.declarePublic('getUid')
+    def getUid(self, obj):
+        """See IUniqueIdQuery.
+        """
+        uid = self.queryUid(obj, None)
+        if uid is None:
+            raise UniqueIdError, "No unique id available on '%s'" % obj
+        return uid
+    
+    security.declarePrivate('setUid')
+    def setUid(self, obj, uid, check_uniqueness=True):
+        """See IUniqueIdSet.
+        """
+        # None is the only value a unique id shall never have!
+        if uid is None:
+            raise UniqueIdError, "It's forbidden to set a unique id to 'None'."
+        
+        # check for uniqueness if enabled
+        if check_uniqueness:
+            result = self.queryObject(uid)
+            if result is not None and result != obj:
+                if callable(uid):
+                    uid = uid()
+                raise UniqueIdError, \
+                      "The unique id '%s' is already in use" % uid
+        
+        # everything is ok: set it!
+        self._setUid(obj, uid)
+    
+    def _queryBrain(self, uid, searchMethodName, default=None):
+        """This helper method does the "hard work" of querying the catalog
+           and interpreting the results.
+        """
+        if uid is None:
+            return default
+        
+        # convert the uid to the right format
+        generator = getToolByName(self, 'portal_uidgenerator')
+        uid = generator.convert(uid)
+        
+        catalog = getToolByName(self, 'portal_catalog')
+        searchMethod = getattr(catalog, searchMethodName)
+        result = searchMethod({self.UID_ATTRIBUTE_NAME: uid})
+        len_result = len(result)
+
+        # return None if no object found with this uid
+        if len_result == 0:
+            return default
+
+        # print a message to the log  if more than one object has
+        # the same uid (uups!)
+        if len_result > 1:
+            zLOG.LOG("CMUid ASSERT:", zLOG.INFO,
+                     "Uups, %s objects have '%s' as uid!!!" % \
+                     (len_result, uid))
+        
+        return result[0]
+    
+    security.declarePublic('queryBrain')
+    def queryBrain(self, uid, default=None):
+        """See IUniqueIdBrainQuery.
+        """
+        return self._queryBrain(uid, 'searchResults', default)
+        
+    def _getBrain(self, uid, queryBrainMethod):
+        brain = queryBrainMethod(uid, default=None)
+        if brain is None:
+            raise UniqueIdError, "No object found with '%s' as uid." % uid
+        return brain
+    
+    security.declarePublic('getBrain')
+    def getBrain(self, uid):
+        """See IUniqueIdBrainQuery.
+        """
+        return self._getBrain(uid, self.queryBrain)
+
+    security.declarePublic('getObject')
+    def getObject(self, uid):
+        """See IUniqueIdQuery.
+        """
+        return self.getBrain(uid).getObject()
+
+    security.declarePublic('queryObject')
+    def queryObject(self, uid, default=None):
+        """See IUniqueIdQuery.
+        """
+        try:
+            return self.getObject(uid)
+        except UniqueIdError:
+            return default
+    
+    security.declarePrivate('unrestrictedQueryBrain')
+    def unrestrictedQueryBrain(self, uid, default=None):
+        """See IUniqueIdUnrestrictedQuery.
+        """
+        return self._queryBrain(uid, 'unrestrictedSearchResults', default)
+        
+    security.declarePrivate('unrestrictedGetBrain')
+    def unrestrictedGetBrain(self, uid):
+        """See IUniqueIdUnrestrictedQuery.
+        """
+        return self._getBrain(uid, self.unrestrictedQueryBrain)
+        
+    security.declarePrivate('unrestrictedGetObject')
+    def unrestrictedGetObject(self, uid):
+        """See IUniqueIdUnrestrictedQuery.
+        """
+        return self.unrestrictedGetBrain(uid).getObject()
+    
+    security.declarePrivate('unrestrictedQueryObject')
+    def unrestrictedQueryObject(self, uid, default=None):
+        """See IUniqueIdUnrestrictedQuery.
+        """
+        try:
+            return self.unrestrictedGetObject(uid)
+        except UniqueIdError:
+            return default
+    
+InitializeClass(UniqueIdHandlerTool)

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/__init__.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/__init__.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/__init__.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/__init__.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,59 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Unique id generation and handling.
+
+$Id: __init__.py 37118 2005-07-07 16:52:34Z regebro $
+"""
+
+from sys import modules
+
+from Products.CMFCore import utils
+try:
+    from Products.CMFSetup import EXTENSION
+    from Products.CMFSetup import profile_registry
+    has_profile_registry = True
+except ImportError:
+    has_profile_registry = False
+
+import UniqueIdAnnotationTool
+import UniqueIdGeneratorTool
+import UniqueIdHandlerTool
+
+tools = (
+    UniqueIdAnnotationTool.UniqueIdAnnotationTool,
+    UniqueIdGeneratorTool.UniqueIdGeneratorTool,
+    UniqueIdHandlerTool.UniqueIdHandlerTool,
+)
+
+this_module = modules[ __name__ ]
+
+z_tool_bases = utils.initializeBasesPhase1(tools, this_module)
+
+my_globals=globals()
+
+def initialize(context):
+
+    utils.initializeBasesPhase2(z_tool_bases, context)
+
+    utils.ToolInit( 'CMF Unique Id Tool'
+                  , tools=tools
+                  , icon='tool.gif'
+                  ).initialize(context)
+
+    if has_profile_registry:
+        profile_registry.registerProfile('default',
+                                         'CMFUid',
+                                         'Adds UID support.',
+                                         'profiles/default',
+                                         'CMFUid',
+                                         EXTENSION)

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/changelog
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/changelog?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/changelog (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/changelog Thu Feb 15 18:15:44 2007
@@ -1,0 +1,6 @@
+erp5-cmfuid (1.5.4-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Yusei TAHARA <yusei at domen.cx>  Wed, 14 Feb 2007 03:27:56 +0900
+

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/compat
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/compat?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/compat (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/compat Thu Feb 15 18:15:44 2007
@@ -1,0 +1,1 @@
+5

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/control
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/control?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/control (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/control Thu Feb 15 18:15:44 2007
@@ -1,0 +1,13 @@
+Source: erp5-cmfuid
+Section: web
+Priority: optional
+Maintainer: Yusei TAHARA
+Build-Depends: debhelper (>= 5.0)
+Build-Depends-Indep: zope-debhelper (>= 0.3.6)
+Standards-Version: 3.7.2
+
+Package: erp5-cmfuid
+Architecture: all
+Depends: erp5-zope
+Description: CMFUid Product for Zope
+ This package provides CMFUid product for zope.

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/copyright
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/copyright?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/copyright (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/copyright Thu Feb 15 18:15:44 2007
@@ -1,0 +1,1 @@
+Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/dzproduct
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/dzproduct?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/dzproduct (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/dzproduct Thu Feb 15 18:15:44 2007
@@ -1,0 +1,3 @@
+Name: CMFUid
+Package: erp5-cmfuid
+ZopeVersions: >= 2.7

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/postinst
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/postinst?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/postinst (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/postinst Thu Feb 15 18:15:44 2007
@@ -1,0 +1,7 @@
+#!/bin/sh -e
+
+. /usr/share/debconf/confmodule
+
+#DEBHELPER#
+
+db_stop

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/rules
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/debian/rules?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/debian/rules (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/debian/rules Thu Feb 15 18:15:44 2007
@@ -1,0 +1,44 @@
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+pwd        := $(shell pwd)
+debian     := $(pwd)/debian/erp5-cmfuid
+
+build: build-stamp
+build-stamp:
+	touch build-stamp
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs
+	dh_installerp5zope .
+
+binary-indep: build install
+	dh_testdir
+	dh_testroot
+	dh_installdocs
+	dh_installexamples
+	dh_installchangelogs
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary-arch:
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary install

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/debian/rules
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/interfaces.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/interfaces.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/interfaces.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/interfaces.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,203 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Unique Id Generation and Handling
+
+These interfaces are intentionaly kept close to those from Zope3. Additionaly
+handling (IUniqueIdHandler) and generation (IUniqueIdGenerator) of unique ids 
+are kept separate.
+
+$Id: interfaces.py 36666 2004-11-18 10:38:51Z gregweb $
+"""
+
+from Interface import Interface, Attribute
+
+from Products.CMFCore.interfaces.IOpaqueItems \
+    import ICallableOpaqueItem, ICallableOpaqueItemEvents
+
+class UniqueIdError(Exception): pass
+
+
+class IUniqueIdGenerator(Interface):
+    """Generate a unique id.
+    """
+    
+    def __call__():
+        """Return a unique id value.
+        """
+
+    def convert(uid):
+        """Converts the unique id from string type to the appropriate
+           uid type.
+           
+        The resulting type has to be the same as the one '__call__'
+        returns.
+        """
+
+class IUniqueIdAnnotationManagement(Interface):
+    """Manage unique id annotations.
+    """
+    
+    def __call__(obj, id):
+        """Attach an unique id attribute of 'id' to the passed object.
+        
+        Return a unique id object implementing 'IUniqueIdAnnotation'.
+        """
+
+class IUniqueIdAnnotation(ICallableOpaqueItem, ICallableOpaqueItemEvents):
+    """Opaque unique id item handling adding, copying, and deletion events.
+    """
+    
+    def setUid(uid):
+        """Set the uid value the unique id annotation shall return.
+        """
+
+
+class IUniqueIdSet(Interface):
+    """(Un)register unique ids on objects.
+    """
+
+    def register(obj):
+        """Register the object and return the unique id generated for it.
+        
+        If the object is already registered, its unique id is returned 
+        anyway.
+        
+        UniqueIdError is raised if object can not be registered a unique id.
+        """
+
+    def unregister(obj):
+        """Remove the object from the indexes.
+        
+        UniqueIdError is raised if object was not registered previously.
+        """
+
+    def setUid(obj, uid, check_uniqueness=True):
+        """Set the unique id of an object.
+        
+        By default a check ensuring uniqueness is enabled. Be aware when
+        disabling this check: You really need to know what you do !!!
+        """
+
+
+class IUniqueIdQuery(Interface):
+    """Querying unique ids.
+    """
+    def queryUid(obj, default=None):
+        """Return the unique id of the object.
+        
+        If the object doesn't have a unique, the default value is returned.
+        """
+        
+    def getUid(obj):
+        """Return the unique id of the object.
+        
+        If the object doesn't have a unique, a UniqueIdError is raised.
+        """
+        
+    def queryObject(uid, default=None):
+        """Return the object with the given uid.
+        
+        If no object exist with the given unique id, the default value is 
+        returned.
+        """
+        
+    def getObject(uid):
+        """Return the object with the given uid.
+        
+        If no object exist with the given unique id, a UniqueIdError is raised.
+        """
+
+# This is the main API for playing with unique ids
+class IUniqueIdHandler(IUniqueIdSet, IUniqueIdQuery):
+    """Handle registering, querying unique ids and objects.
+    """
+
+# This is a secondary API enhancement
+class IUniqueIdBrainQuery(Interface):
+    """Querying unique ids returning brains for efficiency sake.
+    
+    Returning a brain is more efficient than returning the object.
+    A brain usually exposes only parts of the object and should only 
+    be read from. 
+    
+    If the implementing class doesn't support returning a catalog 
+    brain it may fallback to return the object. To be entirely
+    compatible it must implement the (non existing) interface 
+    catalog brains implement.
+    """
+    
+    def queryBrain(uid, default=None):
+        """Return the brain of object with the given uid.
+        
+        If no object exist with the given unique id, the default value
+        is returned.
+        """
+        
+    def getBrain(uid):
+        """Return a brain of the object with the given uid.
+        
+        If no object exist with the given unique id, a UniqueIdError 
+        is raised.
+        """
+
+# This is another secondary API enhancement
+class IUniqueIdUnrestrictedQuery(Interface):
+    """Querying unique ids unrestricted.
+    
+    The below methods return not yet effective and already expired 
+    objects regardless of the roles the caller has.
+    
+    CAUTION: Care must be taken not to open security holes by exposing 
+    the results of these methods to non authorized callers!
+        
+    If you're in doubth if you should use this method signature or
+    the restricted ones ('IUniqueIdQuery' and 'IUniqueIdBrainQuery') 
+    use the latter!
+    
+    Returning a brain is more efficient than returning the object.
+    A brain usually exposes only parts of the object and should only 
+    be read from. 
+    
+    If the implementing class doesn't support returning a catalog 
+    brain it may fallback to return the object. To be entirely
+    compatible it must implement the (non existing) interface 
+    catalog brains implement.
+    """
+    
+    def unrestrictedQueryObject(uid, default=None):
+        """Return the object with the given uid.
+        
+        If no object exist with the given unique id, the default value 
+        is returned.
+        """
+        
+    def unrestrictedGetObject(uid):
+        """Return a brain of the object with the given uid.
+        
+        If no object exist with the given unique id, a UniqueIdError 
+        is raised.
+        """
+
+    def unrestrictedQueryBrain(uid, default=None):
+        """Return the brain of the object with the given uid.
+        
+        If no object exist with the given unique id, the default value
+        is returned.
+        """
+        
+    def unrestrictedGetBrain(uid):
+        """Return a brain of the object with the given uid.
+        
+        If no object exist with the given unique id, a UniqueIdError 
+        is raised.
+        """

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/default/toolset.xml
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/default/toolset.xml?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/default/toolset.xml (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/profiles/default/toolset.xml Thu Feb 15 18:15:44 2007
@@ -1,0 +1,9 @@
+<?xml version="1.0"?>
+<tool-setup>
+ <required tool_id="portal_uidannotation"
+           class="Products.CMFUid.UniqueIdAnnotationTool.UniqueIdAnnotationTool"/>
+ <required tool_id="portal_uidgenerator"
+           class="Products.CMFUid.UniqueIdGeneratorTool.UniqueIdGeneratorTool"/>
+ <required tool_id="portal_uidhandler"
+           class="Products.CMFUid.UniqueIdHandlerTool.UniqueIdHandlerTool"/>
+</tool-setup>

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/__init__.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/tests/__init__.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/tests/__init__.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/tests/__init__.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,1 @@
+#

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/__init__.py
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_all.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_all.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_all.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_all.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,41 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+""" CMFCore tests.
+
+$Id: test_all.py 37135 2005-07-08 13:24:33Z tseaver $
+"""
+
+from unittest import main
+import Testing
+try:
+    import Zope2
+except ImportError: # BBB: for Zope 2.7
+    import Zope as Zope2
+Zope2.startup()
+
+from Products.CMFCore.tests.base.utils import build_test_suite
+
+
+def suite():
+    return build_test_suite('Products.CMFUid.tests',[
+        'test_uidannotation',
+        'test_uidgeneration',
+        'test_uidhandling',
+        ])
+
+def test_suite():
+    # Just to silence the top-level test.py
+    return None
+
+if __name__ == '__main__':
+    main(defaultTest='suite')

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_all.py
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidannotation.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidannotation.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidannotation.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidannotation.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,147 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Test the unique id annotation.
+
+$Id: test_uidannotation.py 37135 2005-07-08 13:24:33Z tseaver $
+"""
+
+from unittest import TestSuite, makeSuite, main
+import Testing
+try:
+    import Zope2
+except ImportError: # BBB: for Zope 2.7
+    import Zope as Zope2
+Zope2.startup()
+
+from Interface.Verify import verifyObject
+
+from Products.CMFCore.PortalFolder import PortalFolder
+from Products.CMFCore.tests.base.dummy import DummyContent
+from Products.CMFCore.tests.base.testcase import SecurityTest
+
+from Products.CMFUid.interfaces import IUniqueIdAnnotation
+from Products.CMFUid.interfaces import IUniqueIdAnnotationManagement
+
+
+UID_ATTRNAME = 'cmf_uid'
+
+class UniqueIdAnnotationTests(SecurityTest):
+
+    def setUp(self):
+        from Products.CMFUid.UniqueIdAnnotationTool \
+                import UniqueIdAnnotationTool
+
+        SecurityTest.setUp(self)
+        self.root._setObject('portal_uidannotation', UniqueIdAnnotationTool())
+        self.root._setObject('dummy', DummyContent(id='dummy'))
+
+    def test_interface(self):
+        dummy = self.root.dummy
+        anno_tool = self.root.portal_uidannotation
+        annotation = anno_tool(dummy, UID_ATTRNAME)
+
+        verifyObject(IUniqueIdAnnotationManagement, anno_tool)
+        verifyObject(IUniqueIdAnnotation, annotation)
+
+    def test_setAndGetUid(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        self.assertEqual(annotation(), None)
+        annotation.setUid(13)
+        self.assertEqual(annotation(), 13)
+
+    # copy/rename/add events: Just to remember
+    #
+    # add/import obj:
+    #   obj.manage_afterAdd(obj, obj, folder)
+    #
+    # move/rename obj:
+    #   obj.manage_beforeDelete(obj, obj, source_folder)
+    #   obj.manage_afterAdd(obj_at_target, obj_at_target, target_folder)
+    #
+    # copy and paste (clone) obj:
+    #   obj.manage_afterAdd(obj_at_target, obj_at_target, target_folder)
+    #   obj.manage_afterClone(obj_at_target, obj_at_target)
+
+    def test_simulateItemAddRemovingUid(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        annotation.__of__(dummy).manage_afterAdd(dummy, None)
+        self.assertRaises(AttributeError, getattr, dummy, UID_ATTRNAME)
+
+    def test_simulateItemAddDoesNotTouchUid(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        self.root.portal_uidannotation.remove_on_add = False
+        annotation.__of__(dummy).manage_afterAdd(dummy, None)
+        self.assertEqual(getattr(dummy, UID_ATTRNAME), annotation)
+
+    def test_simulateItemRename(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        annotation.__of__(dummy).manage_beforeDelete(dummy, None)
+        annotation.__of__(dummy).manage_afterAdd(dummy, None)
+        self.assertEqual(getattr(dummy, UID_ATTRNAME), annotation)
+
+    def test_simulateItemCloneRemovingUid1(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        annotation.__of__(dummy).manage_afterAdd(dummy, None)
+        annotation.__of__(dummy).manage_afterClone(dummy)
+        self.assertRaises(AttributeError, getattr, dummy, UID_ATTRNAME)
+
+    def test_simulateItemCloneRemovingUid2(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        self.root.portal_uidannotation.remove_on_add = False
+        annotation.__of__(dummy).manage_afterAdd(dummy, None)
+        annotation.__of__(dummy).manage_afterClone(dummy)
+        self.assertRaises(AttributeError, getattr, dummy, UID_ATTRNAME)
+
+    def test_simulateItemCloneDoesNotTouchUid(self):
+        dummy = self.root.dummy
+        annotation = self.root.portal_uidannotation(dummy, UID_ATTRNAME)
+
+        self.root.portal_uidannotation.remove_on_clone = False
+        annotation.__of__(dummy).manage_afterAdd(dummy, None)
+        annotation.__of__(dummy).manage_afterClone(dummy)
+        self.assertEqual(getattr(dummy, UID_ATTRNAME), annotation)
+
+    def test_simulateNestedFolderCloneRemovingUid1(self):
+        self.root._setObject( 'foo', PortalFolder(id='foo') )
+        foo = self.root.foo
+        foo._setObject( 'sub1', PortalFolder(id='sub1') )
+        foo.sub1._setObject( 'sub2', PortalFolder(id='sub2') )
+        foo.sub1.sub2._setObject( 'baz', DummyContent(id='baz', catalog=1) )
+        baz = foo.sub1.sub2.baz
+        annotation = self.root.portal_uidannotation(baz, UID_ATTRNAME)
+        self.assertEqual( getattr(baz, UID_ATTRNAME), annotation )
+
+        foo.manage_afterAdd(foo, None)
+        foo.manage_afterClone(foo)
+        self.assertRaises(AttributeError, getattr, baz, UID_ATTRNAME)
+
+
+def test_suite():
+    return TestSuite((
+        makeSuite(UniqueIdAnnotationTests),
+        ))
+
+if __name__ == '__main__':
+    main(defaultTest='test_suite')

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidannotation.py
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidgeneration.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidgeneration.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidgeneration.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidgeneration.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,79 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Test the unique id generation.
+
+$Id: test_uidgeneration.py 37148 2005-07-14 09:33:42Z gregweb $
+"""
+
+from unittest import TestCase, TestSuite, makeSuite, main
+import Testing
+try:
+    import Zope2
+except ImportError: # BBB: for Zope 2.7
+    import Zope as Zope2
+Zope2.startup()
+
+from BTrees.Length import Length
+from Interface.Verify import verifyObject
+
+from Products.CMFCore.tests.base.dummy import DummyContent
+
+from Products.CMFCore.tests.base.testcase import SecurityTest
+
+from Products.CMFUid.interfaces import IUniqueIdGenerator
+from Products.CMFUid.UniqueIdGeneratorTool import UniqueIdGeneratorTool
+
+
+class UniqueIdGeneratorTests(SecurityTest):
+
+    def setUp(self):
+        SecurityTest.setUp(self)
+        self.root._setObject('portal_uidgenerator', UniqueIdGeneratorTool())
+    
+    def test_interface(self):
+        generator = self.root.portal_uidgenerator
+        verifyObject(IUniqueIdGenerator, generator)
+        
+    def test_returnedUidsAreValidAndDifferent(self):
+        generator = self.root.portal_uidgenerator
+        uid1 = generator()
+        uid2 = generator()
+        self.failIfEqual(uid1, uid2)
+        self.failIfEqual(uid1, None)
+        
+    def test_converter(self):
+        generator = self.root.portal_uidgenerator
+        uid = generator()
+        str_uid = str(uid)
+        result = generator.convert(str_uid)
+        self.assertEqual(result, uid)
+        
+    def test_migrationFromBTreeLengthToInteger(self):
+        # For backwards compatibility with CMF 1.5.0 and 1.5.1, check if
+        # the generator correctly replaces a ``BTree.Length.Length`` object
+        # to an integer.
+        generator = self.root.portal_uidgenerator
+        uid1 = generator()
+        generator._uid_counter = Length(uid1)
+        self.failUnless(isinstance(generator._uid_counter, Length))
+        uid2 = generator()
+        self.failUnless(isinstance(generator._uid_counter, int))
+        self.failIfEqual(uid1, uid2)
+
+def test_suite():
+    return TestSuite((
+        makeSuite(UniqueIdGeneratorTests),
+        ))
+
+if __name__ == '__main__':
+    main(defaultTest='test_suite')

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidgeneration.py
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidhandling.py
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidhandling.py?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidhandling.py (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidhandling.py Thu Feb 15 18:15:44 2007
@@ -1,0 +1,241 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Test the unique id handling.
+
+$Id: test_uidhandling.py 37135 2005-07-08 13:24:33Z tseaver $
+"""
+
+from unittest import TestCase, TestSuite, makeSuite, main
+import Testing
+try:
+    import Zope2
+except ImportError: # BBB: for Zope 2.7
+    import Zope as Zope2
+Zope2.startup()
+
+from Interface.Verify import verifyObject
+
+from Products.CMFCore.tests.base.testcase import SecurityTest
+
+from Products.CMFCore.tests.base.dummy import DummyContent
+from Products.CMFCore.tests.base.dummy import DummyFolder
+from Products.CMFCore.tests.base.dummy import DummySite
+
+from Products.CMFCore.CatalogTool import CatalogTool
+
+from Products.CMFUid.interfaces import IUniqueIdHandler
+from Products.CMFUid.interfaces import IUniqueIdBrainQuery
+from Products.CMFUid.interfaces import IUniqueIdUnrestrictedQuery
+
+from Products.CMFUid.UniqueIdGeneratorTool import UniqueIdGeneratorTool
+from Products.CMFUid.UniqueIdAnnotationTool import UniqueIdAnnotationTool
+from Products.CMFUid.UniqueIdHandlerTool import UniqueIdHandlerTool
+
+def removeUnnecessaryIndexes(catalog):
+    indexes = [id[0] for id in catalog.enumerateIndexes()]
+    columns = catalog.enumerateColumns()
+    catalog.manage_delIndex(indexes)
+    catalog.manage_delColumn(columns)
+
+class DummyUid:
+    """A dummy uid that surely is of different type of the generated ones.
+    """
+    pass
+
+class UniqueIdHandlerTests(SecurityTest):
+
+    def setUp(self):
+        SecurityTest.setUp(self)
+        self.root._setObject('portal_catalog', CatalogTool())
+        self.root._setObject('portal_uidgenerator', UniqueIdGeneratorTool())
+        self.root._setObject('portal_uidannotation', UniqueIdAnnotationTool())
+        self.root._setObject('portal_uidhandler', UniqueIdHandlerTool())
+        self.root._setObject('dummy', DummyContent(id='dummy'))
+        self.root._setObject('dummy2', DummyContent(id='dummy2'))
+        
+        removeUnnecessaryIndexes(self.root.portal_catalog)
+    
+    def test_interface(self):
+        handler = self.root.portal_uidhandler
+        verifyObject(IUniqueIdHandler, handler)
+        verifyObject(IUniqueIdBrainQuery, handler)
+        verifyObject(IUniqueIdUnrestrictedQuery, handler)
+    
+    def test_getUidOfNotYetRegisteredObject(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        self.assertEqual(handler.queryUid(dummy, None), None)
+        self.assertRaises(UniqueIdError, handler.getUid, dummy)
+    
+    def test_getInvalidUid(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        self.assertEqual(handler.queryObject(100, None), None)
+        self.assertRaises(UniqueIdError, handler.getObject, 100)
+        self.assertEqual(handler.unrestrictedQueryObject(100, None), None)
+        self.assertRaises(UniqueIdError, handler.unrestrictedGetObject, 100)
+    
+        uid = handler.register(dummy)
+        self.assertEqual(handler.queryObject(uid+1, None), None)
+        self.assertRaises(UniqueIdError, handler.getObject, uid+1)
+        self.assertEqual(handler.unrestrictedQueryObject(uid+1, None), None)
+        self.assertRaises(UniqueIdError, handler.unrestrictedGetObject, uid+1)
+    
+    def test_getUidOfRegisteredObject(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        
+        uid = handler.register(dummy)
+        self.assertEqual(handler.getUid(dummy), uid)
+    
+    def test_getRegisteredObjectByUid(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        
+        uid = handler.register(dummy)
+        self.assertEqual(handler.getObject(uid), dummy)
+        self.assertEqual(handler.unrestrictedGetObject(uid), dummy)
+    
+    def test_getUnregisteredObject(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        uid = handler.register(dummy)
+        handler.unregister(dummy)
+        self.assertEqual(handler.queryObject(uid, None), None)
+        self.assertRaises(UniqueIdError, handler.getObject, uid)
+        self.assertEqual(handler.unrestrictedQueryObject(uid, None), None)
+        self.assertRaises(UniqueIdError, handler.unrestrictedGetObject, uid)
+
+    def test_getUidOfUnregisteredObject(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        uid = handler.register(dummy)
+        handler.unregister(dummy)
+        self.assertEqual(handler.queryUid(dummy, None), None)
+        self.assertRaises(UniqueIdError, handler.getUid, dummy)
+
+    def test_reregisterObject(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        
+        uid1_reg = handler.register(dummy)
+        uid1_get = handler.getUid(dummy)
+        uid2_reg = handler.register(dummy)
+        uid2_get = handler.getUid(dummy)
+        self.assertEqual(uid1_reg, uid2_reg)
+        self.assertEqual(uid1_get, uid2_get)
+        self.assertEqual(uid1_reg, uid1_get)
+    
+    def test_unregisterObjectWithoutUid(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        self.assertRaises(UniqueIdError, handler.unregister, dummy)
+
+    def test_setNewUidByHandWithCheck(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        
+        # registering and unregisterung a object just to get a free uid
+        unused_uid = handler.register(dummy)
+        handler.unregister(dummy)
+        
+        handler.setUid(dummy, unused_uid)
+        
+        result = handler.getUid(dummy)
+        self.assertEqual(unused_uid, result)
+        
+    def test_setSameUidOnSameObjectWithCheck(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        
+        uid = handler.register(dummy)
+        
+        # just setting the same uid another time is allowed
+        handler.setUid(dummy, uid)
+        
+        result = handler.getUid(dummy)
+        self.assertEqual(uid, result)
+        
+    def test_setExistingUidOnDifferentObjectWithCheckRaisesException(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        dummy2 = self.root.dummy2
+        UniqueIdError = handler.UniqueIdError
+        
+        # registering and unregisterung a object just to get a free uid
+        uid1_reg = handler.register(dummy)
+        uid2_reg = handler.register(dummy2)
+        
+        self.assertRaises(UniqueIdError, handler.setUid, dummy2, uid1_reg)
+
+    def test_setExistingUidOnDifferentObjectWithoutCheck(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        dummy2 = self.root.dummy2
+        UniqueIdError = handler.UniqueIdError
+        
+        # registering and unregisterung a object just to get a free uid
+        uid1_reg = handler.register(dummy)
+        uid2_reg = handler.register(dummy2)
+        
+        # now lets double the unique id
+        handler.setUid(dummy2, uid1_reg, check_uniqueness=False)
+        
+        # calling a getter returns one object and generates a log
+        # we can't capture. So let's ask the catalog directly.
+        catalog = self.root.portal_catalog
+        result = catalog({handler.UID_ATTRIBUTE_NAME: uid1_reg})
+        self.assertEqual(len(result), 2)
+        
+        # dummy2 shall not be reachable anymore by uid2_reg
+        self.assertRaises(UniqueIdError, handler.getBrain, uid2_reg)
+
+    def test_setNoneAsUidRaisesException(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        uid = handler.register(dummy)
+        
+        self.assertRaises(UniqueIdError, handler.setUid, dummy, None)
+
+    def test_setArbitraryKindOfUidRaisesException(self):
+        handler = self.root.portal_uidhandler
+        dummy = self.root.dummy
+        UniqueIdError = handler.UniqueIdError
+        
+        uid = handler.register(dummy)
+        
+        # As we don't know what kind of exception the implementation
+        # throws lets check for all exceptions! 
+        # IMHO it makes sense here to catch exceptions in general here!
+        self.assertRaises(Exception, handler.setUid, dummy, DummyUid())
+        
+
+def test_suite():
+    return TestSuite((
+        makeSuite(UniqueIdHandlerTests),
+        ))
+
+if __name__ == '__main__':
+    main(defaultTest='test_suite')

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/tests/test_uidhandling.py
------------------------------------------------------------------------------
    svn:executable = 

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/tool.gif
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/tool.gif?rev=12767&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-cmfuid/CMFUid/tool.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-cmfuid/CMFUid/version.txt
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/CMFUid/version.txt?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/CMFUid/version.txt (added)
+++ spec/debian/unstable/erp5-cmfuid/CMFUid/version.txt Thu Feb 15 18:15:44 2007
@@ -1,0 +1,1 @@
+CMF-1.5.4

Added: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.diff.gz
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.diff.gz?rev=12767&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.diff.gz
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.dsc
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.dsc?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.dsc (added)
+++ spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1.dsc Thu Feb 15 18:15:44 2007
@@ -1,0 +1,12 @@
+Format: 1.0
+Source: erp5-cmfuid
+Version: 1.5.4-1
+Binary: erp5-cmfuid
+Maintainer: Yusei TAHARA
+Architecture: all
+Standards-Version: 3.7.2
+Build-Depends: debhelper (>= 5.0)
+Build-Depends-Indep: zope-debhelper (>= 0.3.6)
+Files: 
+ d270c6ea388c966f3d0711db49918844 9327 erp5-cmfuid_1.5.4.orig.tar.gz
+ 872583f51f18c9cf76ca288c2b3fc4ea 898 erp5-cmfuid_1.5.4-1.diff.gz

Added: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_all.deb
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_all.deb?rev=12767&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_all.deb
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.build
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.build?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.build (added)
+++ spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.build Thu Feb 15 18:15:44 2007
@@ -1,0 +1,34 @@
+ fakeroot debian/rules clean
+dh_testdir
+dh_testroot
+rm -f build-stamp configure-stamp
+dh_clean
+ dpkg-source -b CMFUid
+dpkg-source: warning: source directory `./CMFUid' is not <sourcepackage>-<upstreamversion> `erp5-cmfuid-1.5.4'
+dpkg-source: warning: .orig directory name CMFUid.orig is not <package>-<upstreamversion> (wanted erp5-cmfuid-1.5.4.orig)
+dpkg-source: building erp5-cmfuid using existing erp5-cmfuid_1.5.4.orig.tar.gz
+dpkg-source: building erp5-cmfuid in erp5-cmfuid_1.5.4-1.diff.gz
+dpkg-source: building erp5-cmfuid in erp5-cmfuid_1.5.4-1.dsc
+ debian/rules build
+touch build-stamp
+ fakeroot debian/rules binary
+dh_testdir
+dh_testroot
+dh_clean -k
+dh_installdirs
+dh_installerp5zope .
+dh_testdir
+dh_testroot
+dh_installdocs
+dh_installexamples
+dh_installchangelogs
+dh_compress
+dh_fixperms
+dh_installdeb
+dh_gencontrol
+dh_md5sums
+dh_builddeb
+dpkg-deb: `../erp5-cmfuid_1.5.4-1_all.deb' ¤Ë¥Ñ¥Ã¥±¡¼¥¸ `erp5-cmfuid' ¤ò¹½ÃÛ¤·¤Æ¤¤¤Þ¤¹¡£
+ dpkg-genchanges
+dpkg-genchanges: including full source code in upload
+dpkg-buildpackage (debuild emulation): full upload (original source is included)

Added: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.changes
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.changes?rev=12767&view=auto
==============================================================================
--- spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.changes (added)
+++ spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4-1_i386.changes Thu Feb 15 18:15:44 2007
@@ -1,0 +1,21 @@
+Format: 1.7
+Date: Wed, 14 Feb 2007 03:27:56 +0900
+Source: erp5-cmfuid
+Binary: erp5-cmfuid
+Architecture: source all
+Version: 1.5.4-1
+Distribution: unstable
+Urgency: low
+Maintainer: Yusei TAHARA
+Changed-By: Yusei TAHARA <yusei at domen.cx>
+Description: 
+ erp5-cmfuid - CMFUid Product for Zope
+Changes: 
+ erp5-cmfuid (1.5.4-1) unstable; urgency=low
+ .
+   * Initial Release.
+Files: 
+ f7255b014279967033c1ff39ceac1519 361 web optional erp5-cmfuid_1.5.4-1.dsc
+ d270c6ea388c966f3d0711db49918844 9327 web optional erp5-cmfuid_1.5.4.orig.tar.gz
+ 872583f51f18c9cf76ca288c2b3fc4ea 898 web optional erp5-cmfuid_1.5.4-1.diff.gz
+ a799841a5e597440bf1caaa93df9e51f 11526 web optional erp5-cmfuid_1.5.4-1_all.deb

Added: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4.orig.tar.gz
URL: http://svn.erp5.org/spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4.orig.tar.gz?rev=12767&view=auto
==============================================================================
Binary file - no diff available.

Propchange: spec/debian/unstable/erp5-cmfuid/erp5-cmfuid_1.5.4.orig.tar.gz
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream




More information about the Erp5-report mailing list