Package ZenRelations :: Module ToOneRelationship
[hide private]
[frames] | no frames]

Source Code for Module ZenRelations.ToOneRelationship

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 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  # Base classes for ToOneRelationship 
 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   
37 -def manage_addToOneRelationship(context, id, REQUEST = None):
38 """ToOneRelationship Factory""" 39 r = ToOneRelationship(id) 40 context._setObject(id, r) 41 if REQUEST: 42 REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
43 44 45 46 addToOneRelationship = DTMLFile('dtml/addToOneRelationship',globals()) 47 48
49 -class ToOneRelationship(RelationshipBase):
50 """ToOneRelationship represents a to one Relationship 51 on a RelationshipManager""" 52 53 meta_type = 'ToOneRelationship' 54 55 security = ClassSecurityInfo() 56 57
58 - def __init__(self, id):
59 self.id = id 60 self.obj = None
61 62
63 - def __call__(self):
64 """return the related object when a ToOne relation is called""" 65 # Disabling relationship checking code. 66 # http://dev.zenoss.org/trac/ticket/5391 67 #self.checkRelation(True) 68 return self.obj
69 70
71 - def hasobject(self, obj):
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):
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
94 - def _remoteRemove(self, obj=None):
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')
107 - def getRelatedId(self):
108 '''return the id of the our related object''' 109 if self.obj: 110 return self.obj.id 111 else: 112 return None
113 114
115 - def _getCopy(self, container):
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
129 - def manage_afterAdd(self, item, container):
130 """Don't do anything here because we have on containment""" 131 pass
132
133 - def manage_afterClone(self, item):
134 """Don't do anything here because we have on containment""" 135 pass
136
137 - def manage_beforeDelete(self, item, container):
138 """ 139 There are 4 possible states during when beforeDelete is called. 140 They are defined by the attribute _operation and can be: 141 -1 = object being deleted remove relation 142 0 = copy, 1 = move, 2 = rename 143 Any state less than 1 will provoke deletion of the remote end of the 144 relationship. 145 ToOne doesn't call beforeDelete on its related object because its 146 not a container. 147 """ 148 unused(container) 149 if (getattr(item, "_operation", -1) < 1 150 and self.remoteTypeName() != 'ToManyCont'): 151 self._remoteRemove()
152 153
154 - def manage_workspace(self, REQUEST):
155 """ZMI function to return the workspace of the related object""" 156 if self.obj: 157 objurl = self.obj.getPrimaryUrlPath() 158 REQUEST['RESPONSE'].redirect(objurl+'/manage_workspace') 159 else: 160 return MessageDialog( 161 title = "No Relationship Error", 162 message = "This relationship does not currently point" \ 163 " to an object", 164 action = "manage_main")
165 166
167 - def manage_main(self, REQUEST=None):
168 """ZMI function to redirect to parent relationship manager""" 169 REQUEST['RESPONSE'].redirect( 170 self.getPrimaryParent().getPrimaryUrlPath()+'/manage_workspace')
171 172 173 #FIXME - please make me go away, I'm so ugly! 174 security.declareProtected('View', 'getPrimaryLink') 185 186
187 - def getPrimaryHref(self):
188 """Return the primary URL for our related object. 189 """ 190 return self.obj.getPrimaryUrlPath()
191 192
193 - def exportXml(self,ofile,ignorerels=[]):
194 """return an xml representation of a ToOneRelationship 195 <toone id='cricket'> 196 /Monitors/Cricket/crk0.srv.hcvlny.cv.net 197 </toone>""" 198 from RelSchema import ToManyCont 199 if not self.obj or self.remoteType()==ToManyCont: return 200 ofile.write("<toone id='%s' objid='%s'/>\n" % ( 201 self.id, self.obj.getPrimaryId()))
202 203
204 - def checkRelation(self, repair=False):
205 """Check to make sure that relationship bidirectionality is ok. 206 """ 207 if not self.obj: return 208 log.debug("checking relation: %s", self.id) 209 210 try: 211 ppath = self.obj.getPrimaryPath() 212 getObjByPath(self, ppath) 213 except (KeyError, NotFound): 214 log.error("object %s in relation %s has been deleted " \ 215 "from its primary path", 216 self.obj.getPrimaryId(), self.getPrimaryId()) 217 if repair: 218 log.warn("removing object %s from relation %s", 219 self.obj.getPrimaryId(), self.getPrimaryId()) 220 self.obj = None 221 222 if not self.obj: return 223 224 rname = self.remoteName() 225 rrel = getattr(self.obj, rname) 226 parobj = self.getPrimaryParent() 227 if not rrel.hasobject(parobj): 228 log.error("remote relation %s doesn't point back to %s", 229 rrel.getPrimaryId(), self.getPrimaryId()) 230 if repair: 231 log.warn("reconnecting relation %s to relation %s", 232 rrel.getPrimaryId(), self.getPrimaryId()) 233 rrel._add(parobj)
234 235 236 InitializeClass(ToOneRelationship) 237