diff --git a/interfaces.py b/interfaces.py index 50525f0..2cfd966 100644 --- a/interfaces.py +++ b/interfaces.py @@ -22,6 +22,7 @@ loops interface definitions. $Id$ """ +from zope.interface import Interface from zope.app.container.interfaces import IOrderedContainer from zope.schema import TextLine @@ -70,18 +71,18 @@ class ITask(IOrderedContainer): target resource types given. """ - def allocateResource(resource, allocType=None): + def allocateResource(resource, allocType='standard'): """ Allocate resource to self. A special allocation type may be given. """ - def createAndAllocateResource(resourceType='Resource', allocType='standard', + def createAndAllocateResource(resourceType=None, allocType='standard', container=None, name=None): """ Allocate resource to self. A special allocation type may be given. - Additional properties may be given as keyword parameters. """ - def deallocateResource(resource): - """ Deallocate from self the resource allocated. + def deallocateResource(resource, allocTypes=None): + """ Deallocate from self the resource given. If no allocTypes + given all allocations to resource will be removed. """ def allocatedUserIds(): @@ -89,9 +90,9 @@ class ITask(IOrderedContainer): Used by catalog index 'allocUserIds'. """ - def getAllocType(resource): - """ Return the allocation type for the resource given. Raise a - ValueException if resource is not allocated to self. + def getAllocTypes(resource): + """ Return the allocation types with which the resource given + is allocated to self. """ def getAllAllocTypes(): @@ -111,3 +112,9 @@ class IResource(IOrderedContainer): source task types given. """ + +class IResourceConstraint(Interface): + """ A ResourceConstraint governs which Resource objects may be + allocated to a Task object. + """ + diff --git a/resource.py b/resource.py index a68387e..cf48443 100644 --- a/resource.py +++ b/resource.py @@ -24,6 +24,7 @@ $Id$ from zope.interface import implements from zope.app.container.ordered import OrderedContainer +from zope.app import zapi from interfaces import IResource @@ -52,13 +53,23 @@ class Resource(OrderedContainer): # Helper methods: - def _updateAllocations(self, task, allocType): + def _addAllocation(self, task, allocType): #called by Task.allocateResource tList = self._allocations.get(allocType, []) tList.append(task) self._allocations[allocType] = tList - def _createResourceName(self): + def _removeAllocations(self, task, allocTypes): + #called by Task.deallocateResource + allocs = self._allocations + for at in allocTypes or allocs.keys(): + if task in allocs[at]: + allocs[at].remove(task) + + def _createResourceName(self, container=None): prefix = 'rsc' - last = max([ int(n[len(prefix):]) for n in self.__parent__.keys() ] or [1]) + container = container or zapi.getParent(self) + last = max([ int(n[len(prefix):]) for n in container.keys() ] or [1]) return prefix + str(last+1) + + \ No newline at end of file diff --git a/task.py b/task.py index edf4001..ba2e4c1 100644 --- a/task.py +++ b/task.py @@ -24,10 +24,11 @@ $Id$ from zope.interface import implements from zope.app.container.ordered import OrderedContainer +from zope.app import zapi +from resource import Resource from interfaces import ITask - class Task(OrderedContainer): implements(ITask) @@ -54,9 +55,9 @@ class Task(OrderedContainer): task._parentTasks.append(self) def createSubtask(self, taskType=None, container=None, name=None): - container = container or self.__parent__ + container = container or zapi.getParent(self) task = Task() - name = name or self._createTaskName() + name = name or task._createTaskName(container) container[name] = task self.assignSubtask(task) return task @@ -65,37 +66,47 @@ class Task(OrderedContainer): self._subtasks.remove(task) task._parentTasks.remove(self) - # resources: + # resource allocations: def getAllocatedResources(self, allocTypes=None, resTypes=None): from sets import Set allocs = self._resourceAllocs res = Set() - for at in allocs.keys(): - if allocTypes is None or at in allocTypes: - res.union_update(allocs[at]) + for at in allocTypes or allocs.keys(): + res.union_update(allocs[at]) + if resTypes: + res = [ r for r in res if r in resTypes ] return tuple(res) - def allocateResource(self, resource, allocType=None): - allocType = allocType or 'standard' + def allocateResource(self, resource, allocType='standard'): allocs = self._resourceAllocs rList = allocs.get(allocType, []) - rList.append(resource) + if resource not in rList: + rList.append(resource) allocs[allocType] = rList - resource._updateAllocations(self, allocType) + resource._addAllocation(self, allocType) - def createAndAllocateResource(self, resourceType='Resource', allocType='standard', - container=None, id=None): - return None + def createAndAllocateResource(self, resourceType=None, allocType='standard', + container=None, name=None): + container = container or zapi.getParent(self) + resource = Resource() + name = name or resource._createResourceName(container) + container[name] = resource + self.allocateResource(resource, allocType) + return resource - def deallocateResource(self, resource): - pass + def deallocateResource(self, resource, allocTypes=None): + allocs = self._resourceAllocs + for at in allocTypes or allocs.keys(): + if resource in allocs[at]: + allocs[at].remove(resource) + resource._removeAllocations(self, allocTypes) def allocatedUserIds(self): return () - def getAllocType(self, resource): - return 'standard' + def getAllocTypes(self, resource): + return ('standard',) def getAllAllocTypes(self): return ('standard',) @@ -103,7 +114,8 @@ class Task(OrderedContainer): # Helper methods: - def _createTaskName(self): + def _createTaskName(self, container=None): prefix = 'tsk' - last = max([ int(n[len(prefix):]) for n in self.__parent__.keys() ] or [1]) + container = container or zapi.getParent(self) + last = max([ int(n[len(prefix):]) for n in container.keys() ] or [1]) return prefix + str(last+1) diff --git a/tests/test_resource.py b/tests/test_resource.py index a9871be..929fcae 100755 --- a/tests/test_resource.py +++ b/tests/test_resource.py @@ -54,6 +54,14 @@ class Test(unittest.TestCase): t1.allocateResource(r1) self.assertEqual((t1,), r1.getTasksAllocatedTo()) + def testDeallocateFromTask(self): + t1 = self.t1 + r1 = self.r1 + t1.allocateResource(r1) + self.assertEqual((t1,), r1.getTasksAllocatedTo()) + t1.deallocateResource(r1) + self.assertEqual((), r1.getTasksAllocatedTo()) + def test_suite(): return unittest.TestSuite(( diff --git a/tests/test_task.py b/tests/test_task.py index 88b379a..e237a68 100755 --- a/tests/test_task.py +++ b/tests/test_task.py @@ -4,9 +4,11 @@ import unittest #from zope.testing.doctestunit import DocTestSuite from zope.interface.verify import verifyClass #from zope.app.tests.setup import placelessSetUp +from zope.app.tests.setup import placefulSetUp #from zope.app.container.tests.test_icontainer import TestSampleContainer from zope.app.container.interfaces import IContained from zope.app.folder import Folder +from zope.app import zapi from loops.task import Task from loops.interfaces import ITask @@ -16,7 +18,8 @@ class TestTask(unittest.TestCase): "Test methods of the Task class." def setUp(self): - #placelessSetUp() +# placelessSetUp() + placefulSetUp() self.f1 = Folder() self.f1.__name__ = u'f1' self.t1 = Task() @@ -35,8 +38,8 @@ class TestTask(unittest.TestCase): verifyClass(ITask, Task) def testContained(self): - self.assertEqual(u'tsk1', self.t1.__name__) - self.assertEqual(u'f1', self.t1.__parent__.__name__) + self.assertEqual(u'tsk1', zapi.name(self.t1)) + self.assertEqual(u'f1', zapi.name(zapi.getParent(self.t1))) def testTitle(self): t = Task() @@ -75,9 +78,9 @@ from loops.resource import Resource class TestTaskResource(unittest.TestCase): "Test methods of the Task class related to Resource allocations." - def setUp(self): #placelessSetUp() + #placefulSetUp() self.f1 = Folder() self.f1.__name__ = u'f1' self.t1 = Task() @@ -97,6 +100,20 @@ class TestTaskResource(unittest.TestCase): t1.allocateResource(r1) self.assertEqual((r1,), t1.getAllocatedResources()) + def testDeallocateResource(self): + t1 = self.t1 + r1 = self.r1 + t1.allocateResource(r1) + self.assertEqual((r1,), t1.getAllocatedResources()) + t1.deallocateResource(r1) + self.assertEqual((), t1.getAllocatedResources()) + + def testCreateAndAllocateResource(self): + t1 = self.t1 + self.assertEqual((), t1.getAllocatedResources()) + r1 = t1.createAndAllocateResource() + self.assertEqual((r1,), t1.getAllocatedResources()) + def test_suite(): return unittest.TestSuite((