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
85 - def _remove(self,obj=None, suppress_events=False):
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 attributes = ''
168 if target is not None:
169 attributes = "target='%s' " % (target,)
170 link = "<a %shref='%s'>%s</a>" % (
171 attributes,
172 self.obj.getPrimaryUrlPath(),
173 self.obj.id)
174 return link
175
176
178 """Return the primary URL for our related object.
179 """
180 return self.obj.getPrimaryUrlPath()
181
182
184 """return an xml representation of a ToOneRelationship
185 <toone id='cricket'>
186 /Monitors/Cricket/crk0.srv.hcvlny.cv.net
187 </toone>"""
188 from RelSchema import ToManyCont
189 if not self.obj or self.remoteType()==ToManyCont: return
190 ofile.write("<toone id='%s' objid='%s'/>\n" % (
191 self.id, self.obj.getPrimaryId()))
192
193
195 """Check to make sure that relationship bidirectionality is ok.
196 """
197 if not self.obj: return
198 log.debug("checking relation: %s", self.id)
199
200 try:
201 ppath = self.obj.getPrimaryPath()
202 getObjByPath(self, ppath)
203 except (KeyError, NotFound):
204 log.error("object %s in relation %s has been deleted " \
205 "from its primary path",
206 self.obj.getPrimaryId(), self.getPrimaryId())
207 if repair:
208 log.warn("removing object %s from relation %s",
209 self.obj.getPrimaryId(), self.getPrimaryId())
210 self.obj = None
211
212 if not self.obj: return
213
214 rname = self.remoteName()
215 rrel = getattr(self.obj, rname)
216 parobj = self.getPrimaryParent()
217 if not rrel.hasobject(parobj):
218 log.error("remote relation %s doesn't point back to %s",
219 rrel.getPrimaryId(), self.getPrimaryId())
220 if repair:
221 log.warn("reconnecting relation %s to relation %s",
222 rrel.getPrimaryId(), self.getPrimaryId())
223 rrel._add(parobj)
224
225
226 InitializeClass(ToOneRelationship)
227