Package ZenRelations :: Module ToManyContRelationship'
[hide private]
[frames] | no frames]

Source Code for Module ZenRelations.ToManyContRelationship'

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  __doc__="""$Id: ToManyRelationship.py,v 1.48 2003/11/12 22:05:48 edahl Exp $""" 
 15   
 16  __version__ = "$Revision: 1.48 $"[11:-2] 
 17   
 18  import logging 
 19  log = logging.getLogger("zen.Relations") 
 20   
 21  from Globals import DTMLFile 
 22  from Globals import InitializeClass 
 23  from AccessControl import ClassSecurityInfo 
 24  from Acquisition import aq_base 
 25  from OFS.ObjectManager import checkValidId 
 26   
 27  from BTrees.OOBTree import OOBTree 
 28   
 29  from ToManyRelationshipBase import ToManyRelationshipBase 
 30   
 31  from Products.ZenRelations.Exceptions import * 
 32   
 33   
34 -def manage_addToManyContRelationship(context, id, REQUEST=None):
35 """factory for ToManyRelationship""" 36 rel = ToManyContRelationship(id) 37 context._setObject(rel.id, rel) 38 if REQUEST: 39 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main') 40 return rel.id
41 42 43 addToManyContRelationship = DTMLFile('dtml/addToManyContRelationship',globals()) 44 45
46 -class ToManyContRelationship(ToManyRelationshipBase):
47 """ 48 ToManyContRelationship is the ToMany side of a realtionship that 49 contains its related objects (like the normal Zope ObjectManager) 50 """ 51 52 meta_type = "ToManyContRelationship" 53 54 security = ClassSecurityInfo() 55 56
57 - def __init__(self, id):
58 """set our instance values""" 59 self.id = id 60 self._objects = OOBTree()
61 62
63 - def __call__(self):
64 """when we are called return our related object in our aq context""" 65 return [ob.__of__(self) for ob in self._objects.values()]
66 67
68 - def __getattr__(self, name):
69 """look in the two object stores for related objects""" 70 if self.__dict__.has_key("_objects"): 71 objects = self.__dict__['_objects'] 72 if objects.has_key(name): return objects[name] 73 raise AttributeError, name
74 75
76 - def __hasattr__(self, name):
77 """check to see if we have an object by an id 78 this will fail if passed a short id and object is stored 79 with fullid (ie: it is related not contained) 80 use hasobject to get around this issue""" 81 return self._objects.has_key(name)
82 83
84 - def hasobject(self, obj):
85 "check to see if we have this object" 86 return self._objects.get(obj.id) == obj
87 88
89 - def addRelation(self, obj):
90 """Override base to run manage_afterAdd like ObjectManager""" 91 ToManyRelationshipBase.addRelation(self, obj) 92 obj = obj.__of__(self) 93 obj.manage_afterAdd(obj, self)
94 95
96 - def _setObject(self,id,object,roles=None,user=None,set_owner=1):
97 """ObjectManager interface to add contained object.""" 98 object.__primary_parent__ = aq_base(self) 99 self.addRelation(object) 100 object.manage_afterAdd(object, self) 101 return object.getId()
102 103
104 - def manage_afterAdd(self, item, container):
105 """ 106 Copied code from ObjectManager 107 """ 108 for object in self.objectValues(): 109 try: s=object._p_changed 110 except: s=0 111 if hasattr(aq_base(object), 'manage_afterAdd'): 112 object.manage_afterAdd(item, container) 113 if s is None: object._p_deactivate()
114 115
116 - def manage_afterClone(self, item):
117 """ 118 Copied code from ObjectManager 119 """ 120 for object in self.objectValues(): 121 try: s=object._p_changed 122 except: s=0 123 if hasattr(aq_base(object), 'manage_afterClone'): 124 object.manage_afterClone(item) 125 if s is None: object._p_deactivate()
126 127
128 - def manage_beforeDelete(self, item, container):
129 """ 130 Copied code from ObjectManager 131 """ 132 for object in self.objectValues(): 133 try: s=object._p_changed 134 except: s=0 135 try: 136 if hasattr(aq_base(object), 'manage_beforeDelete'): 137 object.manage_beforeDelete(item, container) 138 except BeforeDeleteException, ob: 139 raise 140 except ConflictError: 141 raise 142 except: 143 LOG('Zope',ERROR,'manage_beforeDelete() threw', 144 error=sys.exc_info()) 145 # In debug mode when non-Manager, let exceptions propagate. 146 if getConfiguration().debug_mode: 147 if not getSecurityManager().getUser().has_role('Manager'): 148 raise 149 if s is None: object._p_deactivate()
150 151
152 - def _add(self,obj):
153 """add an object to one side of a ToManyContRelationship. 154 """ 155 id = obj.id 156 if self._objects.has_key(id): 157 raise RelationshipExistsError 158 v=checkValidId(self, id) 159 if v is not None: id=v 160 self._objects[id] = aq_base(obj) 161 obj = aq_base(obj).__of__(self)
162 163
164 - def _remove(self, obj=None):
165 """remove object from our side of a relationship""" 166 if obj: objs = [obj] 167 else: objs = self.objectValuesAll() 168 for robj in objs: 169 robj.manage_beforeDelete(robj, self) 170 if obj: 171 id = obj.id 172 if not self._objects.has_key(id): 173 raise ObjectNotFound( 174 "Object with id %s not found on relation %s" % 175 (id, self.id)) 176 del self._objects[id] 177 else: 178 self._objects = OOBTree() 179 self.__primary_parent__._p_changed = True
180 181
182 - def _remoteRemove(self, obj=None):
183 """remove an object from the far side of this relationship 184 if no object is passed in remove all objects""" 185 if obj: 186 if not self._objects.has_key(obj.id): raise ObjectNotFround 187 objs = [obj] 188 else: objs = self.objectValuesAll() 189 remoteName = self.remoteName() 190 for obj in objs: 191 rel = getattr(obj, remoteName) 192 rel._remove(self.__primary_parent__)
193 194
195 - def _getOb(self, id, default=zenmarker):
196 """look up in our local store and wrap in our aq_chain""" 197 if self._objects.has_key(id): 198 return self._objects[id].__of__(self) 199 elif default == zenmarker: 200 raise AttributeError, id 201 return default
202 203 204 security.declareProtected('View', 'objectIds')
205 - def objectIds(self, spec=None):
206 """only return contained objects""" 207 if spec: 208 if type(spec)==type('s'): spec=[spec] 209 return [obj.id for obj in self._objects.values() \ 210 if obj.meta_type in spec] 211 return [ k for k in self._objects.keys() ]
212 objectIdsAll = objectIds 213 214 215 security.declareProtected('View', 'objectValues')
216 - def objectValues(self, spec=None):
217 """over ride to only return owned objects for many to many rel""" 218 if spec: 219 retval = [] 220 if type(spec)==type('s'): spec=[spec] 221 return [ob.__of__(self) for ob in self._objects.values() \ 222 if ob.meta_type in spec] 223 return [ob.__of__(self) for ob in self._objects.values()]
224 security.declareProtected('View', 'objectValuesAll') 225 objectValuesAll = objectValues 226 227
228 - def objectValuesGen(self):
229 """Generator that returns all related objects.""" 230 for obj in self._objects.values(): 231 yield obj.__of__(self)
232 233
234 - def objectItems(self, spec=None):
235 """over ride to only return owned objects for many to many rel""" 236 if spec: 237 if type(spec)==type('s'): spec=[spec] 238 return [(key,value.__of__(self)) \ 239 for (key,value) in self._objects.items() \ 240 if value.meta_type in spec] 241 return [(key,value.__of__(self)) \ 242 for (key,value) in self._objects.items()]
243 objectItemsAll = objectItems 244 245 246 #FIXME - need to make this work 247 # def all_meta_types(self, interfaces=None): 248 # mts = [] 249 # for mt in ToManyRelationshipBase.all_meta_types(self, interfaces): 250 # if (mt.has_key('instance') and mt['instance']): 251 # for cl in self.sub_classes: 252 # if checkClass(mt['instance'], cl): 253 # mts.append(mt) 254 # return mts 255 256
257 - def _getCopy(self, container):
258 """ 259 make new relation add copies of contained objs 260 and refs if the relation is a many to many 261 """ 262 rel = self.__class__(self.id) 263 rel.__primary_parent__ = container 264 rel = rel.__of__(container) 265 norelcopy = getattr(self, 'zNoRelationshipCopy', []) 266 if self.id in norelcopy: return rel 267 for oobj in self.objectValuesAll(): 268 cobj = oobj._getCopy(rel) 269 rel._setObject(cobj.id, cobj) 270 return rel
271 272
273 - def exportXml(self, ofile, ignorerels=[]):
274 """Return an xml representation of a ToManyContRelationship 275 <tomanycont id='interfaces'> 276 <object id='hme0' 277 module='Products.Confmon.IpInterface' class='IpInterface'> 278 <property></property> etc.... 279 </object> 280 </tomanycont> 281 """ 282 if self.countObjects() == 0: return 283 ofile.write("<tomanycont id='%s'>\n" % self.id) 284 for obj in self.objectValues(): 285 obj.exportXml(ofile, ignorerels) 286 ofile.write("</tomanycont>\n")
287 288 289 InitializeClass(ToManyContRelationship) 290