1
2
3
4
5
6
7
8
9
10
11
12
13
14 __doc__="""ToOneRelationship
15
16 ToOneRelationship is a class used on a RelationshipManager
17 to give it toOne management Functions.
18 """
19
20 import logging
21 log = logging.getLogger("zen.Relations")
22
23
24
25 from RelationshipBase import RelationshipBase
26
27 from Globals import InitializeClass
28 from Globals import DTMLFile
29 from AccessControl import ClassSecurityInfo
30 from App.Dialogs import MessageDialog
31 from Acquisition import aq_base
32
33 from zExceptions import NotFound
34 from Products.ZenRelations.Exceptions import *
35 from Products.ZenUtils.Utils import unused, getObjByPath
36
43
44
45
46 addToOneRelationship = DTMLFile('dtml/addToOneRelationship',globals())
47
48
50 """ToOneRelationship represents a to one Relationship
51 on a RelationshipManager"""
52
53 meta_type = 'ToOneRelationship'
54
55 security = ClassSecurityInfo()
56
57
59 self.id = id
60 self.obj = None
61
62
64 """return the related object when a ToOne relation is called"""
65
66
67
68 return self.obj
69
70
72 """does this relation point to the object passed"""
73 return self.obj == obj
74
75
76 - def _add(self, obj):
77 """add a to one side of a relationship
78 if a relationship already exists clear it"""
79 if obj == self.obj: raise RelationshipExistsError
80 self._remoteRemove()
81 self.obj = aq_base(obj)
82 self.__primary_parent__._p_changed = True
83
84
86 """remove the to one side of a relationship"""
87 if obj == None or obj == self.obj:
88 self.obj = None
89 self.__primary_parent__._p_changed = True
90 else:
91 raise ObjectNotFound( "object %s was not found on %s" % (obj, self))
92
93
95 """clear the remote side of this relationship"""
96 if self.obj:
97 if obj != None and obj != self.obj:
98 raise ObjectNotFound(
99 "object %s was not found on %s it has object %s" %
100 (obj.getPrimaryId(), self.getPrimaryId(),
101 self.obj.getPrimaryId()))
102 remoteRel = getattr(aq_base(self.obj), self.remoteName())
103 remoteRel._remove(self.__primary_parent__)
104
105
106 security.declareProtected('View', 'getRelatedId')
113
114
116 """
117 Create ToOne copy. If this is the one side of one to many
118 we set our side of the relation to point towards the related
119 object (maintain the relationship across the copy).
120 """
121 rel = self.__class__(self.id)
122 rel.__primary_parent__ = container
123 rel = rel.__of__(container)
124 if (self.remoteTypeName() == "ToMany" and self.obj):
125 rel.addRelation(self.obj)
126 return rel
127
128
130 """Don't do anything here because we have on containment"""
131 pass
132
133
135 """Don't do anything here because we have on containment"""
136 pass
137
138
140 """ZMI function to return the workspace of the related object"""
141 if self.obj:
142 objurl = self.obj.getPrimaryUrlPath()
143 REQUEST['RESPONSE'].redirect(objurl+'/manage_workspace')
144 else:
145 return MessageDialog(
146 title = "No Relationship Error",
147 message = "This relationship does not currently point" \
148 " to an object",
149 action = "manage_main")
150
151
152 - def manage_main(self, REQUEST=None):
153 """ZMI function to redirect to parent relationship manager"""
154 REQUEST['RESPONSE'].redirect(
155 self.getPrimaryParent().getPrimaryUrlPath()+'/manage_workspace')
156
157
158
159 security.declareProtected('View', 'getPrimaryLink')
161 """get the link tag of a related object"""
162 link = ""
163 if self.obj:
164 if not self.obj.checkRemotePerm("View", self.obj):
165 link = self.obj.id
166 else:
167 link = "<a href='%s'>%s</a>" % (self.obj.getPrimaryUrlPath(),
168 self.obj.id)
169 return link
170
171
173 """Return the primary URL for our related object.
174 """
175 return self.obj.getPrimaryUrlPath()
176
177
179 """return an xml representation of a ToOneRelationship
180 <toone id='cricket'>
181 /Monitors/Cricket/crk0.srv.hcvlny.cv.net
182 </toone>"""
183 from RelSchema import ToManyCont
184 if not self.obj or self.remoteType()==ToManyCont: return
185 ofile.write("<toone id='%s' objid='%s'/>\n" % (
186 self.id, self.obj.getPrimaryId()))
187
188
190 """Check to make sure that relationship bidirectionality is ok.
191 """
192 if not self.obj: return
193 log.debug("checking relation: %s", self.id)
194
195 try:
196 ppath = self.obj.getPrimaryPath()
197 getObjByPath(self, ppath)
198 except (KeyError, NotFound):
199 log.error("object %s in relation %s has been deleted " \
200 "from its primary path",
201 self.obj.getPrimaryId(), self.getPrimaryId())
202 if repair:
203 log.warn("removing object %s from relation %s",
204 self.obj.getPrimaryId(), self.getPrimaryId())
205 self.obj = None
206
207 if not self.obj: return
208
209 rname = self.remoteName()
210 rrel = getattr(self.obj, rname)
211 parobj = self.getPrimaryParent()
212 if not rrel.hasobject(parobj):
213 log.error("remote relation %s doesn't point back to %s",
214 rrel.getPrimaryId(), self.getPrimaryId())
215 if repair:
216 log.warn("reconnecting relation %s to relation %s",
217 rrel.getPrimaryId(), self.getPrimaryId())
218 rrel._add(parobj)
219
220
221 InitializeClass(ToOneRelationship)
222