r13305 - in Products.Relations: branches/4.0-compatibility trunk trunk/Products/Relations trunk/Products/Relations/components trunk/Products/Relations/profiles/default trunk/Products/Relations/tests trunk/docs

"Eric Steele" <[email protected]>
Newsgroups gmane.comp.web.zope.plone.archetypes.cvs
Message-ID <[email protected]>
Author: esteele
Date: Tue Nov 30 20:49:36 2010
New Revision: 13305

Removed:
   Products.Relations/branches/4.0-compatibility/
Modified:
   Products.Relations/trunk/   (props changed)
   Products.Relations/trunk/Products/Relations/__init__.py
   Products.Relations/trunk/Products/Relations/brain.py
   Products.Relations/trunk/Products/Relations/components/cardinality.py
   Products.Relations/trunk/Products/Relations/components/contentreference.py
   Products.Relations/trunk/Products/Relations/components/inverse.py
   Products.Relations/trunk/Products/Relations/components/types.py
   Products.Relations/trunk/Products/Relations/field.py
   Products.Relations/trunk/Products/Relations/interfaces.py
   Products.Relations/trunk/Products/Relations/processor.py
   Products.Relations/trunk/Products/Relations/profiles/default/controlpanel.xml
   Products.Relations/trunk/Products/Relations/ruleset.py
   Products.Relations/trunk/Products/Relations/tests/common.py
   Products.Relations/trunk/Products/Relations/tests/testBrain.py
   Products.Relations/trunk/Products/Relations/tests/testComponents.py
   Products.Relations/trunk/Products/Relations/tests/testRuleset.py
   Products.Relations/trunk/Products/Relations/utils.py
   Products.Relations/trunk/docs/HISTORY.txt
   Products.Relations/trunk/setup.py
Log:
Merge 4.0-compatibility branch.

Modified: Products.Relations/trunk/Products/Relations/__init__.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/__init__.py	(original)
+++ Products.Relations/trunk/Products/Relations/__init__.py	Tue Nov 30 20:49:36 2010
@@ -7,6 +7,13 @@
 from Products.CMFCore.DirectoryView import registerDirectory
 registerDirectory(SKINS_DIR, GLOBALS)
 
+# BBB for Z2 vs Z3 interfaces checks, borrowed from Products.PloneFormGen
+def implementedOrProvidedBy(anInterface, anObject):
+    try:
+        return anInterface.providedBy(anObject)
+    except AttributeError:
+        return anInterface.isImplementedBy(anObject)
+
 def initialize(context):
     import ruleset
     import components
@@ -25,3 +32,4 @@
 
 import brain, exception, processor, utils # contain ModuleSecurityInfo
 import field # registers field
+

Modified: Products.Relations/trunk/Products/Relations/brain.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/brain.py	(original)
+++ Products.Relations/trunk/Products/Relations/brain.py	Tue Nov 30 20:49:36 2010
@@ -1,13 +1,16 @@
 from AccessControl import ModuleSecurityInfo
 from Acquisition import aq_base
 from Globals import InitializeClass
-from Products.CMFCore.utils import getToolByName
 from Products.Archetypes.ReferenceEngine import Reference
 from Products.Archetypes.utils import shasattr
+from Products.CMFCore.utils import getToolByName
+from zope.interface import implements
+
+from Products.Relations import implementedOrProvidedBy
+from Products.Relations.interfaces import IBrainAggregate, IReferenceWithBrains
+from zope.interface import classImplements
 
-from config import *
-import brain
-import interfaces
+from Products.Relations.config import *
 
 modulesec = ModuleSecurityInfo('Products.Relations.brain')
 modulesec.declarePublic('makeBrainAggregate')
@@ -18,7 +21,7 @@
     """Catalog brain kind of object that aggregates metadata from multiple
     catalogs."""
 
-    __implements__ = interfaces.IBrainAggregate,
+    implements(IBrainAggregate,)
     __allow_access_to_unprotected_subobjects__ = 1
 
     def __init__(self, brain, sources):
@@ -44,7 +47,7 @@
                (self.brain.UID, self.brain.getPath())
 
     def __eq__(self, other):
