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 Products.ZenRelations.Exceptions import *
34 from Products.ZenUtils.Utils import unused
35
42
43
44
45 addToOneRelationship = DTMLFile('dtml/addToOneRelationship',globals())
46
47
49 """ToOneRelationship represents a to one Relationship
50 on a RelationshipManager"""
51
52 meta_type = 'ToOneRelationship'
53
54 security = ClassSecurityInfo()
55
56
58 self.id = id
59 self.obj = None
60
61
63 """return the related object when a ToOne relation is called"""
64 return self.obj
65
66
68 """does this relation point to the object passed"""
69 return self.obj == obj
70
71
72 - def _add(self, obj):
73 """add a to one side of a relationship
74 if a relationship already exists clear it"""
75 if obj == self.obj: raise RelationshipExistsError
76 self._remoteRemove()
77 self.obj = aq_base(obj)
78 self.__primary_parent__._p_changed = True
79
80
82 """remove the to one side of a relationship"""
83 if obj == None or obj == self.obj:
84 self.obj = None
85 self.__primary_parent__._p_changed = True
86 else:
87 raise ObjectNotFound( "on %s: %s is not %s" % (
88 self.getPrimaryId(), obj.getPrimaryId(),
89 self.obj.getPrimaryId()) )
90
91
93 """clear the remote side of this relationship"""
94 if self.obj:
95 if obj != None and obj != self.obj: raise ObjectNotFound
96 remoteRel = getattr(aq_base(self.obj), self.remoteName())
97 remoteRel._remove(self.__primary_parent__)
98
99
100 security.declareProtected('View', 'getRelatedId')
107
108
110 """
111 Create ToOne copy. If this is the one side of one to many
112 we set our side of the relation to point towards the related
113 object (maintain the relationship across the copy).
114 """
115 rel = self.__class__(self.id)
116 rel.__primary_parent__ = container
117 rel = rel.__of__(container)
118 if (self.remoteTypeName() == "ToMany" and self.obj):
119 rel.addRelation(self.obj)
120 return rel
121
122
124 """Don't do anything here because we have on containment"""
125 pass
126
128 """Don't do anything here because we have on containment"""
129 pass
130
132 """
133 There are 4 possible states during when beforeDelete is called.
134 They are defined by the attribute _operation and can be:
135 -1 = object being deleted remove relation
136 0 = copy, 1 = move, 2 = rename
137 Any state less than 1 will provoke deletion of the remote end of the
138 relationship.
139 ToOne doesn't call beforeDelete on its related object because its
140 not a container.
141 """
142 unused(container)
143 if (getattr(item, "_operation", -1) < 1
144 and self.remoteTypeName() != 'ToManyCont'):
145 self._remoteRemove()
146
147
149 """ZMI function to return the workspace of the related object"""
150 if self.obj:
151 objurl = self.obj.getPrimaryUrlPath()
152 REQUEST['RESPONSE'].redirect(objurl+'/manage_workspace')
153 else:
154 return MessageDialog(
155 title = "No Relationship Error",
156 message = "This relationship does not currently point" \
157 " to an object",
158 action = "manage_main")
159
160
161 - def manage_main(self, REQUEST=None):
162 """ZMI function to redirect to parent relationship manager"""
163 REQUEST['RESPONSE'].redirect(
164 self.getPrimaryParent().getPrimaryUrlPath()+'/manage_workspace')
165
166
167
168 security.declareProtected('View', 'getPrimaryLink')
170 """get the link tag of a related object"""
171 link = ""
172 if self.obj:
173 if not self.obj.checkRemotePerm("View", self.obj):
174 link = self.obj.id
175 else:
176 link = "<a href='%s'>%s</a>" % (self.obj.getPrimaryUrlPath(),
177 self.obj.id)
178 return link
179
180
182 """Return the primary URL for our related object.
183 """
184 return self.obj.getPrimaryUrlPath()
185
186
188 """return an xml representation of a ToOneRelationship
189 <toone id='cricket'>
190 /Monitors/Cricket/crk0.srv.hcvlny.cv.net
191 </toone>"""
192 from RelSchema import ToManyCont
193 if not self.obj or self.remoteType()==ToManyCont: return
194 ofile.write("<toone id='%s' objid='%s'/>\n" % (
195 self.id, self.obj.getPrimaryId()))
196
197
199 """Check to make sure that relationship bidirectionality is ok.
200 """
201 if not self.obj: return
202 log.info("checking relation: %s", self.id)
203 try:
204 ppath = self.obj.getPrimaryPath()
205 self.getObjByPath(ppath)
206 except KeyError:
207 log.critical("obj:%s rel:%s robj:%s no longer exists",
208 self.getPrimaryId(), self.id, self.obj.getPrimaryId())
209 if repair:
210 log.warn("removing rel to:%s", self.obj.getPrimaryId())
211 self.obj = None
212 rname = self.remoteName()
213 rrel = getattr(self.obj, rname)
214 parobj = self.getPrimaryParent()
215 if not rrel.hasobject(parobj):
216 log.critical("obj:%s rel:%s robj:%s rrel:%s doesn't point back",
217 parobj.getPrimaryId(),self.id,self.obj.getPrimaryId(),rname)
218 if repair:
219 log.warn("adding obj:%s to rrel:%s",
220 self.getPrimaryId(),rname)
221 rrel._add(parobj)
222
223
224 InitializeClass(ToOneRelationship)
225