Changeset 547
- Timestamp:
- 05/30/03 10:56:07 (5 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/RBFoundation/RBFoundation/Objects/Relations.py
r510 r547 21 21 22 22 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 #~ Imports 24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 26 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 27 #~ Definitions 24 28 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 25 29 26 class Re altionship(object):27 """This class is meant to illustrait a generic relationship object, and the28 interface that is expected of it."""30 class RelationsCollection(object): 31 def __len__(self): 32 return len(list(iter(self))) 29 33 30 def __init__(self, obj): 31 """Called either explicitly, or from Add()""" 32 self.relationobj = obj 34 def __iter__(self): 35 raise NotImplementedError 33 36 34 def __repr__(self): 35 """Nice string representation for debugging""" 36 return '<%s to:%r>' % (self.__class__.__name__, self.relationobj) 37 def __contains__(self, item): 38 return item in iter(self) 37 39 38 def __call__(self):39 """This should dereference the object and return the resultant object"""40 return self.relationobj40 def extend(self, relations): 41 for relation in relations: 42 self.append(relation) 41 43 42 def LookupKey(self): 43 """This should return the lookup key for a specific type of relation. 44 You should change the name of the method to reflect the key information 45 being returned. This method is pointed to by 46 RelationshipCollection.KeyOfRelationType 47 """ 48 return hash(self.relationobj) 49 50 def AsRelation(klass, obj): 51 """This method is intended to be a "smart wrapper" class method around 52 the Relationship object""" 53 if isinstance(obj, klass): 54 # pass it through 55 return obj 56 elif isinstance(obj, RelationshipCollection): 57 # pass it through 58 return obj 59 else: 60 # wrap it with this relationship wrapper 61 return klass(obj) 62 AsRelation = classmethod(AsRelation) 44 def append(self, relation): 45 raise NotImplementedError 63 46 64 47 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65 48 66 class RelationshipCollection(object): 67 """Base class for RelationshipCollection like RelationshipBag and 68 RelationshipLookup""" 49 class RelationsBag(RelationsCollection): 50 """A simple, modifyable implementation of RelationsCollection""" 69 51 70 #~ Collection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 def __init__(self): 53 self.bag = list() 54 55 def __contains__(self, relation): 56 return relation in self.bag 71 57 72 58 def __len__(self): 73 return self.lenRelations()59 return len(self.bag) 74 60 75 61 def __iter__(self): 76 return self.iterRelations()62 return iter(self.bag) 77 63 78 #~ Readonly ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 def append(self, relation): 65 return self.bag.append(relation) 79 66 80 def _AssertModifyable(self): 81 if self.IsReadonly(): 82 raise ValueError, 'Relationship collection is read only' 83 84 def IsReadonly(self): 85 return getattr(self, 'readonly', False) 86 87 def SetReadonly(self, readonly=True): 88 self.readonly = bool(readonly) 67 def extend(self, relations): 68 return self.bag.extend(relations) 89 69 90 70 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 91 71 92 class Relationship Bag(RelationshipCollection):72 class Relationships(RelationsCollection): 93 73 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 94 74 #~ Constants / Variables / Etc. 95 75 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 96 76 97 AsRelationType = Realtionship.AsRelation77 defaultKind = None 98 78 99 79 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ … … 101 81 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 102 82 103 def __ repr__(self):104 """Nice string representation for debugging"""105 return '<%s %s>' % (self.__class__.__name__, self._collection)83 def __init__(self, dataitem=None): 84 if dataitem is not None: 85 self.SetDataItem(dataitem) 106 86 107 #~ RelationshipCollection interface ~~~~~~~~~~~~~~~~~ 87 def GetDataItem(self): 88 """Returns the subject dataitem of the relationship""" 89 return self.dataitem 108 90 109 def lenRelations(self): 110 return len(self._collection) 91 def SetDataItem(self, dataitem): 92 """Ability to set the dataitem to a new value""" 93 self.dataitem = dataitem 111 94 112 def iterRelations(self): 113 return iter(self._collection) 95 def Metadata(self): 96 """Returns the metadata about this relationship""" 97 try: 98 return self.metadata 99 except AttributeError: 100 self.metadata = {} 101 return self.metadata 114 102 115 def Add(self, relation, *args, **kw): 116 self._AssertModifyable() 117 relation = self.AsRelationType(relation, *args, **kw) 118 self._collection.append(relation) 103 #def MetaRelationship(self): 104 # """Returns the relationship "above" the current level... a relationship of relationships""" 105 # return self.metarelationship 119 106 120 def AddMany(self, many): 121 self._AssertModifyable() 122 for each in many: 123 if isinstance(each, tuple): 124 relation = self.AsRelationType(*each) 125 else: 126 relation = self.AsRelationType(each) 127 self._collection.append(relation) 107 #~ Relations related ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 128 108 129 def Remove(self, relation, *args, **kw): 130 self._AssertModifyable() 131 relation = self.AsRelationType(relation, *args, **kw) 132 self._collection.remove(relation) 109 def AddRelation(self, other, kind=None): 110 if kind is None: kind = self.defaultKind 111 self.Relations(kind).append(other) 133 112 134 #~ _collection property ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 113 def AddRelationKind(self, kind, relationcollection): 114 self._getRelations()[kind] = relationcollection 135 115 136 def _get_collection(self): 137 try: return self._collection_ 116 def Relations(self, kind=None): 117 if kind is None: kind = self.defaultKind 118 return self._getRelations()[kind] 119 120 def AllRelations(self): 121 return self._getRelations().iteritems() 122 123 def RelationKinds(self): 124 return self._getRelations().iterkeys() 125 126 def _getRelations(self): 127 try: 128 return self.relations 138 129 except AttributeError: 139 self._collection_ = [] 140 return self._collection_ 141 _collection = property(_get_collection) 130 self.relations = self._RelationsFactory() 131 return self.relations 142 132 143 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 def _RelationsFactory(self): 134 return {} 135 136 #~ RelationCollection stand in for defaultKind ~~~~~~ 144 137 145 class RelationshipLookup(RelationshipCollection): 146 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 147 #~ Constants / Variables / Etc. 148 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 138 def __iter__(self): 139 """Iterable of the default relation""" 140 return iter(self.Relations(self.defaultKind)) 149 141 150 AsRelationType = Realtionship.AsRelation 151 KeyOfRelationType = Realtionship.LookupKey 142 def __contains__(self, relation): 143 """Tests for membership in the default relation""" 144 return relation in self.Relations(self.defaultKind) 152 145 153 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~154 #~ Public Methods155 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~146 def __len__(self): 147 """Length of the default relation""" 148 return len(self.Relations(self.defaultKind)) 156 149 157 def __repr__(self):158 """ Nice string representation for debugging"""159 return '<%s %s>' % (self.__class__.__name__, self._collection)150 def append(self, relation): 151 """Appends to the default relation""" 152 return self.Relations(self.defaultKind).append(relation) 160 153 161 #~ dictionary view of collection ~~~~~~~~~~~~~~~~~~~~ 154 def extend(self, relations): 155 """Extends the default relation""" 156 return self.Relations(self.defaultKind).extend(relations) 162 157 163 def __contains__(self, key):164 return key in self._collection165 166 def __getitem__(self, key):167 return self._collection[key]168 169 def __setitem__(self, category, value):170 raise NotImplementedError, "Cannot set a lookup relation by key. Use Add() or Set() instead."171 172 def __delitem__(self, key):173 del self._collection[key]174 175 def iterkeys(self):176 return self._categories.iterkeys()177 178 def itervalues(self):179 return self._categories.itervalues()180 181 def iteritems(self):182 return self._categories.iteritems()183 184 #~ RelationshipCollection interface ~~~~~~~~~~~~~~~~~185 186 def lenRelations(self):187 return len(self._collection)188 189 def iterRelations(self):190 return iter(self._collection)191 192 def Add(self, relation, *args, **kw):193 self._AssertModifyable()194 relation = self.AsRelationType(relation, *args, **kw)195 key = self.KeyOfRelationType(relation)196 self._collection[key] = relation197 198 def Set(self, relation):199 return self.Add(relation)200 201 def AddMany(self, many):202 self._AssertModifyable()203 for each in many:204 if isinstance(each, tuple):205 relation = self.AsRelationType(*each)206 else:207 relation = self.AsRelationType(each)208 key = self.KeyOfRelationType(relation)209 self._collection[key] = relation210 211 def Remove(self, relation, *args, **kw):212 self._AssertModifyable()213 relation = self.AsRelationType(relation, *args, **kw)214 key = self.KeyOfRelationType(relation)215 del self._collection[key]216 217 #~ _collection property ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~218 219 def _get_collection(self):220 try: return self._collection_221 except AttributeError:222 self._collection_ = {}223 return self._collection_224 _collection = property(_get_collection)225 226 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~227 #~ Testing228 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~229 230 if __name__=='__main__':231 pass232