-        if interfaces.IBrainAggregate.isImplementedBy(other):
+        if implementedOrProvidedBy(IBrainAggregate, other):
             return self.brain.UID == other.brain.UID and \
                    self.sources == other.sources
 
@@ -54,7 +57,7 @@
     obj may be either a UID string, a brain of uid_catalog or an aggregated
     brain."""
 
-    if interfaces.IBrainAggregate.isImplementedBy(obj):
+    if implementedOrProvidedBy(IBrainAggregate, obj):
         return obj
     elif isinstance(obj, type('')): # assume a UID
         return makeBrainAggrFromUID(context, obj)
@@ -95,17 +98,22 @@
     return aggr
 
 class ReferenceWithBrains(Reference):
-    __implements__ = interfaces.IReferenceWithBrains
+    pass
+    
+try:
+    classImplements(ReferenceWithBrains, IReferenceWithBrains)
+except TypeError:
+    ReferenceWithBrains.__implements__ = (IReferenceWithBrains,)
 
-# These proxy methods all make use of a volatile attribute to store their value
+# # These proxy methods all make use of a volatile attribute to store their value
 # The dict maps method names, e.g. 'getSourceBrain', to functions that produce
 # the value.
 proxies = {
     'getSourceBrain':
-    lambda self: brain.makeBrainAggregate(self, self.sourceUID),
+    lambda self: makeBrainAggregate(self, self.sourceUID),
            
     'getTargetBrain':
-    lambda self: brain.makeBrainAggregate(self, self.targetUID),
+    lambda self: makeBrainAggregate(self, self.targetUID),
 
     'getSourceObject':
     lambda self: Reference.getSourceObject(self),

Modified: Products.Relations/trunk/Products/Relations/components/cardinality.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/components/cardinality.py	(original)
+++ Products.Relations/trunk/Products/Relations/components/cardinality.py	Tue Nov 30 20:49:36 2010
@@ -7,11 +7,18 @@
 from Products.Relations.config import *
 from Products.Relations.schema import BaseSchemaWithInvisibleId
 
+# Maybe some day we will get consistency on how implements works
+# so that we don't have to do this - cwarner
+from zope.interface import implements
+from Products.Archetypes.interfaces import IBaseContent
+from Products.Archetypes.interfaces import IReferenceable
+from Products.Archetypes.interfaces import IExtensibleMetadata
+
+
 class CardinalityConstraint(BaseContent, ruleset.RuleBase):
     """An IValidator and IReferenceLayerProvider that enforces cardinality."""
-    __implements__ = BaseContent.__implements__ + \
-                     (interfaces.IValidator,
-                      interfaces.IReferenceLayerProvider)
+    implements(IBaseContent, IReferenceable, IExtensibleMetadata, interfaces.IValidator,
+               interfaces.IReferenceLayerProvider)
 
     content_icon = 'cardinalityconstraint_icon.gif'
 
@@ -96,11 +103,11 @@
         ))
     portal_type = 'Cardinality Constraint'
 
-registerType(CardinalityConstraint)
+registerType(CardinalityConstraint, PROJECTNAME)
 
 
 class CardinalityReferenceLayer:
-    __implements__ = interfaces.IReferenceLayerProvider,
+    implements(interfaces.IReferenceLayerProvider,)
 
     def __init__(self, ruleset, cc):
         self.ruleset = ruleset

Modified: Products.Relations/trunk/Products/Relations/components/contentreference.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/components/contentreference.py	(original)
+++ Products.Relations/trunk/Products/Relations/components/contentreference.py	Tue Nov 30 20:49:36 2010
@@ -11,6 +11,16 @@
 from Products.Archetypes.ReferenceEngine import Reference
 from Products.Archetypes.interfaces.referenceengine \
      import IContentReference as IATContentReference
+from Products.Archetypes.interfaces import IReference
+
+# Maybe some day we will get consistency on how implements works
+# so that we don't have to do this - cwarner
+from zope.interface import implements
+from zope.interface import classImplements
+from Products.Archetypes.interfaces import IBaseContent
+from Products.Archetypes.interfaces import IReferenceable
+from Products.Archetypes.interfaces import IExtensibleMetadata
+
 from Products.Archetypes.utils import getRelPath, getRelURL
 
 from Products.Relations.config import *
@@ -33,7 +43,6 @@
 
     Note that portal objects associated with this reference are identified
     by a reference, not by containment."""
