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 $Id: ToOneRelationship.py,v 1.23 2003/10/02 20:48:22 edahl Exp $"""
20
21 __version__ = "$Revision: 1.23 $"[11:-2]
22
23 import copy
24
25 import logging
26 log = logging.getLogger("zen.Relations")
27
28
29
30 from RelationshipBase import RelationshipBase
31
32 from Globals import InitializeClass
33 from Globals import DTMLFile
34 from AccessControl import ClassSecurityInfo
35 from App.Dialogs import MessageDialog
36 from Acquisition import aq_base, aq_parent
37
38 from Products.ZenRelations.Exceptions import *
39
46
47
48
49 addToOneRelationship = DTMLFile('dtml/addToOneRelationship',globals())
50
51
53 """ToOneRelationship represents a to one Relationship
54 on a RelationshipManager"""
55
56 meta_type = 'ToOneRelationship'
57
58 security = ClassSecurityInfo()
59
60
64
65
67 """return the related object when a ToOne relation is called"""
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
92
93
95 """clear the remote side of this relationship"""
96 if self.obj:
97 if obj != None and obj != self.obj: raise ObjectNotFound
98 remoteRel = getattr(aq_base(self.obj), self.remoteName())
99 remoteRel._remove(self.__primary_parent__)
100
101
102 security.declareProtected('View', 'getRelatedId')
109
110
112 """
113 Create ToOne copy. If this is the one side of one to many
114 we set our side of the relation to point towards the related
115 object (maintain the relationship across the copy).
116 """
117 rel = self.__class__(self.id)
118 rel.__primary_parent__ = container
119 rel = rel.__of__(container)
120 if (self.remoteTypeName() == "ToMany" and self.obj):
121 rel.addRelation(self.obj)
122 return rel
123
124
126 """Don't do anything here because we have on containment"""
127 pass
128
130 """Don't do anything here because we have on containment"""
131 pass
132
134 """
135 There are 4 possible states during when beforeDelete is called.
136 They are defined by the attribute _operation and can be:
137 -1 = object being deleted remove relation
138 0 = copy, 1 = move, 2 = rename
139 Any state less than 1 will provoke deletion of the remote end of the
140 relationship.
141 ToOne doesn't call beforeDelete on its related object because its
142 not a container.
143 """
144 if (getattr(item, "_operation", -1) < 1
145 and self.remoteTypeName() != 'ToManyCont'):
146 self._remoteRemove()
147
148
150 """ZMI function to return the workspace of the related object"""
151 if self.obj:
152 objurl = self.obj.getPrimaryUrlPath()
153 REQUEST['RESPONSE'].redirect(objurl+'/manage_workspace')
154 else:
155 return MessageDialog(
156 title = "No Relationship Error",
157 message = "This relationship does not currently point" \
158 " to an object",
159 action = "manage_main")
160
161
162 - def manage_main(self, REQUEST=None):
163 """ZMI function to redirect to parent relationship manager"""
164 REQUEST['RESPONSE'].redirect(
165 self.getPrimaryParent().getPrimaryUrlPath()+'/manage_workspace')
166
167
168
169 security.declareProtected('View', 'getPrimaryLink')
171 """get the link tag of a related object"""
172 link = ""
173 if self.obj:
174 if not self.obj.checkRemotePerm("View", self.obj):
175 link = self.obj.id
176 else:
177 link = "<a href='%s'>%s</a>" % (self.obj.getPrimaryUrlPath(),
178 self.obj.id)
179 return link
180
181
183 """Return the primary URL for our related object.
184 """
185 return self.obj.getPrimaryUrlPath()
186
187
189 """return an xml representation of a ToOneRelationship
190 <toone id='cricket'>
191 /Monitors/Cricket/crk0.srv.hcvlny.cv.net
192 </toone>"""
193 from RelSchema import ToManyCont
194 if not self.obj or self.remoteType()==ToManyCont: return
195 ofile.write("<toone id='%s' objid='%s'/>\n" % (
196 self.id, self.obj.getPrimaryId()))
197
198
200 """Check to make sure that relationship bidirectionality is ok.
201 """
202 if not self.obj: return
203 log.info("checking relation: %s", self.id)
204 try:
205 ppath = self.obj.getPrimaryPath()
206 self.getObjByPath(ppath)
207 except KeyError:
208 log.critical("obj:%s rel:%s robj:%s no longer exists",
209 self.getPrimaryId(), self.id, self.obj.getPrimaryId())
210 if repair:
211 log.warn("removing rel to:%s", self.obj.getPrimaryId())
212 self.obj = None
213 rname = self.remoteName()
214 rrel = getattr(self.obj, rname)
215 parobj = self.getPrimaryParent()
216 if not rrel.hasobject(parobj):
217 log.critical("obj:%s rel:%s robj:%s rrel:%s doesn't point back",
218 parobj.getPrimaryId(),self.id,self.obj.getPrimaryId(),rname)
219 if repair:
220 log.warn("adding obj:%s to rrel:%s",
221 self.getPrimaryId(),rname)
222 rrel._add(parobj)
223
224
225 InitializeClass(ToOneRelationship)
226