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

# Source Code for Module Products.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 or (at your
      8  # option) any later version as published by 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, 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
     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
    134 -    def manage_afterClone(self, item):
    135          """Don't do anything here because we have on containment"""
    136          pass
    137
    138
    139 -    def manage_workspace(self, REQUEST):
    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      #FIXME - please make me go away, I'm so ugly!
    159      security.declareProtected('View', 'getPrimaryLink')
    160 -    def getPrimaryLink(self, target=None):
    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
    177 -    def getPrimaryHref(self):
    178          """Return the primary URL for our related object.
    179          """
    180          return self.obj.getPrimaryUrlPath()
    181
    182
    183 -    def exportXml(self,ofile,ignorerels=[]):
    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
    194 -    def checkRelation(self, repair=False):
    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