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

# Source Code for Module Products.ZenRelations.ToOneRelationship

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved.
      4  #
      5  # This content is made available according to terms specified in
      6  # License.zenoss under the directory where your Zenoss product is installed.
      7  #
      8  ##############################################################################
      9
     10
     11  __doc__="""ToOneRelationship
     12
     13  ToOneRelationship is a class used on a RelationshipManager
     14  to give it toOne management Functions.
     15  """
     16
     17  import sys
     18  import logging
     19  log = logging.getLogger("zen.Relations")
     20
     21
     22  # Base classes for ToOneRelationship
     23  from RelationshipBase import RelationshipBase
     24
     25  from Globals import InitializeClass
     26  from Globals import DTMLFile
     27  from AccessControl import ClassSecurityInfo
     28  from App.Dialogs import MessageDialog
     29  from Acquisition import aq_base
     30
     31  from zExceptions import NotFound
     32  from Products.ZenRelations.Exceptions import *
     33  from Products.ZenUtils.Utils import unused, getObjByPath
     34  from Products.ZenUtils.tbdetail import log_tb
     35
     36 -def manage_addToOneRelationship(context, id, REQUEST = None):
     37      """ToOneRelationship Factory"""
     38      r =  ToOneRelationship(id)
     39      context._setObject(id, r)
     40      if REQUEST:
     41          REQUEST['RESPONSE'].redirect(context.absolute_url()+'/manage_main')
     42
     43
     44
     45  addToOneRelationship = DTMLFile('dtml/addToOneRelationship',globals())
     46
     47
     48 -class ToOneRelationship(RelationshipBase):
     49      """ToOneRelationship represents a to one Relationship
     50      on a RelationshipManager"""
     51
     52      meta_type = 'ToOneRelationship'
     53
     54      security = ClassSecurityInfo()
     55
     56
     57 -    def __init__(self, id):
     58          self.id = id
     59          self.obj = None
     60
     61
     62 -    def __call__(self):
     63          """return the related object when a ToOne relation is called"""
     64          # Disabling relationship checking code.
     65          # http://dev.zenoss.org/trac/ticket/5391
     66          #self.checkRelation(True)
     67          return self.obj
     68
     69
     70 -    def hasobject(self, obj):
     71          """does this relation point to the object passed"""
     72          return self.obj == obj
     73
     74
     75 -    def _add(self, obj):
     76          """add a to one side of a relationship
     77          if a relationship already exists clear it"""
     78          if obj == self.obj: raise RelationshipExistsError
     79          self._remoteRemove()
     80          self.obj = aq_base(obj)
     81          self.__primary_parent__._p_changed = True
     82
     83
     84 -    def _remove(self,obj=None, suppress_events=False):
     85          """remove the to one side of a relationship"""
     86          if obj == None or obj == self.obj:
     87              self.obj = None
     88              self.__primary_parent__._p_changed = True
     89          else:
     90              raise ObjectNotFound( "object %s was not found on %s" % (obj, self))
     91
     92
     93 -    def _remoteRemove(self, obj=None):
     94          """clear the remote side of this relationship"""
     95          if self.obj:
     96              if obj != None and obj != self.obj:
     97                  raise ObjectNotFound(
     98                          "object %s was not found on %s it has object %s" %
     99                          (obj.getPrimaryId(), self.getPrimaryId(),
    100                          self.obj.getPrimaryId()))
    101              remoteRel = getattr(aq_base(self.obj), self.remoteName())
    102              try:
    103                  remoteRel._remove(self.__primary_parent__)
    104              except ObjectNotFound:
    105                  message = log_tb(sys.exc_info())
    106                  log.error('Remote remove failed. Run "zenchkrels -r -x1". ' + message)
    107
    108
    109      security.declareProtected('View', 'getRelatedId')
    110 -    def getRelatedId(self):
    111          '''return the id of the our related object'''
    112          if self.obj:
    113              return self.obj.id
    114          else:
    115              return None
    116
    117
    118 -    def _getCopy(self, container):
    119          """
    120          Create ToOne copy. If this is the one side of one to many
    121          we set our side of the relation to point towards the related
    122          object (maintain the relationship across the copy).
    123          """
    124          rel = self.__class__(self.id)
    125          rel.__primary_parent__ = container
    126          rel = rel.__of__(container)
    127          if (self.remoteTypeName() == "ToMany" and self.obj):
    128              rel.addRelation(self.obj)
    129          return rel
    130
    131
    132 -    def manage_afterAdd(self, item, container):
    133          """Don't do anything here because we have on containment"""
    134          pass
    135
    136
    137 -    def manage_afterClone(self, item):
    138          """Don't do anything here because we have on containment"""
    139          pass
    140
    141
    142 -    def manage_workspace(self, REQUEST):
    143          """ZMI function to return the workspace of the related object"""
    144          if self.obj:
    145              objurl = self.obj.getPrimaryUrlPath()
    146              REQUEST['RESPONSE'].redirect(objurl+'/manage_workspace')
    147          else:
    148              return MessageDialog(
    149                  title = "No Relationship Error",
    150                  message = "This relationship does not currently point" \
    151                              " to an object",
    152                  action = "manage_main")
    153
    154
    155 -    def manage_main(self, REQUEST=None):
    156          """ZMI function to redirect to parent relationship manager"""
    157          REQUEST['RESPONSE'].redirect(
    158              self.getPrimaryParent().getPrimaryUrlPath()+'/manage_workspace')
    159
    160
    161      #FIXME - please make me go away, I'm so ugly!
    162      security.declareProtected('View', 'getPrimaryLink')
    163 -    def getPrimaryLink(self, target=None):
    164          """get the link tag of a related object"""
    165          link = ""
    166          if self.obj:
    167              if not self.obj.checkRemotePerm("View", self.obj):
    168                  link = self.obj.id
    169              else:
    170                  attributes = ''
    171                  if target is not None:
    172                      attributes = "target='%s' " % (target,)
    173                  link = "<a %shref='%s'>%s</a>" % (
    174                      attributes,
    175                      self.obj.getPrimaryUrlPath(),
    176                      self.obj.id)
    177          return link
    178
    179
    180 -    def getPrimaryHref(self):
    181          """Return the primary URL for our related object.
    182          """
    183          return self.obj.getPrimaryUrlPath()
    184
    185
    186 -    def exportXml(self,ofile,ignorerels=[]):
    187          """return an xml representation of a ToOneRelationship
    188          <toone id='cricket'>
    189              /Monitors/Cricket/crk0.srv.hcvlny.cv.net
    190          </toone>"""
    191          from RelSchema import ToManyCont
    192          if not self.obj or self.remoteType()==ToManyCont: return
    193          ofile.write("<toone id='%s' objid='%s'/>\n" % (
    194                      self.id, self.obj.getPrimaryId()))
    195
    196
    197 -    def checkRelation(self, repair=False):
    198          """Check to make sure that relationship bidirectionality is ok.
    199          """
    200          if not self.obj: return
    201          log.debug("checking relation: %s", self.id)
    202
    203          try:
    204              ppath = self.obj.getPrimaryPath()
    205              getObjByPath(self, ppath)
    206          except (KeyError, NotFound):
    207              log.error("object %s in relation %s has been deleted " \
    208                           "from its primary path",
    209                           self.obj.getPrimaryId(), self.getPrimaryId())
    210              if repair:
    211                  log.warn("removing object %s from relation %s",
    212                           self.obj.getPrimaryId(), self.getPrimaryId())
    213                  self.obj = None
    214
    215          if not self.obj: return
    216
    217          rname = self.remoteName()
    218          rrel = getattr(self.obj, rname)
    219          parobj = self.getPrimaryParent()
    220          if not rrel.hasobject(parobj):
    221              log.error("remote relation %s doesn't point back to %s",
    222                        rrel.getPrimaryId(), self.getPrimaryId())
    223              if repair:
    224                  log.warn("reconnecting relation %s to relation %s",
    225                          rrel.getPrimaryId(), self.getPrimaryId())
    226                  rrel._add(parobj)
    227
    228
    229  InitializeClass(ToOneRelationship)
    230