Back to index

plone3  3.1.7
CatalogMultiplex.py
Go to the documentation of this file.
00001 from debug import log
00002 from logging import WARNING
00003 
00004 from Acquisition import aq_base
00005 from AccessControl import ClassSecurityInfo
00006 from Globals import InitializeClass
00007 from Products.CMFCore.permissions import ModifyPortalContent
00008 from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
00009 from Products.CMFCore.utils import getToolByName
00010 from Products.Archetypes.config import CATALOGMAP_USES_PORTALTYPE, TOOL_NAME
00011 from Products.Archetypes.Referenceable import Referenceable
00012 from Products.Archetypes.utils import shasattr
00013 
00014 class CatalogMultiplex(CMFCatalogAware):
00015     security = ClassSecurityInfo()
00016 
00017     def __url(self):
00018         return '/'.join( self.getPhysicalPath() )
00019 
00020     def getCatalogs(self):
00021         at = getToolByName(self, TOOL_NAME, None)
00022         if at is None:
00023             return []
00024 
00025         if CATALOGMAP_USES_PORTALTYPE:
00026             return at.getCatalogsByType(self.portal_type)
00027         else:
00028             return at.getCatalogsByType(self.meta_type)
00029 
00030     security.declareProtected(ModifyPortalContent, 'indexObject')
00031     def indexObject(self):
00032         catalogs = self.getCatalogs()
00033         url = self.__url()
00034         for c in catalogs:
00035             c.catalog_object(self, url)
00036 
00037     security.declareProtected(ModifyPortalContent, 'unindexObject')
00038     def unindexObject(self):
00039         catalogs = self.getCatalogs()
00040         url = self.__url()
00041         for c in catalogs:
00042             if c._catalog.uids.get(url, None) is not None:
00043                 c.uncatalog_object(url)
00044 
00045     security.declareProtected(ModifyPortalContent, 'reindexObjectSecurity')
00046     def reindexObjectSecurity(self, skip_self=False):
00047         """update security information in all registered catalogs.
00048         """
00049         at = getToolByName(self, TOOL_NAME, None)
00050         if at is None:
00051             return
00052 
00053         catalogs = [c for c in at.getCatalogsByType(self.meta_type)
00054                                 if c is not None]
00055         path = '/'.join(self.getPhysicalPath())
00056 
00057         for catalog in catalogs:
00058             for brain in catalog.unrestrictedSearchResults(path=path):
00059                 brain_path = brain.getPath()
00060                 if brain_path == path and skip_self:
00061                     continue
00062 
00063                 # Get the object
00064                 if hasattr(aq_base(brain), '_unrestrictedGetObject'):
00065                     ob = brain._unrestrictedGetObject()
00066                 else:
00067                     # BBB: Zope 2.7
00068                     ob = self.unrestrictedTraverse(brain_path, None)
00069                 if ob is None:
00070                     # BBB: Ignore old references to deleted objects.
00071                     # Can happen only in Zope 2.7, or when using
00072                     # catalog-getObject-raises off in Zope 2.8
00073                     log("reindexObjectSecurity: Cannot get %s from catalog" % 
00074                         brain_path, level=WARNING)
00075                     continue
00076 
00077                 # Recatalog with the same catalog uid.
00078                 catalog.reindexObject(ob, idxs=self._cmf_security_indexes,
00079                                         update_metadata=0, uid=brain_path)
00080 
00081 
00082 
00083     security.declareProtected(ModifyPortalContent, 'reindexObject')
00084     def reindexObject(self, idxs=[]):
00085         """update indexes of this object in all registered catalogs.
00086 
00087         Catalogs are registered per 'meta_type' in archetypes tool.
00088 
00089         'idxs' are a list of index names. If this list is given only the given
00090         indexes are refreshed. If a index does not exist in catalog its
00091         silently ignored.
00092         """
00093         if idxs == [] and shasattr(self, 'notifyModified'):
00094             # Archetypes default setup has this defined in ExtensibleMetadata
00095             # mixin. note: this refreshes the 'etag ' too.
00096             self.notifyModified()
00097 
00098         self.http__refreshEtag()
00099 
00100         catalogs = self.getCatalogs()
00101         if not catalogs:
00102             return
00103 
00104         url = self.__url()
00105 
00106         for c in catalogs:
00107             if c is not None:
00108                 # We want the intersection of the catalogs idxs
00109                 # and the incoming list.
00110                 lst = idxs
00111                 indexes = c.indexes()
00112                 if idxs:
00113                     lst = [i for i in idxs if i in indexes]
00114                 c.catalog_object(self, url, idxs=lst)
00115 
00116         # We only make this call if idxs is not passed.
00117         #
00118         # manage_afterAdd/manage_beforeDelete from Referenceable take
00119         # care of most of the issues, but some places still expect to
00120         # call reindexObject and have the uid_catalog updated.
00121         # TODO: fix this so we can remove the following lines.
00122         if not idxs:
00123             if isinstance(self, Referenceable):
00124                 isCopy = getattr(self, '_v_is_cp', None)
00125                 if isCopy is None:
00126                     self._catalogUID(self)
00127 
00128 InitializeClass(CatalogMultiplex)