-    __implements__ = Reference.__implements__ + (IContentReference,)
     
     portal_type = meta_type = "Relation ContentReference"
     
@@ -70,6 +79,11 @@
 
 InitializeClass(ContentReference)
 
+try:
+    classImplements(ContentReference, IContentReference)    
+except TypeError:
+    ContentReference.__implements__ = (IContentReference)
+
 
 def _makeKey(relationship, sUID, tUID, portal_type):
     return "relationship: %s\n" % relationship + \
@@ -92,9 +106,8 @@
     References that I create conform to this module's
     IContentReference, which derives from
     Archetypes.interfaces.referenceengine.IContentReference."""
-    __implements__ = (interfaces.IPrimaryImplicator, interfaces.IFinalizer,
-                      interfaces.IReferenceActionProvider) + \
-                     BaseContent.__implements__
+    implements(interfaces.IPrimaryImplicator, interfaces.IFinalizer, interfaces.IReferenceActionProvider,
+               IBaseContent, IReferenceable, IExtensibleMetadata)
 
     def connect(self, source, target, metadata=None):
         impl = ruleset.DefaultPrimaryImplicator(self.getRuleset())
@@ -213,4 +226,4 @@
         return DisplayList(
             [(pt, pt) for pt in utils.getReferenceableTypes(self)])
 
-registerType(ContentReferenceFinalizer)
+registerType(ContentReferenceFinalizer, PROJECTNAME)

Modified: Products.Relations/trunk/Products/Relations/components/inverse.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/components/inverse.py	(original)
+++ Products.Relations/trunk/Products/Relations/components/inverse.py	Tue Nov 30 20:49:36 2010
@@ -8,12 +8,19 @@
 from Products.Relations import interfaces, ruleset, utils
 from Products.Relations.schema import BaseSchemaWithInvisibleId
 
+# Maybe some day we will get consistency on how implements works
+# so that we don't have to do this - cwarner
+from zope.interface import implements
+from Products.Archetypes.interfaces import IBaseContent
+from Products.Archetypes.interfaces import IReferenceable
+from Products.Archetypes.interfaces import IExtensibleMetadata
+
 _invref_attr = '_relations_invref_uid'
 _proc_marker_attr = '_v_relations_process_invref'
 
 class InverseImplicator(BaseContent, ruleset.RuleBase):
     """Implicator that creates a reference from target to source."""
-    __implements__ = (interfaces.IImplicator,) + BaseContent.__implements__
+    implements(interfaces.IImplicator, IBaseContent, IReferenceable, IExtensibleMetadata)
 
     content_icon = 'inverseimplicator_icon.gif'
 
@@ -67,8 +74,7 @@
         else:
             return None
 
-registerType(InverseImplicator)
-                       
+registerType(InverseImplicator, PROJECTNAME)                       
         
 
     

Modified: Products.Relations/trunk/Products/Relations/components/types.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/components/types.py	(original)
+++ Products.Relations/trunk/Products/Relations/components/types.py	Tue Nov 30 20:49:36 2010
@@ -7,11 +7,19 @@
 from Products.Relations.config import *
 from Products.Relations.schema import BaseSchemaWithInvisibleId
 
+# Maybe some day we will get consistency on how implements works
+# so that we don't have to do this - cwarner
+from zope.interface import implements
+from Products.Archetypes.interfaces import IBaseContent
+from Products.Archetypes.interfaces import IReferenceable
+from Products.Archetypes.interfaces import IExtensibleMetadata
+
+
 class PortalTypeConstraint(BaseContent, ruleset.RuleBase):
     """A validator and vocabulary provider, restricting sources and targets
     by portal type."""
-    __implements__ = (interfaces.IVocabularyProvider, interfaces.IValidator) +\
-                     BaseContent.__implements__
+    implements(interfaces.IVocabularyProvider, interfaces.IValidator,
+            IBaseContent, IReferenceable, IExtensibleMetadata)
 
     content_icon = 'portaltypeconstraint_icon.gif'
 
@@ -86,7 +94,7 @@
         return DisplayList(
             [(pt, pt) for pt in utils.getReferenceableTypes(self)])
 
-registerType(PortalTypeConstraint)
+registerType(PortalTypeConstraint, PROJECTNAME)
 
 class InterfaceConstraint(PortalTypeConstraint):
     """A validator and vocabulary provider, restricting sources and targets
