1
2
3
4
5
6
7
8
9
10
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
41
42
43 addToManyContRelationship = DTMLFile('dtml/addToManyContRelationship',globals())
44
45
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
58 """set our instance values"""
59 self.id = id
60 self._objects = OOBTree()
61
62
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
74
75
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
85 "check to see if we have this object"
86 return self._objects.get(obj.id) == obj
87
88
94
95
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
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
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
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
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):
162
163
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
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
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')
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')
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
229 """Generator that returns all related objects."""
230 for obj in self._objects.values():
231 yield obj.__of__(self)
232
233
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
247
248
249
250
251
252
253
254
255
256
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
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