def _initHandlers(self, node): for child in node.childNodes: if child.nodeName != 'subscriber': continue handler = child.getAttribute('handler') if not handler: continue factory = child.getAttribute('factory') if factory: raise ValueError, "Can not specify both a factory and a " \ "handler in a subscriber registration." if child.hasAttribute('provides'): raise ValueError, "Cannot use handler with provides " \ "in a subscriber registration." handler = _resolveDottedName(handler) for_ = child.getAttribute('for') or child.getAttribute('for_') #BBB required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) # Uninstall to prevent duplicate registrations. While this is # allowed in ZCML, GS profiles can be run multiple times. self.context.unregisterHandler(handler, required=required) if child.hasAttribute('remove'): continue self.context.registerHandler(handler, required=required)
def _initAdapters(self, node): blacklist = self._constructBlacklist() for child in node.childNodes: if child.nodeName != 'adapter': continue factory = _resolveDottedName(child.getAttribute('factory')) provided = child.getAttribute('provides') if provided in blacklist: continue provided = _resolveDottedName(provided) name = unicode(str(child.getAttribute('name'))) for_ = child.getAttribute('for') or child.getAttribute( 'for_') #BBB required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) if child.hasAttribute('remove'): self.context.unregisterAdapter(factory, required, provided, name) continue self.context.registerAdapter(factory, required=required, provided=provided, name=name)
def _initAdapters(self, node): blacklist = self._constructBlacklist() for child in node.childNodes: if child.nodeName != 'adapter': continue factory = _resolveDottedName(child.getAttribute('factory')) provided = child.getAttribute('provides') if provided in blacklist: continue provided = _resolveDottedName(provided) name = unicode(str(child.getAttribute('name'))) for_ = child.getAttribute('for') or child.getAttribute('for_') #BBB required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) if child.hasAttribute('remove'): self.context.unregisterAdapter(factory, required, provided, name) continue self.context.registerAdapter(factory, required=required, provided=provided, name=name)
def _initHandlers(self, node): for child in node.childNodes: if child.nodeName != 'subscriber': continue handler = child.getAttribute('handler') if not handler: continue factory = child.getAttribute('factory') if factory: raise ValueError, "Can not specify both a factory and a " \ "handler in a subscriber registration." if child.hasAttribute('provides'): raise ValueError, "Cannot use handler with provides " \ "in a subscriber registration." handler = _resolveDottedName(handler) for_ = child.getAttribute('for') or child.getAttribute( 'for_') #BBB required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) # Uninstall to prevent duplicate registrations. While this is # allowed in ZCML, GS profiles can be run multiple times. self.context.unregisterHandler(handler, required=required) if child.hasAttribute('remove'): continue self.context.registerHandler(handler, required=required)
def registerProfile(self, name, title, description, path, product=None, profile_type=BASE, for_=None, pre_handler=None, post_handler=None): """ See IProfileRegistry. """ profile_id = self._computeProfileId(name, product) # Typos in pre/post handler should be caught on zope startup. if pre_handler: if (not isinstance(pre_handler, types.FunctionType) and _resolveDottedName(pre_handler) is None): raise ValueError('pre_handler points to non existing ' 'function: %s' % pre_handler) if post_handler: if (not isinstance(post_handler, types.FunctionType) and _resolveDottedName(post_handler) is None): raise ValueError('post_handler points to non existing ' 'function: %s' % post_handler) info = { 'id': profile_id, 'title': title, 'description': description, 'path': path, 'product': product, 'type': profile_type, 'for': for_, 'pre_handler': pre_handler, 'post_handler': post_handler, } metadata = ProfileMetadata(path, product=product)() # metadata.xml description trumps ZCML description... awkward info.update(metadata) existing_info = self._registered.get(profile_id) if existing_info is not None: # If it is the same, we can safely accept it. # This may happen during tests. if info == existing_info: logger.warn('Duplicate profile ID with same info ignored: %s' % profile_id) return raise KeyError('Duplicate profile ID: %s' % profile_id) self._registered[profile_id] = info
def enable_ieditfinishedevent(context): """ Replaces handler registration for IObjectModifiedEvent with IEditFinishedEvent. The important part of this step is purging the component registry of old registrations for adapters. Due to the way unregistering works in the registry (by comparing actual factory instances instead of classes), we cannot rely on the registry to perform this task. """ old_for_ = """plone.multilingualbehavior.interfaces.IDexterityTranslatable zope.lifecycleevent.interfaces.IObjectModifiedEvent""" new_for_ = """plone.multilingualbehavior.interfaces.IDexterityTranslatable plone.dexterity.interfaces.IEditFinishedEvent""" handler_name = "plone.multilingualbehavior.subscriber.handler" portal = getSite() sm = portal.getSiteManager() if not IComponentRegistry.providedBy(sm): log.warning('Site manager does not provide component registry') return handler = _resolveDottedName(handler_name) required_old = [] for interface in old_for_.split(): required_old.append(_resolveDottedName(interface)) required_new = [] for interface in new_for_.split(): required_new.append(_resolveDottedName(interface)) # Very similar code is found in zope.component.registry.Components, # method unregisterHandler() # But here we compare the __class__ of each factory, not the factory # itself existing_registration = [ (r, n, f, i) for (r, n, f, i) in sm._handler_registrations if (r == tuple(required_old) and f.__class__ == handler.__class__) ] # Depending on how often the compentneregistry step had been run in the # current site, this list may contain one or many registrations for # the same pair of interfaces for existing in existing_registration: if sm.unregisterHandler( factory=existing[2], required=required_old): log.info('Unregistered old event handler') sm.registerHandler(handler, required=required_new)
def _initPortletManagerNode(self, node): """Create a portlet manager from a node """ name = str(node.getAttribute('name')) if node.hasAttribute('remove'): if self._convertToBoolean(node.getAttribute('remove')): self.context.unregisterUtility(provided=IPortletManager, name=name) return if node.hasAttribute('purge'): if self._convertToBoolean(node.getAttribute('purge')): manager = getUtility(IPortletManager, name=name) # remove global assignments for category in manager.keys(): for portlet in manager[category].keys(): del manager[category][portlet] # remove assignments from root site = self.environ.getSite() mapping = queryMultiAdapter((site, manager), IPortletAssignmentMapping) for portlet in mapping.keys(): del mapping[portlet] return registeredPortletManagers = [ r.name for r in self.context.registeredUtilities() if r.provided.isOrExtends(IPortletManager) ] if name not in registeredPortletManagers: managerClass = node.getAttribute('class') if managerClass: manager = _resolveDottedName(managerClass)() else: manager = PortletManager() managerType = node.getAttribute('type') if managerType: alsoProvides(manager, _resolveDottedName(managerType)) manager[USER_CATEGORY] = PortletCategoryMapping() manager[GROUP_CATEGORY] = PortletCategoryMapping() manager[CONTENT_TYPE_CATEGORY] = PortletCategoryMapping() self.context.registerUtility(component=manager, provided=IPortletManager, name=name)
def _updatePluginRegistry(registry, xml, should_purge, encoding=None): if should_purge: registry._plugin_types = [] registry._plugin_type_info = PersistentMapping() registry._plugins = PersistentMapping() # When PAS import is used in an extension profile, the plugin # registry will have been deleted (content import deletes by # default) but should_purge will be false; need to initialize # _plugins since PluginRegistry's constructor doesn't if registry._plugins is None: registry._plugins = PersistentMapping() pir = PluginRegistryImporter(registry, encoding) reg_info = pir.parseXML(xml) for info in reg_info['plugin_types']: iface = _resolveDottedName(info['interface']) # Avoid duplicate plugin types if iface not in registry._plugin_types: registry._plugin_types.append(iface) registry._plugin_type_info[iface] = { 'id': info['id'], 'title': info['title'], 'description': info['description'], } registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
def _updatePluginRegistry(registry, xml, should_purge, encoding=None): if should_purge: registry._plugin_types = [] registry._plugin_type_info = PersistentMapping() registry._plugins = PersistentMapping() # When PAS import is used in an extension profile, the plugin # registry will have been deleted (content import deletes by # default) but should_purge will be false; need to initialize # _plugins since PluginRegistry's constructor doesn't if registry._plugins is None: registry._plugins = PersistentMapping() pir = PluginRegistryImporter(registry, encoding) reg_info = pir.parseXML(xml) for info in reg_info['plugin_types']: iface = _resolveDottedName(info['interface']) # Avoid duplicate plugin types if iface not in registry._plugin_types: registry._plugin_types.append(iface) registry._plugin_type_info[iface] = {'id': info['id'], 'title': info['title'], 'description': info['description'], } registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
def _initPredictors(self, node): for child in node.childNodes: if child.nodeName != 'predictor': continue self._logger.warning('##TODO## Plone4Bio import predictors.') klass = _resolveDottedName(child.getAttribute('class')) name = unicode(str(child.getAttribute('name'))) self.context.registerPredictor(klass())
def registerProfile(self, name, title, description, path, product=None, profile_type=BASE, for_=None, pre_handler=None, post_handler=None): """ See IProfileRegistry. """ profile_id = self._computeProfileId(name, product) # Typos in pre/post handler should be caught on zope startup. if pre_handler: if (not isinstance(pre_handler, types.FunctionType) and _resolveDottedName(pre_handler) is None): raise ValueError('pre_handler points to non existing ' 'function: %s' % pre_handler) if post_handler: if (not isinstance(post_handler, types.FunctionType) and _resolveDottedName(post_handler) is None): raise ValueError('post_handler points to non existing ' 'function: %s' % post_handler) info = {'id': profile_id, 'title': title, 'description': description, 'path': path, 'product': product, 'type': profile_type, 'for': for_, 'pre_handler': pre_handler, 'post_handler': post_handler, } metadata = ProfileMetadata(path, product=product)() # metadata.xml description trumps ZCML description... awkward info.update(metadata) existing_info = self._registered.get(profile_id) if existing_info is not None: # If it is the same, we can safely accept it. # This may happen during tests. if info == existing_info: msg = 'Duplicate profile ID with same info ignored: %s' logger.warning(msg % profile_id) return raise KeyError('Duplicate profile ID: %s' % profile_id) self._registered[profile_id] = info
def _initPortletManagerNode(self, node): """Create a portlet manager from a node """ name = str(node.getAttribute('name')) if node.hasAttribute('remove'): if self._convertToBoolean(node.getAttribute('remove')): self.context.unregisterUtility(provided=IPortletManager, name=name) return if node.hasAttribute('purge'): if self._convertToBoolean(node.getAttribute('purge')): manager = getUtility(IPortletManager, name=name) # remove global assignments for category in manager.keys(): for portlet in manager[category].keys(): del manager[category][portlet] # remove assignments from root site = self.environ.getSite() mapping = queryMultiAdapter((site, manager), IPortletAssignmentMapping) for portlet in mapping.keys(): del mapping[portlet] return registeredPortletManagers = [r.name for r in self.context.registeredUtilities() if r.provided.isOrExtends(IPortletManager)] if name not in registeredPortletManagers: managerClass = node.getAttribute('class') if managerClass: manager = _resolveDottedName(managerClass)() else: manager = PortletManager() managerType = node.getAttribute('type') if managerType: alsoProvides(manager, _resolveDottedName(managerType)) manager[USER_CATEGORY] = PortletCategoryMapping() manager[GROUP_CATEGORY] = PortletCategoryMapping() manager[CONTENT_TYPE_CATEGORY] = PortletCategoryMapping() self.context.registerUtility(component=manager, provided=IPortletManager, name=name)
def _initSubscriptionAdapters(self, node): blacklist = self._constructBlacklist() for child in node.childNodes: if child.nodeName != 'subscriber': continue # We only handle subscribers with a factory attribute. # The handler attribute is handled by _initHandlers. # Only one of the two attributes is supported in a subscriber. factory = child.getAttribute('factory') if not factory: continue handler = child.getAttribute('handler') if handler: raise ValueError("Can not specify both a factory and a " "handler in a subscriber registration.") factory = _resolveDottedName(factory) provided = child.getAttribute('provides') if provided in blacklist: continue provided = _resolveDottedName(provided) # BBB for_ = child.getAttribute('for') or child.getAttribute('for_') required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) # Uninstall to prevent duplicate registrations. While this is # allowed in ZCML, GS profiles can be run multiple times. self.context.unregisterSubscriptionAdapter(factory, required=required, provided=provided) if child.hasAttribute('remove'): continue self.context.registerSubscriptionAdapter(factory, required=required, provided=provided)
def _initLayers(self, node): for child in node.childNodes: if child.nodeName.lower() == 'layer': name = child.getAttribute('name') if child.getAttribute('remove'): unregister_layer(name, site_manager=self.context) continue interface = _resolveDottedName(child.getAttribute('interface')) register_layer(interface, name, site_manager=self.context)
def importToolset(context): """ Import required / forbidden tools from XML file. """ site = context.getSite() encoding = context.getEncoding() logger = context.getLogger('toolset') xml = context.readDataFile(TOOLSET_XML) if xml is None: logger.debug('Nothing to import.') return setup_tool = context.getSetupTool() toolset = setup_tool.getToolsetRegistry() toolset.parseXML(xml, encoding) existing_ids = site.objectIds() for tool_id in toolset.listForbiddenTools(): if tool_id in existing_ids: site._delObject(tool_id) for info in toolset.listRequiredToolInfo(): tool_id = str(info['id']) tool_class = _resolveDottedName(info['class']) if tool_class is None: logger.info('Class %(class)s not found for tool %(id)s' % info) existing = getattr(aq_base(site), tool_id, None) # Don't even initialize the tool again, if it already exists. if existing is None: try: new_tool = tool_class() except TypeError: new_tool = tool_class(tool_id) else: try: new_tool._setId(tool_id) except (ConflictError, KeyboardInterrupt): raise except: # XXX: ImmutableId raises result of calling MessageDialog pass site._setObject(tool_id, new_tool) else: if tool_class is None: continue unwrapped = aq_base(existing) if not isinstance(unwrapped, tool_class): site._delObject(tool_id) site._setObject(tool_id, tool_class()) logger.info('Toolset imported.')
def _initSubscriptionAdapters(self, node): blacklist = self._constructBlacklist() for child in node.childNodes: if child.nodeName != 'subscriber': continue # We only handle subscribers with a factory attribute. # The handler attribute is handled by _initHandlers. # Only one of the two attributes is supported in a subscriber. factory = child.getAttribute('factory') if not factory: continue handler = child.getAttribute('handler') if handler: raise ValueError("Can not specify both a factory and a " "handler in a subscriber registration.") factory = _resolveDottedName(factory) provided = child.getAttribute('provides') if provided in blacklist: continue provided = _resolveDottedName(provided) for_ = child.getAttribute('for') or child.getAttribute('for_') #BBB required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) # Uninstall to prevent duplicate registrations. While this is # allowed in ZCML, GS profiles can be run multiple times. self.context.unregisterSubscriptionAdapter(factory, required=required, provided=provided) if child.hasAttribute('remove'): continue self.context.registerSubscriptionAdapter(factory, required=required, provided=provided)
def cleanup_portal_setup_registries(context, do_import_steps=True, do_export_steps=True, do_toolset=True): toremove = ['plonepas'] p = portal_setup = getToolByName(context, 'portal_setup') p.applyContextById(p.getBaselineContextID()) import_steps = dict( [(a, portal_setup.getImportStepMetadata(a)) for a in portal_setup.getSortedImportSteps()]) export_steps = dict( [(a, portal_setup.getExportStepMetadata(a)) for a in portal_setup.listExportSteps()]) for (test, registry, pregistry) in [ [do_import_steps, import_steps, p._import_registry], [do_export_steps, export_steps, p._export_registry], ]: if test: invalids = registry.copy() for a in invalids.keys(): try: if ( not invalids[a].get("invalid", False) and not a in toremove ): del invalids[a] except: if invalids[a] is not None: raise for item in invalids: log('Removing %s from %s' % ( item, pregistry.__class__.__name__)) remove = item in pregistry._registered if remove: pregistry.unregisterStep(item) if do_toolset: toolset = p._toolset_registry for l in ['_required', '_forbidden']: invalids = {} reg = getattr(toolset, l) for item in reg: data = reg[item] if _resolveDottedName(data['class']) is None: invalids[item] = data for item in invalids: log( 'Removing from toolset.%s: %s (%s %s)' % ( l, item, invalids[item]['id'], invalids[item]['class'], ) ) del reg[item] setattr(toolset, l, reg) commit(context)
def importToolset(context): """ Import required / forbidden tools from XML file. """ site = context.getSite() encoding = context.getEncoding() logger = context.getLogger('toolset') xml = context.readDataFile(TOOLSET_XML) if xml is None: logger.debug('Nothing to import.') return setup_tool = context.getSetupTool() toolset = setup_tool.getToolsetRegistry() toolset.parseXML(xml, encoding) existing_ids = site.objectIds() for tool_id in toolset.listForbiddenTools(): if tool_id in existing_ids: site._delObject(tool_id) for info in toolset.listRequiredToolInfo(): tool_id = str(info['id']) tool_class = _resolveDottedName(info['class']) if tool_class is None: logger.warning("Not creating required tool %(id)s, because " "class %(class)s is not found." % info) continue existing = getattr(aq_base(site), tool_id, None) # Don't even initialize the tool again, if it already exists. if existing is None: try: new_tool = tool_class() except TypeError: new_tool = tool_class(tool_id) else: new_tool._setId(tool_id) site._setObject(tool_id, new_tool) else: if tool_class is None: continue unwrapped = aq_base(existing) # don't use isinstance here as a subclass may need removing if type(unwrapped) != tool_class: site._delObject(tool_id) site._setObject(tool_id, tool_class()) logger.info('Toolset imported.')
def getStep(self, key, default=None): """ Return the I(Export|Import)Plugin registered for 'key'. o Return 'default' if no such step is registered. """ info = self._registered.get(key) if info is None: return default return _resolveDottedName(info['handler'])
def _modifyForList(self, node, for_): """Examine the "for_" nodes within a "portlet" node to populate, extend, and/or remove interface names from an existing list for_ """ modified_for = [_getDottedName(i) for i in for_] for subNode in node.childNodes: if subNode.nodeName.lower() == "for": interface_name = str(subNode.getAttribute("interface")) if subNode.hasAttribute("remove"): if interface_name in modified_for: modified_for.remove(interface_name) elif interface_name not in modified_for: modified_for.append(interface_name) if node.hasAttribute("for"): raise InvalidPortletForDefinition(node) modified_for = [_resolveDottedName(name) for name in modified_for if _resolveDottedName(name) is not None] return modified_for
def _initLayers(self, node): for child in node.childNodes: if child.nodeName.lower() == 'layer': name = child.getAttribute('name') if child.getAttribute('remove'): try: unregister_layer(name, site_manager=self.context) except KeyError as e: self._logger.info(e) continue interface = _resolveDottedName(child.getAttribute('interface')) register_layer(interface, name, site_manager=self.context)
def _modifyForList(self, node, for_): """Examine the "for_" nodes within a "portlet" node to populate, extend, and/or remove interface names from an existing list for_ """ modified_for = [_getDottedName(i) for i in for_] for subNode in node.childNodes: if subNode.nodeName.lower() == 'for': interface_name = str(subNode.getAttribute('interface')) if subNode.hasAttribute('remove'): if interface_name in modified_for: modified_for.remove(interface_name) elif interface_name not in modified_for: modified_for.append(interface_name) if node.hasAttribute("for"): raise InvalidPortletForDefinition(node) modified_for = [_resolveDottedName(name) for name in modified_for \ if _resolveDottedName(name) is not None] return modified_for
def cleanup_portal_setup_registries(context, do_import_steps=True, do_export_steps=True, do_toolset=True): toremove = ['plonepas'] p = portal_setup = getToolByName(context, 'portal_setup') p.applyContextById(p.getBaselineContextID()) import_steps = dict([(a, portal_setup.getImportStepMetadata(a)) for a in portal_setup.getSortedImportSteps()]) export_steps = dict([(a, portal_setup.getExportStepMetadata(a)) for a in portal_setup.listExportSteps()]) for (test, registry, pregistry) in [ [do_import_steps, import_steps, p._import_registry], [do_export_steps, export_steps, p._export_registry], ]: if test: invalids = registry.copy() for a in invalids.keys(): try: if (not invalids[a].get("invalid", False) and not a in toremove): del invalids[a] except: if invalids[a] is not None: raise for item in invalids: log('Removing %s from %s' % (item, pregistry.__class__.__name__)) remove = item in pregistry._registered if remove: pregistry.unregisterStep(item) if do_toolset: toolset = p._toolset_registry for l in ['_required', '_forbidden']: invalids = {} reg = getattr(toolset, l) for item in reg: data = reg[item] if _resolveDottedName(data['class']) is None: invalids[item] = data for item in invalids: log('Removing from toolset.%s: %s (%s %s)' % ( l, item, invalids[item]['id'], invalids[item]['class'], )) del reg[item] setattr(toolset, l, reg) commit(context)
def getStepMetadata(self, key, default=None): """ Return a mapping of metadata for the step identified by 'key'. o Return 'default' if no such step is registered. o The 'handler' metadata is available via 'getStep'. """ info = self._registered.get(key) if info is None: return default result = info.copy() result['invalid'] = _resolveDottedName(result['handler']) is None return result
def _makeInstance(self, instance_id, type_name, subdir, import_context): context = self.context class _OldStyleClass: pass if '.' in type_name: factory = _resolveDottedName(type_name) if getattr(factory, '__bases__', None) is not None: def _factory(instance_id, container=self.context, klass=factory): try: instance = klass(instance_id) except (TypeError, ValueError): instance = klass() instance._setId(instance_id) container._setObject(instance_id, instance) return instance factory = _factory else: factory = queryAdapter( self.context, IContentFactory, name=type_name, ) if factory is None: return None try: instance = factory(instance_id) except ValueError: # invalid type return None if context._getOb(instance_id, None) is None: context._setObject(instance_id, instance) return context._getOb(instance_id)
def cleanupBrokenSetupRegistrations(context): """Delete portal_setup registrations from missing add-ons.""" setup = getToolByName(context, 'portal_setup') required = setup.getToolsetRegistry()._required for id_, tool in required.items(): if utils._resolveDottedName(tool['class']) is None: steps.logger.info( 'Unregistering missing required tool %r in %r' % (tool, setup)) required.pop(id_) setup._p_changed = True for profile_id in setup.listProfiles(): # Update a broken import step depdendency in the # persisent registry which has been fixed in the # profile import_steps.xml steps.logger.info( 'Applying profile context %r in %r' % (profile_id, setup)) setup.applyContextById(profile_id)
def _makeInstance(self, instance_id, type_name, subdir, import_context): context = self.context class _OldStyleClass: pass if '.' in type_name: factory = _resolveDottedName(type_name) if getattr(factory, '__bases__', None) is not None: def _factory(instance_id, container=self.context, klass=factory): try: instance = klass(instance_id) except (TypeError, ValueError): instance = klass() instance._setId(instance_id) container._setObject(instance_id, instance) return instance factory = _factory else: factory = queryAdapter(self.context, IContentFactory, name=type_name, ) if factory is None: return None try: instance = factory(instance_id) except ValueError: # invalid type return None if context._getOb(instance_id, None) is None: context._setObject(instance_id, instance) return context._getOb(instance_id)
def _updatePluginRegistry(registry, xml, should_purge, encoding=None): if should_purge: registry._plugin_types = [] registry._plugin_type_info = PersistentMapping() registry._plugins = PersistentMapping() pir = PluginRegistryImporter(registry, encoding) reg_info = pir.parseXML(xml) for info in reg_info['plugin_types']: iface = _resolveDottedName(info['interface']) registry._plugin_types.append(iface) registry._plugin_type_info[iface] = {'id': info['id'], 'title': info['title'], 'description': info['description'], } registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
def _updatePluginRegistry(registry, xml, should_purge, encoding=None): if should_purge: registry._plugin_types = [] registry._plugin_type_info = PersistentMapping() registry._plugins = PersistentMapping() pir = PluginRegistryImporter(registry, encoding) reg_info = pir.parseXML(xml) for info in reg_info['plugin_types']: iface = _resolveDottedName(info['interface']) registry._plugin_types.append(iface) registry._plugin_type_info[iface] = { 'id': info['id'], 'title': info['title'], 'description': info['description'], } registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
def registerStep( self, id, handler, title=None, description=None ): """ Register an export step. o 'id' is the unique identifier for this step o 'handler' is the dottoed name of a handler which should implement IImportPlugin. o 'title' is a one-line UI description for this step. If None, the first line of the documentation string of the step is used, or the id if no docstring can be found. o 'description' is a one-line UI description for this step. If None, the remaining line of the documentation string of the step is used, or default to ''. """ if not isinstance(handler, str): handler = _getDottedName( handler ) if title is None or description is None: method = _resolveDottedName(handler) if method is None: t,d = id, '' else: t, d = _extractDocstring( method, id, '' ) title = title or t description = description or d info = { 'id' : id , 'handler' : handler , 'title' : title , 'description' : description } self._registered[ id ] = info
def _cascadeRemove(self, cascade): """Cascaded removal of objects """ portal = getToolByName(self, 'portal_url').getPortalObject() if 'types' in cascade: portal_types=getToolByName(self,'portal_types') delObjects(portal_types, self.types) if 'skins' in cascade: portal_skins=getToolByName(self,'portal_skins') delObjects(portal_skins, self.skins) if 'actions' in cascade: portal_actions=getToolByName(self,'portal_actions') for category, action in self.actions: if category in portal_actions.objectIds(): cat = portal_actions[category] if action in cat.objectIds(): cat._delObject(action) if len(cat.objectIds()) == 0: del cat portal_actions._delObject(category) if 'portalobjects' in cascade: delObjects(portal, self.portalobjects) if 'workflows' in cascade: portal_workflow=getToolByName(self, 'portal_workflow') delObjects(portal_workflow, self.workflows) if 'slots' in cascade: if self.getLeftSlots(): portal.left_slots=[s for s in portal.left_slots if s not in self.getLeftSlots()] if self.getRightSlots(): portal.right_slots=[s for s in portal.right_slots if s not in self.getRightSlots()] if 'registrypredicates' in cascade: ctr = getToolByName(self,'content_type_registry') ids = [id for id, predicate in ctr.listPredicates()] predicates=getattr(self,'registrypredicates',[]) for p in predicates: if p in ids: ctr.removePredicate(p) else: logger.log("Failed to delete '%s' from content type " \ "registry" % p, severity=logging.WARNING) if 'adapters' in cascade: adapters = getattr(self, 'adapters', []) if adapters: sm = getSiteManager() # TODO: expand this to actually cover adapter registrations if 'utilities' in cascade: utilities = getattr(self, 'utilities', []) if utilities: sm = getSiteManager() for registration in utilities: provided = _resolveDottedName(registration[0]) name = registration[1] if queryUtility(provided, name=name) is not None: sm.unregisterUtility(provided=provided, name=name) rr_js = getToolByName(self, 'portal_javascripts', None) rr_css = getToolByName(self, 'portal_css', None) if rr_js is not None: for js in getattr(self,'resources_js',[]): rr_js.unregisterResource(js) if rr_css is not None: for css in getattr(self,'resources_css',[]): rr_css.unregisterResource(css)
def _initRules(self, node): """Import rules from the given node """ site = self.environ.getSite() storage = queryUtility(IRuleStorage) if storage is None: return for child in node.childNodes: if child.nodeName == 'rule': rule = None name = child.getAttribute('name') if name: rule = storage.get(name, None) if rule is None: rule = Rule() if not name: chooser = INameChooser(storage) name = chooser.chooseName(None, rule) storage[name] = rule else: # Clear out conditions and actions since we're expecting new ones del rule.conditions[:] del rule.actions[:] rule.title = child.getAttribute('title') rule.description = child.getAttribute('description') event_name = child.getAttribute('event') rule.event = _resolveDottedName(event_name) if not rule.event: raise ImportError("Can not import %s" % event_name) rule.enabled = as_bool(child.getAttribute('enabled'), True) rule.stop = as_bool(child.getAttribute('stop-after')) rule.cascading = as_bool(child.getAttribute('cascading')) # Aq-wrap to enable complex setters for elements below # to work rule = rule.__of__(site) for rule_config_node in child.childNodes: if rule_config_node.nodeName == 'conditions': for condition_node in rule_config_node.childNodes: if not condition_node.nodeName == 'condition': continue type_ = condition_node.getAttribute('type') element_type = getUtility(IRuleCondition, name=type_) if element_type.factory is None: continue condition = element_type.factory() # Aq-wrap in case of complex setters condition = condition.__of__(rule) handler = IRuleElementExportImportHandler(condition) handler.import_element(condition_node) rule.conditions.append(aq_base(condition)) elif rule_config_node.nodeName == 'actions': for action_node in rule_config_node.childNodes: if not action_node.nodeName == 'action': continue type_ = action_node.getAttribute('type') element_type = getUtility(IRuleAction, name=type_) if element_type.factory is None: continue action = element_type.factory() # Aq-wrap in case of complex setters action = action.__of__(rule) handler = IRuleElementExportImportHandler(action) handler.import_element(action_node) rule.actions.append(aq_base(action)) elif child.nodeName == 'assignment': location = child.getAttribute('location') if location.startswith("/"): location = location[1:] try: container = site.unrestrictedTraverse(str(location)) except KeyError: continue name = child.getAttribute('name') api.assign_rule(container, name, enabled=as_bool(child.getAttribute('enabled')), bubbles=as_bool(child.getAttribute('bubbles')), insert_before=child.getAttribute('insert-before'), )
def _initUtilities(self, node): site = self._getSite() blacklist = self._constructBlacklist() current_utilities = self.context.registeredUtilities() for child in node.childNodes: if child.nodeName != 'utility': continue provided = child.getAttribute('interface') if provided in blacklist: continue provided = _resolveDottedName(provided) name = unicode(str(child.getAttribute('name'))) component = child.getAttribute('component') component = component and _resolveDottedName(component) or None factory = child.getAttribute('factory') factory = factory and _resolveDottedName(factory) or None if component and factory: raise ValueError, "Can not specify both a factory and a " \ "component in a utility registration." obj_path = child.getAttribute('object') if not component and not factory and obj_path is not None: # Support for registering the site itself if obj_path in ('', '/'): obj = site else: # BBB: filter out path segments, we did claim to support # nested paths once id_ = [p for p in obj_path.split('/') if p][0] obj = getattr(site, id_, None) if obj is not None: self.context.registerUtility(aq_base(obj), provided, name) else: # Log an error, object not found self._logger.warning("The object %s was not found, while " "trying to register an utility. The " "provided object definition was %s. " "The site used was: %s" % (repr(obj), obj_path, repr(site))) elif component: self.context.registerUtility(component, provided, name) elif factory: current = [ utility for utility in current_utilities if utility.provided == provided and utility.name == name ] assert len(current) <= 1 if current and getattr(current[0], "factory", None) == factory: continue try: self.context.registerUtility(None, provided, name, factory=factory) except TypeError: # zope.component < 3.5.0 self.context.registerUtility(factory(), provided, name) else: self._logger.warning("Invalid utility registration for " "interface %s" % provided)
def registerStep( self , id , version=None , handler=None , dependencies=() , title=None , description=None ): """ Register a setup step. o 'id' is a unique name for this step, o 'version' is a string for comparing versions, it is preferred to be a yyyy/mm/dd-ii formatted string (date plus two-digit ordinal). when comparing two version strings, the version with the lower sort order is considered the older version. - Newer versions of a step supplant older ones. - Attempting to register an older one after a newer one results in a KeyError. o 'handler' is the dottoed name of a handler which should implement IImportPlugin. o 'dependencies' is a tuple of step ids which have to run before this step in order to be able to run at all. Registration of steps that have unmet dependencies are deferred until the dependencies have been registered. o 'title' is a one-line UI description for this step. If None, the first line of the documentation string of the handler is used, or the id if no docstring can be found. o 'description' is a one-line UI description for this step. If None, the remaining line of the documentation string of the handler is used, or default to ''. """ already = self.getStepMetadata( id ) if handler is None: raise ValueError, 'No handler specified' if already and already[ 'version' ] > version: raise KeyError( 'Existing registration for step %s, version %s' % ( id, already[ 'version' ] ) ) if not isinstance(handler, str): handler = _getDottedName( handler ) if title is None or description is None: method = _resolveDottedName(handler) if method is None: t,d = id, '' else: t, d = _extractDocstring( method, id, '' ) title = title or t description = description or d info = { 'id' : id , 'version' : version , 'handler' : handler , 'dependencies' : dependencies , 'title' : title , 'description' : description } self._registered[ id ] = info
def uninstall(context): """ """ if context.readDataFile('pmb_uninstall.txt') is None: return for_ = """plone.multilingualbehavior.interfaces.IDexterityTranslatable plone.dexterity.interfaces.IEditFinishedEvent""" handler_name = "plone.multilingualbehavior.subscriber.handler" portal = getSite() sm = portal.getSiteManager() if not IComponentRegistry.providedBy(sm): log.warning('Site manager does not provide component registry') return handler = _resolveDottedName(handler_name) required = [] for interface in for_.split(): required.append(_resolveDottedName(interface)) existing_registration = [(r, n, f, i) for (r, n, f, i) in sm._handler_registrations if (r == tuple(required) and f.__class__ == handler.__class__)] # Depending on how often the compentneregistry step had been run in the # current site, this list may contain one or many registrations for # the same pair of interfaces for existing in existing_registration: sm.unregisterHandler( factory=existing[2], # plone.multilingualbehavior.subscriber.LanguageIndependentModifier required=required) # (IDexterityTranslatable, IEditFinishedEvent) log.info('Unregistered old event handler') # gsm = getGlobalSiteManager() # adapter_hook = gsm.adapters.adapter_hook # adapters = gsm.utilities._adapters # for x in adapters[0]: # for key in adapters[0][x].keys(): # if 'plone.multilingualbehavior' in str(key): # del adapters[0][x][key] # log.info("Delete adapter {0} from {1}".format(key, x)) # gsm.utilities._adapters = adapters # provided = gsm.utilities._provided # for x in provided: # for interface in interfaces: # if interface in str(x): # del provided[x] # log.info("Delete provided {0} from {1}".format(interface, x)) # gsm.utilities._provided = provided subscribers = sm.adapters._subscribers for i, sub in enumerate(subscribers): for key in sub.keys(): if 'multilingualbehavior' in str(key): del subscribers[i][key] sm.adapters._subscribers = subscribers transaction.commit() app = portal.restrictedTraverse('/') app._p_jar.sync()
def _initRules(self, node): """Import rules from the given node """ site = self.environ.getSite() storage = queryUtility(IRuleStorage) if storage is None: return for child in node.childNodes: if child.nodeName == 'rule': rule = None name = child.getAttribute('name') if name: rule = storage.get(name, None) if rule is None: rule = Rule() if not name: chooser = INameChooser(storage) name = chooser.chooseName(None, rule) storage[name] = rule else: # Clear out conditions and actions since we're expecting # new ones del rule.conditions[:] del rule.actions[:] rule.title = child.getAttribute('title') rule.description = child.getAttribute('description') event_name = child.getAttribute('event') rule.event = _resolveDottedName(event_name) if not rule.event: raise ImportError('Can not import {0}'.format(event_name)) rule.enabled = as_bool(child.getAttribute('enabled'), True) rule.stop = as_bool(child.getAttribute('stop-after')) rule.cascading = as_bool(child.getAttribute('cascading')) # Aq-wrap to enable complex setters for elements below # to work rule = rule.__of__(site) for rule_config_node in child.childNodes: if rule_config_node.nodeName == 'conditions': for condition_node in rule_config_node.childNodes: if not condition_node.nodeName == 'condition': continue type_ = condition_node.getAttribute('type') element_type = getUtility(IRuleCondition, name=type_) if element_type.factory is None: continue condition = element_type.factory() # Aq-wrap in case of complex setters condition = condition.__of__(rule) handler = IRuleElementExportImportHandler( condition) handler.import_element(condition_node) rule.conditions.append(aq_base(condition)) elif rule_config_node.nodeName == 'actions': for action_node in rule_config_node.childNodes: if not action_node.nodeName == 'action': continue type_ = action_node.getAttribute('type') element_type = getUtility(IRuleAction, name=type_) if element_type.factory is None: continue action = element_type.factory() # Aq-wrap in case of complex setters action = action.__of__(rule) handler = IRuleElementExportImportHandler(action) handler.import_element(action_node) rule.actions.append(aq_base(action)) elif child.nodeName == 'assignment': location = child.getAttribute('location') if location.startswith('/'): location = location[1:] try: container = site.unrestrictedTraverse(str(location)) except KeyError: continue name = child.getAttribute('name') api.assign_rule( container, name, enabled=as_bool(child.getAttribute('enabled')), bubbles=as_bool(child.getAttribute('bubbles')), insert_before=child.getAttribute('insert-before'), )
def importToolset(context): """ Import tools from XML file. We don't use GenericSetup's b/c it sorts the tools alphabetically by name. The sorting happens in the toolset registry; we let that happen, but we perform the import based on the order in the XML file. """ site = context.getSite() encoding = context.getEncoding() logger = context.getLogger('mdtool') xml = context.readDataFile(TOOLSET_XML) if xml is None: logger.info('Nothing to import.') return setup_tool = context.getSetupTool() toolset = setup_tool.getToolsetRegistry() # we still let the persistent registry store the info toolset.parseXML(xml, encoding) # but we generate our own copy that retains the order from the # file ts = etree.fromstring(xml) existing_ids = site.objectIds() existing_values = site.objectValues() for tool_id in toolset.listForbiddenTools(): if tool_id in existing_ids: site._delObject(tool_id) for required in ts.xpath('//required'): info = required.attrib tool_id = str(info['tool_id']) tool_class = _resolveDottedName(info['class']) existing = getattr(aq_base(site), tool_id, None) try: new_tool = tool_class() except TypeError: new_tool = tool_class(tool_id) else: try: new_tool._setId(tool_id) except: # XXX: ImmutableId raises result of calling MessageDialog pass if existing is None: site._setObject(tool_id, new_tool) else: unwrapped = aq_base(existing) if not isinstance(unwrapped, tool_class): site._delObject(tool_id) site._setObject(tool_id, tool_class()) logger.info('MemberData tool imported.')
def _initUtilities(self, node): site = self._getSite() blacklist = self._constructBlacklist() current_utilities = self.context.registeredUtilities() for child in node.childNodes: if child.nodeName != 'utility': continue provided = child.getAttribute('interface') if provided in blacklist: continue provided = _resolveDottedName(provided) name = unicode(str(child.getAttribute('name'))) component = child.getAttribute('component') component = component and _resolveDottedName(component) or None factory = child.getAttribute('factory') factory = factory and _resolveDottedName(factory) or None if child.hasAttribute('remove'): if self.context.queryUtility(provided, name) is not None: ofs_id = self._ofs_id(child) if ofs_id in self.context.objectIds(): self.context._delObject(ofs_id, suppress_events=True) self.context.unregisterUtility(provided=provided, name=name) continue if component and factory: raise ValueError, "Can not specify both a factory and a " \ "component in a utility registration." obj_path = child.getAttribute('object') if not component and not factory and obj_path is not None: # Support for registering the site itself if obj_path in ('', '/'): obj = site else: # BBB: filter out path segments, we did claim to support # nested paths once id_ = [p for p in obj_path.split('/') if p][0] obj = getattr(site, id_, None) if obj is not None: self.context.registerUtility(aq_base(obj), provided, name) else: # Log an error, object not found self._logger.warning("The object %s was not found, while " "trying to register an utility. The " "provided object definition was %s. " "The site used was: %s" % (repr(obj), obj_path, repr(site))) elif component: self.context.registerUtility(component, provided, name) elif factory: current = [ utility for utility in current_utilities if utility.provided==provided and utility.name==name ] if current and getattr(current[0], "factory", None)==factory: continue obj = factory() ofs_id = self._ofs_id(child) if ofs_id not in self.context.objectIds(): self.context._setObject(ofs_id, aq_base(obj), set_owner=False, suppress_events=True) obj = self.context.get(ofs_id) obj.__name__ = ofs_id obj.__parent__ = aq_base(self.context) self.context.registerUtility(aq_base(obj), provided, name) else: self._logger.warning("Invalid utility registration for " "interface %s" % provided)
def _initRules(self, node): """Import rules from the given node """ site = self.environ.getSite() storage = queryUtility(IRuleStorage) if storage is None: return for child in node.childNodes: if child.nodeName == 'rule': rule = None name = child.getAttribute('name') if name: rule = storage.get(name, None) if rule is None: rule = Rule() if not name: chooser = INameChooser(storage) name = chooser.chooseName(None, rule) storage[name] = rule else: # Clear out conditions and actions since we're expecting new ones del rule.conditions[:] del rule.actions[:] rule.title = child.getAttribute('title') rule.description = child.getAttribute('description') event_name = child.getAttribute('event') rule.event = _resolveDottedName(event_name) if not rule.event: raise ImportError("Can not import %s" % event_name) rule.enabled = as_bool(child.getAttribute('enabled'), True) rule.stop = as_bool(child.getAttribute('stop-after')) # Aq-wrap to enable complex setters for elements below # to work rule = rule.__of__(site) for rule_config_node in child.childNodes: if rule_config_node.nodeName == 'conditions': for condition_node in rule_config_node.childNodes: if not condition_node.nodeName == 'condition': continue type_ = condition_node.getAttribute('type') element_type = getUtility(IRuleCondition, name=type_) if element_type.factory is None: continue condition = element_type.factory() # Aq-wrap in case of complex setters condition = condition.__of__(rule) handler = IRuleElementExportImportHandler( condition) handler.import_element(condition_node) rule.conditions.append(aq_base(condition)) elif rule_config_node.nodeName == 'actions': for action_node in rule_config_node.childNodes: if not action_node.nodeName == 'action': continue type_ = action_node.getAttribute('type') element_type = getUtility(IRuleAction, name=type_) if element_type.factory is None: continue action = element_type.factory() # Aq-wrap in case of complex setters action = action.__of__(rule) handler = IRuleElementExportImportHandler(action) handler.import_element(action_node) rule.actions.append(aq_base(action)) elif child.nodeName == 'assignment': location = child.getAttribute('location') if location.startswith("/"): location = location[1:] try: container = site.unrestrictedTraverse(str(location)) except KeyError: continue assignable = IRuleAssignmentManager(container, None) if assignable is None: continue name = child.getAttribute('name') assignment = assignable.get(name, None) if assignment is None: assignment = assignable[name] = RuleAssignment(name) assignment.enabled = as_bool(child.getAttribute('enabled')) assignment.bubbles = as_bool(child.getAttribute('bubbles')) insert_before = child.getAttribute('insert-before') if insert_before: position = None keys = list(assignable.keys()) if insert_before == "*": position = 0 elif insert_before in keys: position = keys.index(insert_before) if position is not None: keys.remove(name) keys.insert(position, name) assignable.updateOrder(keys) path = '/'.join(container.getPhysicalPath()) get_assignments(storage[name]).insert(path)
def _cascadeRemove(self, cascade): """Cascaded removal of objects """ portal = getToolByName(self, 'portal_url').getPortalObject() if 'types' in cascade: portal_types = getToolByName(self, 'portal_types') delObjects(portal_types, getattr(aq_base(self), 'types', [])) if 'skins' in cascade: portal_skins = getToolByName(self, 'portal_skins') delObjects(portal_skins, getattr(aq_base(self), 'skins', [])) if ( 'actions' in cascade and len(getattr(aq_base(self), 'actions', [])) > 0 ): portal_actions = getToolByName(self, 'portal_actions') for info in self.actions: if isinstance(info, six.string_types): action = info # Product was installed before CMF 2.1 # Try to remove the action from all categories for category in portal_actions.objectIds(): cat = portal_actions[category] if action in cat.objectIds(): cat._delObject(action) else: category, action = info if category in portal_actions.objectIds(): cat = portal_actions[category] if action in cat.objectIds(): cat._delObject(action) if len(cat.objectIds()) == 0: del cat portal_actions._delObject(category) if 'portalobjects' in cascade: delObjects(portal, getattr(aq_base(self), 'portalobjects', [])) if 'workflows' in cascade: portal_workflow = getToolByName(self, 'portal_workflow') delObjects( portal_workflow, getattr(aq_base(self), 'workflows', []) ) if 'slots' in cascade: if self.getLeftSlots(): portal.left_slots = [ s for s in portal.left_slots if s not in self.getLeftSlots() ] if self.getRightSlots(): portal.right_slots = [ s for s in portal.right_slots if s not in self.getRightSlots() ] if 'registrypredicates' in cascade: ctr = getToolByName(self, 'content_type_registry') ids = [id for id, predicate in ctr.listPredicates()] predicates = getattr(aq_base(self), 'registrypredicates', []) for pred in predicates: if pred in ids: ctr.removePredicate(pred) else: logger.warning("Failed to delete '%s' from content type " "registry" % pred) if 'adapters' in cascade: adapters = getattr(aq_base(self), 'adapters', []) if adapters: sm = getSiteManager() # TODO: expand this to actually cover adapter registrations if 'utilities' in cascade: utilities = getattr(aq_base(self), 'utilities', []) if utilities: sm = getSiteManager() mapping = sm.objectItems() for registration in utilities: provided = _resolveDottedName(registration[0]) name = registration[1] utility = queryUtility(provided, name=name) if utility is not None: sm.unregisterUtility(provided=provided, name=name) # Make sure utilities are removed from the # site manager's mapping as well for name, value in mapping: if value is utility: sm._delObject(name, suppress_events=True) rr_js = getToolByName(self, 'portal_javascripts', None) rr_css = getToolByName(self, 'portal_css', None) if rr_js is not None: for js in getattr(aq_base(self), 'resources_js', []): rr_js.unregisterResource(js) if rr_css is not None: for css in getattr(aq_base(self), 'resources_css', []): rr_css.unregisterResource(css) portal_controlpanel = getToolByName(self, 'portal_controlpanel', None) if portal_controlpanel is not None: portal_controlpanel.unregisterApplication(self.id)
def _initUtilities(self, node): site = self._getSite() blacklist = self._constructBlacklist() current_utilities = self.context.registeredUtilities() for child in node.childNodes: if child.nodeName != 'utility': continue provided = child.getAttribute('interface') if provided in blacklist: continue provided = _resolveDottedName(provided) name = unicode(str(child.getAttribute('name'))) component = child.getAttribute('component') component = component and _resolveDottedName(component) or None factory = child.getAttribute('factory') factory = factory and _resolveDottedName(factory) or None if child.hasAttribute('remove'): if self.context.queryUtility(provided, name) is not None: ofs_id = self._ofs_id(child) if ofs_id in self.context.objectIds(): self.context._delObject(ofs_id, suppress_events=True) self.context.unregisterUtility(provided=provided, name=name) continue if component and factory: raise ValueError, "Can not specify both a factory and a " \ "component in a utility registration." obj_path = child.getAttribute('object') if not component and not factory and obj_path is not None: # Support for registering the site itself if obj_path in ('', '/'): obj = site else: # BBB: filter out path segments, we did claim to support # nested paths once id_ = [p for p in obj_path.split('/') if p][0] obj = getattr(site, id_, None) if obj is not None: self.context.registerUtility(aq_base(obj), provided, name) else: # Log an error, object not found self._logger.warning("The object %s was not found, while " "trying to register an utility. The " "provided object definition was %s. " "The site used was: %s" % (repr(obj), obj_path, repr(site))) elif component: self.context.registerUtility(component, provided, name) elif factory: current = [ utility for utility in current_utilities if utility.provided == provided and utility.name == name ] if current and getattr(current[0], "factory", None) == factory: continue obj = factory() ofs_id = self._ofs_id(child) if ofs_id not in self.context.objectIds(): self.context._setObject(ofs_id, aq_base(obj), set_owner=False, suppress_events=True) try: getter = self.context.get except AttributeError: getter = self.context._getOb # BBB: Zope <= 2.10.x obj = getter(ofs_id) obj.__name__ = ofs_id obj.__parent__ = aq_base(self.context) self.context.registerUtility(aq_base(obj), provided, name) else: self._logger.warning("Invalid utility registration for " "interface %s" % provided)
def _initLayers(self, node): for child in node.childNodes: if child.nodeName.lower() == "layer": name = child.getAttribute("name") interface = _resolveDottedName(child.getAttribute("interface")) register_layer(interface, name, site_manager=self.context)
def _cascadeRemove(self, cascade): """Cascaded removal of objects """ portal = getToolByName(self, 'portal_url').getPortalObject() if 'types' in cascade: portal_types = getToolByName(self, 'portal_types') delObjects(portal_types, getattr(aq_base(self), 'types', [])) if 'skins' in cascade: portal_skins = getToolByName(self, 'portal_skins') delObjects(portal_skins, getattr(aq_base(self), 'skins', [])) if 'actions' in cascade and len(getattr(aq_base(self), 'actions', [])) > 0: portal_actions = getToolByName(self, 'portal_actions') for info in self.actions: if isinstance(info, basestring): action = info # Product was installed before CMF 2.1 # Try to remove the action from all categories for category in portal_actions.objectIds(): cat = portal_actions[category] if action in cat.objectIds(): cat._delObject(action) else: category, action = info if category in portal_actions.objectIds(): cat = portal_actions[category] if action in cat.objectIds(): cat._delObject(action) if len(cat.objectIds()) == 0: del cat portal_actions._delObject(category) if 'portalobjects' in cascade: delObjects(portal, getattr(aq_base(self), 'portalobjects', [])) if 'workflows' in cascade: portal_workflow = getToolByName(self, 'portal_workflow') delObjects(portal_workflow, getattr(aq_base(self), 'workflows', [])) if 'slots' in cascade: if self.getLeftSlots(): portal.left_slots = [s for s in portal.left_slots if s not in self.getLeftSlots()] if self.getRightSlots(): portal.right_slots = [s for s in portal.right_slots if s not in self.getRightSlots()] if 'registrypredicates' in cascade: ctr = getToolByName(self, 'content_type_registry') ids = [id for id, predicate in ctr.listPredicates()] predicates = getattr(aq_base(self), 'registrypredicates', []) for p in predicates: if p in ids: ctr.removePredicate(p) else: logger.warning("Failed to delete '%s' from content type " "registry" % p) if 'adapters' in cascade: adapters = getattr(aq_base(self), 'adapters', []) if adapters: sm = getSiteManager() # TODO: expand this to actually cover adapter registrations if 'utilities' in cascade: utilities = getattr(aq_base(self), 'utilities', []) if utilities: sm = getSiteManager() mapping = sm.objectItems() for registration in utilities: provided = _resolveDottedName(registration[0]) name = registration[1] utility = queryUtility(provided, name=name) if utility is not None: sm.unregisterUtility(provided=provided, name=name) # Make sure utilities are removed from the # site manager's mapping as well for name, value in mapping: if value is utility: sm._delObject(name, suppress_events=True) rr_js = getToolByName(self, 'portal_javascripts', None) rr_css = getToolByName(self, 'portal_css', None) if rr_js is not None: for js in getattr(aq_base(self), 'resources_js', []): rr_js.unregisterResource(js) if rr_css is not None: for css in getattr(aq_base(self), 'resources_css', []): rr_css.unregisterResource(css) portal_controlpanel = getToolByName(self, 'portal_controlpanel', None) if portal_controlpanel is not None: portal_controlpanel.unregisterApplication(self.id)