@@ -129,6 +137,5 @@
         ))
     archetype_name = portal_type = 'Interface Constraint'
 
-registerType(InterfaceConstraint)
-
+registerType(InterfaceConstraint, PROJECTNAME)
     

Modified: Products.Relations/trunk/Products/Relations/field.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/field.py	(original)
+++ Products.Relations/trunk/Products/Relations/field.py	Tue Nov 30 20:49:36 2010
@@ -12,10 +12,7 @@
 from Products.Archetypes.utils import DisplayList
 from Products.Archetypes import config as atconfig
 
-try:
-    from Products.generator import i18n
-except ImportError:
-    from Products.Archetypes.generator import i18n
+from zope import i18n
 
 from config import RELATIONS_LIBRARY
 import processor

Modified: Products.Relations/trunk/Products/Relations/interfaces.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/interfaces.py	(original)
+++ Products.Relations/trunk/Products/Relations/interfaces.py	Tue Nov 30 20:49:36 2010
@@ -7,7 +7,7 @@
 on an object.
 """
 
-from Interface import Interface, Attribute
+from zope.interface import Interface, Attribute
 from Products.Archetypes.interfaces.referenceengine import IReference
 
 

Modified: Products.Relations/trunk/Products/Relations/processor.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/processor.py	(original)
+++ Products.Relations/trunk/Products/Relations/processor.py	Tue Nov 30 20:49:36 2010
@@ -10,11 +10,12 @@
 from events import RelationConnectedEvent
 from events import RelationDisconnectedEvent
 from zope.event import notify
+from zope.interface import implements, classImplements
 
 modulesec = ModuleSecurityInfo('Products.Relations.processor')
 
 class Chain(dict):
-    __implements__ = interfaces.IChain,
+    implements(interfaces.IChain)
     
     def __init__(self):
         self.added = []
@@ -25,10 +26,11 @@
             self[key] = {}
         return dict.__getitem__(self, key)
 
-
-
 # module implements the interface
-__implements__ = interfaces.IReferenceConnectionProcessor,
+try:
+    classImplements(Chain, interfaces.IReferenceConnectionProcessor)
+except TypeError:
+    Chain.__implements__ = (interfaces.IReferenceConnectionProcessor,)
 
 modulesec.declarePublic('process')
 def process(context, connect=(), disconnect=()):

Modified: Products.Relations/trunk/Products/Relations/profiles/default/controlpanel.xml
==============================================================================
--- Products.Relations/trunk/Products/Relations/profiles/default/controlpanel.xml	(original)
+++ Products.Relations/trunk/Products/Relations/profiles/default/controlpanel.xml	Tue Nov 30 20:49:36 2010
@@ -3,7 +3,9 @@
     i18n:domain="Relations">
  <configlet title="Relations: Library" action_id="relations_library"
     appId="Products.Relations" category="Products" condition_expr=""
-    url_expr="string:${portal_url}/relations_library/" visible="True" i18n:attributes="title">
+    url_expr="string:${portal_url}/relations_library/" visible="True"
+    icon_expr="string:$portal_url/book_icon.gif"
+    i18n:attributes="title">
   <permission>Manage portal</permission>
  </configlet>
 </object>

Modified: Products.Relations/trunk/Products/Relations/ruleset.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/ruleset.py	(original)
+++ Products.Relations/trunk/Products/Relations/ruleset.py	Tue Nov 30 20:49:36 2010
@@ -9,6 +9,7 @@
 from Products import CMFCore
 from Products.CMFCore.utils import getToolByName
 from Products.CMFCore.Expression import Expression
+from Products.CMFCore.interfaces import IDynamicType
 from Products.Archetypes.interfaces.referenceable import IReferenceable
 from Products.Archetypes.Referenceable import Referenceable
 from Products.Archetypes.ReferenceEngine import Reference
@@ -16,19 +17,23 @@
 from Products.Archetypes.public import *
 from Products.Archetypes.exceptions import ReferenceException
 from Products.Relations.permissions import ManageContentRelations
+from Products.Relations import implementedOrProvidedBy
+from zope.interface import implements
 from config import *
 import interfaces
 import brain
 import schema
 import utils
+from zope.interface import implements
 
 import logging
 logger = logging.getLogger('Relations')
 
 
 class XMLImportExport:
-    __implements__ = interfaces.IXMLImportExport,
+    implements(interfaces.IXMLImportExport)
 
+    
     schema=Schema((
         StringField('xml',
                     mutator='importXML',
@@ -216,13 +221,13 @@
     pass
 
 class RuleBase(XMLImportExport):
-    __implements__ = interfaces.IRule,
+    implements(interfaces.IRule,)
 
     global_allow = 0 # convenience
     def getRuleset(self): return aq_parent(aq_inner(self))
 
 class DefaultPrimaryImplicator(RuleBase):
-    __implements__ = interfaces.IPrimaryImplicator,
+    implements(interfaces.IPrimaryImplicator,)
 
     referenceClass = RLMWithBrains
 
@@ -249,8 +254,7 @@
         
 class Ruleset(utils.AllowedTypesByIface, OrderedBaseFolder, XMLImportExport):
     """See IRuleset."""
-    __implements__ = (interfaces.IRuleset,) +\
-                     OrderedBaseFolder.__implements__
+    implements(interfaces.IRuleset, IDynamicType)
 
     schema = schema.RulesetSchema
     portal_type = archetype_name = 'Ruleset'
@@ -265,7 +269,7 @@
         """Return a list of objects in self that implement the given
         interface."""
         return [obj for obj in self.objectValues()
-                if interface.isImplementedBy(obj)]
+                if implementedOrProvidedBy(interface,obj)]
 
     def implyOnConnect(self, source, target, chain, metadata=None):
         primaryImplicator = self._getPrimaryImplicator()
@@ -342,7 +346,7 @@
             url = getRelURL(aq_parent(aq_inner(ref)), ref.getPhysicalPath())
             ref_ctl.catalog_object(ref, url, idxs=['relationship'])
 
-registerType(Ruleset)
+registerType(Ruleset, PROJECTNAME)
 
 
 class RulesetAwareContainer:
@@ -361,19 +365,19 @@
         v = super_invokeFactory(self, type_name, id, RESPONSE, *args, **kwargs)
 
         obj = getattr(self, v)
-        if interfaces.IRuleset.isImplementedBy(obj):
+        if implementedOrProvidedBy(interfaces.IRuleset, obj):
 
             library.addReference(obj, RELATIONSHIP_LIBRARY)
         return v
 
     # This hack allows us to inform the ruleset that it has been renamed.
-    def _setObject(self, id, obj, roles=None, user=None, set_owner=1):
+    def _setObject(self, id, obj, roles=None, user=None, set_owner=1, suppress_events=True):
         library = getToolByName(self, RELATIONS_LIBRARY)
         
         super_setObject = OrderedBaseFolder._setObject
         super_setObject(self, id, obj, roles, user, set_owner)
 
-        if interfaces.IRuleset.isImplementedBy(obj):
+        if implementedOrProvidedBy(interfaces.IRuleset, obj):
             ruleset = obj
             ref_ctl = getToolByName(self, REFERENCE_CATALOG)
             brains = ref_ctl(sourceUID=library.UID(),
@@ -388,9 +392,7 @@
 class Library(RulesetAwareContainer, utils.AllowedTypesByIface,
               OrderedBaseFolder, XMLImportExport):
     """Registry for IRulesets. See ILibrary."""
-    __implements__ = ((interfaces.ILibrary,) +
-                      (OrderedBaseFolder.__implements__, ))
-                      
+    implements(interfaces.ILibrary, IDynamicType)
 
     schema = schema.BaseSchemaWithInvisibleId + XMLImportExport.schema
     portal_type = archetype_name = 'Relations Library'
@@ -452,14 +454,13 @@
     def getFolder(self):
         return self
 
-registerType(Library)
+registerType(Library, PROJECTNAME)
 
 
 class RulesetCollection(RulesetAwareContainer, utils.AllowedTypesByIface,
                         OrderedBaseFolder, XMLImportExport):
     """A container for IRulesets that lives inside the library."""
-    __implements__ = (interfaces.IRulesetCollection,) + \
-                     OrderedBaseFolder.__implements__
+    implements(interfaces.IRulesetCollection, IDynamicType)
 
     schema = schema.BaseSchemaWithInvisibleId + XMLImportExport.schema
     portal_type = archetype_name = 'Ruleset Collection'
@@ -472,4 +473,4 @@
             v = v + collection.getRulesets()
         return v
 
-registerType(RulesetCollection)
+registerType(RulesetCollection, PROJECTNAME)

Modified: Products.Relations/trunk/Products/Relations/tests/common.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/tests/common.py	(original)
+++ Products.Relations/trunk/Products/Relations/tests/common.py	Tue Nov 30 20:49:36 2010
@@ -19,7 +19,8 @@
     from Products.Archetypes.tests import attestcase
     
     installProducts()
-    PloneTestCase.setupPloneSite(products=product_dependencies)
+    PloneTestCase.setupPloneSite(products=product_dependencies, 
+        extension_profiles=('Products.Archetypes:Archetypes_sampletypes',))
 
 def createObjects(testcase, names):
     """Given a testname and a list of portal types "names", I will create

