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, BeforeDeleteException
26 from ZODB.POSException import ConflictError
27
28 from BTrees.OOBTree import OOBTree
29
30 from ToManyRelationshipBase import ToManyRelationshipBase
31
32 from Products.ZenRelations.Exceptions import *
33
34 from Products.ZenUtils.Utils import unused
35
43
44
45 addToManyContRelationship = DTMLFile('dtml/addToManyContRelationship',globals())
46
47
49 """
50 ToManyContRelationship is the ToMany side of a realtionship that
51 contains its related objects (like the normal Zope ObjectManager)
52 """
53
54 meta_type = "ToManyContRelationship"
55
56 security = ClassSecurityInfo()
57
58
60 """set our instance values"""
61 self.id = id
62 self._objects = OOBTree()
63
64
66 """when we are called return our related object in our aq context"""
67 return [ob.__of__(self) for ob in self._objects.values()]
68
69
71 """look in the two object stores for related objects"""
72 if self.__dict__.has_key("_objects"):
73 objects = self.__dict__['_objects']
74 if objects.has_key(name): return objects[name]
75 raise AttributeError( "Unable to find the attribute '%s'" % name )
76
77
79 """check to see if we have an object by an id
80 this will fail if passed a short id and object is stored
81 with fullid (ie: it is related not contained)
82 use hasobject to get around this issue"""
83 return self._objects.has_key(name)
84
85
87 "check to see if we have this object"
88 return self._objects.get(obj.id) == obj
89
90
96
97
98 - def _setObject(self,id,object,roles=None,user=None,set_owner=1):
99 """ObjectManager interface to add contained object."""
100 unused(user, roles, set_owner)
101 object.__primary_parent__ = aq_base(self)
102 self.addRelation(object)
103 object.manage_afterAdd(object, self)
104 return object.getId()
105
106
108 """
109 Copied code from ObjectManager
110 """
111 for object in self.objectValues():
112 try: s=object._p_changed
113 except: s=0
114 if hasattr(aq_base(object), 'manage_afterAdd'):
115 object.manage_afterAdd(item, container)
116 if s is None: object._p_deactivate()
117
118
120 """
121 Copied code from ObjectManager
122 """
123 for object in self.objectValues():
124 try: s=object._p_changed
125 except: s=0
126 if hasattr(aq_base(object), 'manage_afterClone'):
127 object.manage_afterClone(item)
128 if s is None: object._p_deactivate()
129
130
132 """
133 Copied code from ObjectManager
134 """
135 for object in self.objectValues():
136 try: s=object._p_changed
137 except: s=0
138 try:
139 if hasattr(aq_base(object), 'manage_beforeDelete'):
140 object.manage_beforeDelete(item, container)
141 except BeforeDeleteException:
142 raise
143 except ConflictError:
144 raise
145 except:
146 log.exception('manage_beforeDelete()')
147 if s is None: object._p_deactivate()
148
149
150 - def _add(self,obj):
151 """add an object to one side of a ToManyContRelationship.
152 """
153 id = obj.id
154 if self._objects.has_key(id):
155 raise RelationshipExistsError
156 v=checkValidId(self, id)
157 if v is not None: id=v
158 self._objects[id] = aq_base(obj)
159 obj = aq_base(obj).__of__(self)
160
161
163 """remove object from our side of a relationship"""
164 if obj: objs = [obj]
165 else: objs = self.objectValuesAll()
166 for robj in objs:
167 robj.manage_beforeDelete(robj, self)
168 if obj:
169 id = obj.id
170 if not self._objects.has_key(id):
171 raise ObjectNotFound(
172 "object %s not found on %s" % (
173 obj.getPrimaryId(), self.getPrimaryId()))
174 del self._objects[id]
175 else:
176 self._objects = OOBTree()
177 self.__primary_parent__._p_changed = True
178
179
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( "Unable to find %s" % 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 """override to only return owned objects for many to many rel"""
218 if spec:
219 if type(spec)==type('s'): spec=[spec]
220 return [ob.__of__(self) for ob in self._objects.values() \
221 if ob.meta_type in spec]
222 return [ob.__of__(self) for ob in self._objects.values()]
223 security.declareProtected('View', 'objectValuesAll')
224 objectValuesAll = objectValues
225
226
228 """Generator that returns all related objects."""
229 for obj in self._objects.values():
230 yield obj.__of__(self)
231
232
234 """over ride to only return owned objects for many to many rel"""
235 if spec:
236 if type(spec)==type('s'): spec=[spec]
237 return [(key,value.__of__(self)) \
238 for (key,value) in self._objects.items() \
239 if value.meta_type in spec]
240 return [(key,value.__of__(self)) \
241 for (key,value) in self._objects.items()]
242 objectItemsAll = objectItems
243
244
245
246
247
248
249
250
251
252
253
254
255
257 """
258 make new relation add copies of contained objs
259 and refs if the relation is a many to many
260 """
261 rel = self.__class__(self.id)
262 rel.__primary_parent__ = container
263 rel = rel.__of__(container)
264 norelcopy = getattr(self, 'zNoRelationshipCopy', [])
265 if self.id in norelcopy: return rel
266 for oobj in self.objectValuesAll():
267 cobj = oobj._getCopy(rel)
268 rel._setObject(cobj.id, cobj)
269 return rel
270
271
273 """Return an xml representation of a ToManyContRelationship
274 <tomanycont id='interfaces'>
275 <object id='hme0'
276 module='Products.Confmon.IpInterface' class='IpInterface'>
277 <property></property> etc....
278 </object>
279 </tomanycont>
280 """
281 if self.countObjects() == 0: return
282 ofile.write("<tomanycont id='%s'>\n" % self.id)
283 for obj in self.objectValues():
284 obj.exportXml(ofile, ignorerels)
285 ofile.write("</tomanycont>\n")
286
287
288 InitializeClass(ToManyContRelationship)
289