Package Products :: Package ZenUtils :: Module MultiPathIndex |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenUtils.MultiPathIndex

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2008, 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  from types import StringType, ListType, TupleType
     14  import logging
     15  LOG = logging.getLogger('ZenUtils.MultiPathIndex')
     16
     17  from Globals import DTMLFile
     18
     19  from Products.PluginIndexes.PathIndex.PathIndex import PathIndex
     20  from Products.PluginIndexes.common import safe_callable
     21
     22 -def _isSequenceOfSequences(seq):
     23      if not seq:
     24          return False
     25      if not isinstance(seq, (TupleType, ListType)):
     26          return False
     27      for item in seq:
     28          if not isinstance(item, (TupleType, ListType)):
     29              return False
     30      return True
     31
     32 -def _recursivePathSplit(seq):
     33      if isinstance(seq, (TupleType, ListType)):
     34          return map(_recursivePathSplit, seq)
     35      if '/' in seq:
     36          return seq.split('/')
     37      else:
     38          return seq
     39
     40 -class MultiPathIndex(PathIndex):
     41      """
     42      A path index that is capable of indexing multiple paths per object.
     43      """
     44      meta_type = "MultiPathIndex"
     45
     46 -    def getIndexSourceNames(self):
     47          """ return names of indexed attributes """
     48          return (self.id, )
     49
     50 -    def index_object(self, docid, obj ,threshold=100):
     51          """ hook for (Z)Catalog """
     52
     53          f = getattr(obj, self.id, None)
     54          if f is not None:
     55              if safe_callable(f):
     56                  try:
     57                      paths = f()
     58                  except AttributeError:
     59                      return 0
     60              else:
     61                  paths = f
     62          else:
     63              try:
     64                  paths = obj.getPhysicalPath()
     65              except AttributeError:
     66                  return 0
     67
     68          if not paths: return 0
     69
     70          paths = _recursivePathSplit(paths)
     71
     72          if not _isSequenceOfSequences(paths):
     73              paths = [paths]
     74
     75          # Safest to clear out all for this object first
     76          if self._unindex.has_key(docid):
     77              self.unindex_object(docid)
     78          self._unindex[docid] = set()
     79          self._length.change(1)
     80
     81          for path in paths:
     82              if not isinstance(path, (StringType, TupleType, ListType)):
     83                  raise TypeError(
     84                      'path value must be a tuple of strings')
     85              if isinstance(path, (ListType, TupleType)):
     86                  path = '/'+ '/'.join(path[1:])
     87              comps = filter(None, path.split('/'))
     88              for i in range(len(comps)):
     89                  self.insertEntry(comps[i], docid, i)
     90              self._unindex[docid].add(path)
     91
     92          return 1
     93
     94 -    def unindex_object(self, docid):
     95          """ hook for (Z)Catalog """
     96
     97          if not self._unindex.has_key(docid):
     98              # That docid isn't indexed.
     99              return
    100
    101          for item in self._unindex[docid]:
    102              comps =  item.split('/')
    103
    104              for level in range(len(comps[1:])):
    105                  comp = comps[level+1]
    106
    107                  try:
    108                      self._index[comp][level].remove(docid)
    109
    110                      if not self._index[comp][level]:
    111                          del self._index[comp][level]
    112
    113                      if not self._index[comp]:
    114                          del self._index[comp]
    115                  except KeyError:
    116                      # We've already unindexed this one.
    117                      pass
    118
    119          self._length.change(-1)
    120          del self._unindex[docid]
    121
    122      manage = manage_main = DTMLFile('dtml/manageMultiPathIndex', globals())
    123      manage_main._setName('manage_main')
    124
    125
    126  manage_addMultiPathIndexForm = DTMLFile('dtml/addMultiPathIndex', globals())
    127
    128 -def manage_addMultiPathIndex(self, id, REQUEST=None, RESPONSE=None,
    129                               URL3=None):
    130      """
    131      Add a MultiPathIndex.
    132      """
    133      return self.manage_addIndex(id, 'MultiPathIndex', extra=None,
    134                                  REQUEST=REQUEST, RESPONSE=RESPONSE,
    135                                  URL1=URL3)
    136