Modified: Products.Relations/trunk/Products/Relations/tests/testBrain.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/tests/testBrain.py	(original)
+++ Products.Relations/trunk/Products/Relations/tests/testBrain.py	Tue Nov 30 20:49:36 2010
@@ -4,7 +4,7 @@
 
 from Products.PloneTestCase import PloneTestCase
 
-from Interface.Verify import verifyObject
+from zope.interface.verify import verifyObject
 
 import Products.Relations.interfaces as interfaces
 import Products.Relations.brain as brain

Modified: Products.Relations/trunk/Products/Relations/tests/testComponents.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/tests/testComponents.py	(original)
+++ Products.Relations/trunk/Products/Relations/tests/testComponents.py	Tue Nov 30 20:49:36 2010
@@ -9,7 +9,7 @@
 
 from Products.Relations.config import *
 from Products.Relations import brain, exception, processor
-
+from Products.Relations import implementedOrProvidedBy
 import common
 common.installWithinPortal()
 
@@ -111,7 +111,7 @@
         # make list
         brains = self.ic.makeVocabulary(self.brains[0], None)
         for obj in [b.getObject() for b in brains]:
-            self.assert_(IBaseFolder.isImplementedBy(obj))
+            self.assert_(implementedOrProvidedBy(IBaseFolder, obj))
 
         # disallowed source interface
         self.ic.setAllowedSourceInterfaces(['IFooBar'])
@@ -123,7 +123,7 @@
         self.ic.setAllowedSourceInterfaces(['IReferenceable', 'IBaseFolder'])
         brains = self.ic.makeVocabulary(self.brains[0], None)
         for obj in [b.getObject() for b in brains]:
-            self.assert_(IBaseFolder.isImplementedBy(obj))
+            self.assert_(implementedOrProvidedBy(IBaseFolder, obj))
 
     def testValidateConnected(self):
         triples = (self.brains[0].UID, self.brains[1].UID,
@@ -401,8 +401,8 @@
         r2 = self.reflookup(tUID, sUID, self.ruleset2.getId())
 
         # Make sure both are of type IContentReference
-        self.assert_(contentreference.IContentReference.isImplementedBy(r1))
-        self.assert_(contentreference.IContentReference.isImplementedBy(r2))
+        self.assert_(implementedOrProvidedBy(contentreference.IContentReference, r1))
+        self.assert_(implementedOrProvidedBy(contentreference.IContentReference, r2))
 
         self.assertEquals(r1.getContentObject(), r2.getContentObject())
 

Modified: Products.Relations/trunk/Products/Relations/tests/testRuleset.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/tests/testRuleset.py	(original)
+++ Products.Relations/trunk/Products/Relations/tests/testRuleset.py	Tue Nov 30 20:49:36 2010
@@ -15,6 +15,10 @@
 import Products.Relations.brain as brain
 import Products.Relations.ruleset as rulesetmodule
 import Products.Relations.processor as processor
+from Products.Relations import implementedOrProvidedBy
+from zope.interface import implements
+
+from AccessControl import Unauthorized
 
 import common
 common.installWithinPortal()
@@ -64,7 +68,7 @@
         lib = self.library.getFolder()
         lib.invokeFactory('Ruleset', 'allowed')
         # wrong place
-        self.assertRaises(ValueError,
+        self.assertRaises((Unauthorized, ValueError),
                           self.folder.invokeFactory,
                           'Ruleset', 'disallowed')
         # wrong type
@@ -73,78 +77,7 @@
                           'SimpleType', 'disallowed')
         self.logout()
     
-    ## TODO:
-    ##  rework this test to comply with current permissions settings for Products.Relations action
-    def testActions(self):
-        # test registration as ActionProvider and the action we define
-
-        at = getToolByName(self.portal, 'portal_actions')
-
-        def hasaction(obj):
-            category = 'object'
-            filtered_actions = at.listFilteredActionsFor(obj)
-            if category not in filtered_actions.keys():
-                return False
-            for action in filtered_actions[category]:
-                if action['id'] == 'relations':
-                    return action
-            return False
-
-        ## No, that's not supposed to happen anymore
-        ## all actions are registered with the actions, types, or
-        ## workflow tool from CMF 2.0 onwards
-        # self.assert_(RELATIONS_LIBRARY in at.listActionProviders())
-
-        # There's no action because there's no vocabularies
-        self.assert_(not hasaction(self.library))
-
-        # We add a ruleset and a corresponding reference.
-        self.loginAsPortalOwner()
-        f = self.library.getFolder()
-        f.invokeFactory('Ruleset', 'samerel')
-
-        self.library.addReference(self.library, 'samerel')
-        self.logout(); self.login()
-
-        # Not there, ruleset needs to be published.
-        self.assert_(not hasaction(self.library))
-
-        self.loginAsPortalOwner()
-        self.portal.portal_workflow.doActionFor(f.samerel, 'publish')
-        self.logout(); self.login()
-
-        # Still not there, we need 'Modify portal content' on the object...
-        self.assert_(not hasaction(self.library))        
-
-        # ... which we get now.
-        self.loginAsPortalOwner()
-        self.assert_(hasaction(self.library), "'relations' action n/a")
-        self.logout(); self.login()
-
-        # What we do here is test our action's condition in cases where context
-        # is not a Referenceable.
-        self.assert_(not hasaction(self.folder))
-
-        # We create a folder which is referenceable. Inside this folder, we
-        # create a document which is not.
-        # We want to make sure that in the context of document we don't acquire
-        # the folder's vocabulary.
-
-        # XXX: Document is referenceable, need to find something
-        # that's not referenceable.
-##         self.folder.invokeFactory('SimpleFolder', 'somefolder')
-##         sf = self.folder.somefolder
-##         sf.invokeFactory('Document', 'somedocument')
-##         sd = sf.somedocument
-##         self.assertEquals(sd.UID(), sf.UID())
-
-##         sf.addReference(sf, 'samerel')
-##         action = hasaction(sf)
-##         self.assert_(action)
-
-##         self.assert_(not hasaction(sd),
-##                      "%r has acquired vocabulary of %r" % (sd, sf))
-
+        
     def testRenameLibrary(self):
         self.loginAsPortalOwner()
         rename = self.portal.manage_renameObject
@@ -180,7 +113,7 @@
 # A dummy component that implements all interfaces and stores argument values
 # to its methods inside self.calls, a dict that's keyed by methodnames.
 class DummyComponent(SimpleItem, rulesetmodule.RuleBase):
-    __implements__ = (interfaces.IVocabularyProvider,
+    implements(interfaces.IVocabularyProvider,
                       interfaces.IPrimaryImplicator,
                       interfaces.IImplicator,
                       interfaces.IValidator,
@@ -347,14 +280,14 @@
         # components that we may add.
         self.assert_(len(types) > 0)
         for ti in types:
-            self.assert_(icmfcore.ITypeInformation.providedBy(ti),
+            self.assert_(implementedOrProvidedBy(icmfcore.ITypeInformation, ti),
                          "%s not a type information." % ti)
 
     def testInvokeFactory(self):
         ti = self.ruleset.allowedContentTypes()[0]
         self.ruleset.invokeFactory(ti.id, 'allowed')
         # wrong place
-        self.assertRaises(ValueError,
+        self.assertRaises((Unauthorized, ValueError),
                           self.folder.invokeFactory,
                           ti.id, 'disallowed')
         # wrong type

Modified: Products.Relations/trunk/Products/Relations/utils.py
==============================================================================
--- Products.Relations/trunk/Products/Relations/utils.py	(original)
+++ Products.Relations/trunk/Products/Relations/utils.py	Tue Nov 30 20:49:36 2010
@@ -1,6 +1,6 @@
 from AccessControl import ModuleSecurityInfo
 from Acquisition import aq_base
-from Interface import Implements
+from zope.interface.declarations import Implements
 from OFS.CopySupport import CopySource
 
 from Products.CMFCore.utils import getToolByName
@@ -74,7 +74,7 @@
         for data in listTypes():
             klass = data['klass']
             for iface in self.allowed_interfaces:
-                if iface.isImplementedByInstancesOf(klass):
+                if iface.implementedBy(klass):
                     ti = pt.getTypeInfo(data['portal_type'])
                     if ti is not None and ti.isConstructionAllowed(self):
                         value.append(ti)
@@ -84,7 +84,7 @@
         """Does the given portal_type implement one of the given interfaces?"""
         klass = self._getClassByPortalType(portal_type)
         for iface in ifaces:
-            if iface.isImplementedByInstancesOf(klass):
+            if iface.implementedBy(klass):
                 return 1
 
     def _getClassByPortalType(self, name):
@@ -103,21 +103,10 @@
     tool = getToolByName(context, 'archetype_tool')
     for data in tool.listRegisteredTypes():
         klass = data['klass']
-        kifaces = klass.__implements__
-
-            
-        # We now flatten the interfaces and get their unqualified names,
-        # e.g. <Products.FooBar.interfaces.ISpam> becomes "ISpam"
-        # we support now both interfaces for zope2 and zope3
-        
-        kifaces_z2 = [str(iface.__name__)
-                   for iface in Implements.flattenInterfaces((kifaces,))]
                    
-        kifaces_z3 = [str(iface.__name__)
+        kifaces = [str(iface.__name__)
                    for iface in interface.implementedBy(klass).flattened()]
                    
-        kifaces = kifaces_z2 + kifaces_z3
-                   
         if [iface for iface in allowedIfaces if iface in kifaces]:
             value.append(data['portal_type'])
 

Modified: Products.Relations/trunk/docs/HISTORY.txt
==============================================================================
--- Products.Relations/trunk/docs/HISTORY.txt	(original)
+++ Products.Relations/trunk/docs/HISTORY.txt	Tue Nov 30 20:49:36 2010
@@ -1,3 +1,11 @@
+2010-10-11  Max Burgess (netropic at u dot washington dot edu)
+
+    Removed test for unsupported Relations action tab.
+
+2010-10-11  Eric Steele (ericsteele at psu dot edu)
+
+    Add Plone 4.x compatibility. Product should now work in both 3.x and 4.x
+
 2008-09-10  Cris Ewing (cewing at u dot washington dot edu)
 
     Fixed a bug in the finalizeOnConnect() method of 

Modified: Products.Relations/trunk/setup.py
==============================================================================
--- Products.Relations/trunk/setup.py	(original)
+++ Products.Relations/trunk/setup.py	Tue Nov 30 20:49:36 2010
@@ -1,7 +1,7 @@
 from setuptools import setup, find_packages
 import os
 
-version = '0.8 (svn/trunk)'
+version = '0.9 (svn/trunk)'
 
 setup(name='Products.Relations',
       version=version,

------------------------------------------------------------------------------
Increase Visibility of Your 3D Game App & Earn a Chance To Win $500!
Tap into the largest installed PC base & get more eyes on your game by
optimizing for Intel(R) Graphics Technology. Get started today with the
Intel(R) Software Partner Program. Five $500 cash prizes are up for grabs.
http://p.sf.net/sfu/intelisp-dev2dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.