Back to index

plone3  3.1.7
exportimport.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2005 Zope Corporation and Contributors. All Rights
00004 # Reserved.
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE
00013 #
00014 ##############################################################################
00015 """ GenericSetup export / import support for PluginRegistry.
00016 
00017 $Id: exportimport.py 74714 2007-04-24 18:21:57Z tseaver $
00018 """
00019 from StringIO import StringIO
00020 
00021 from Persistence import PersistentMapping
00022 from zope.interface import implements
00023 
00024 from Products.GenericSetup.interfaces import IFilesystemExporter
00025 from Products.GenericSetup.interfaces import IFilesystemImporter
00026 from Products.GenericSetup.content import FauxDAVRequest
00027 from Products.GenericSetup.content import FauxDAVResponse
00028 from Products.GenericSetup.utils import ExportConfiguratorBase
00029 from Products.GenericSetup.utils import ImportConfiguratorBase
00030 from Products.GenericSetup.utils import _getDottedName
00031 from Products.GenericSetup.utils import _resolveDottedName
00032 from Products.GenericSetup.utils import CONVERTER
00033 from Products.GenericSetup.utils import DEFAULT
00034 from Products.GenericSetup.utils import KEY
00035 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
00036 
00037 from interfaces import IPluginRegistry
00038 
00039 def _providedBy(obj, iface):
00040     try:
00041         return iface.providedBy(obj)
00042     except AttributeError:
00043         return iface.isImplementedBy(obj) # Z2 interfaces
00044 
00045 _FILENAME = 'pluginregistry.xml'
00046 
00047 def _getRegistry(site):
00048     registries = [x for x in site.objectValues()
00049                     if _providedBy(x, IPluginRegistry)]
00050 
00051     if len(registries) < 1:
00052         raise ValueError, 'No plugin registries'
00053 
00054     if len(registries) > 1:
00055         raise ValueError, 'Too many plugin registries'
00056 
00057     return registries[0]
00058 
00059 def exportPluginRegistry(context):
00060     """ Export plugin registry as an XML file.
00061 
00062     o Designed for use as a GenericSetup export step.
00063     """
00064     registry = _getRegistry(context.getSite())
00065     pre = PluginRegistryExporter(registry).__of__(registry)
00066     xml = pre.generateXML()
00067     context.writeDataFile(_FILENAME, xml, 'text/xml')
00068 
00069     return 'Plugin registry exported.'
00070 
00071 def _updatePluginRegistry(registry, xml, should_purge, encoding=None):
00072 
00073     if should_purge:
00074 
00075         registry._plugin_types = []
00076         registry._plugin_type_info = PersistentMapping()
00077         registry._plugins = PersistentMapping()
00078 
00079     pir = PluginRegistryImporter(registry, encoding)
00080     reg_info = pir.parseXML(xml)
00081 
00082     for info in reg_info['plugin_types']:
00083         iface = _resolveDottedName(info['interface'])
00084         # Avoid duplicate plugin types
00085         if iface not in registry._plugin_types:
00086             registry._plugin_types.append(iface)
00087         registry._plugin_type_info[iface] = {'id': info['id'],
00088                                              'title': info['title'],
00089                                              'description': info['description'],
00090                                             }
00091         registry._plugins[iface] = tuple([x['id'] for x in info['plugins']])
00092 
00093 def importPluginRegistry(context):
00094     """ Import plugin registry from an XML file.
00095 
00096     o Designed for use as a GenericSetup import step.
00097     """
00098     registry = _getRegistry(context.getSite())
00099     encoding = context.getEncoding()
00100 
00101     xml = context.readDataFile(_FILENAME)
00102     if xml is None:
00103         return 'Site properties: Nothing to import.'
00104 
00105     _updatePluginRegistry(registry, xml, context.shouldPurge(), encoding)
00106 
00107     return 'Plugin registry imported.'
00108 
00109 class PluginRegistryExporter(ExportConfiguratorBase):
00110 
00111     def __init__(self, context, encoding=None):
00112         ExportConfiguratorBase.__init__(self, None, encoding)
00113         self.context = context
00114 
00115     def _getExportTemplate(self):
00116         return PageTemplateFile('xml/pirExport.xml', globals())
00117 
00118     def listPluginTypes(self):
00119         for info in self.context.listPluginTypeInfo():
00120             iface = info['interface']
00121             info['interface'] = _getDottedName(iface)
00122             info['plugins'] = self.context.listPluginIds(iface)
00123             yield info
00124 
00125 class PluginRegistryImporter(ImportConfiguratorBase):
00126 
00127     def __init__(self, context, encoding=None):
00128         ImportConfiguratorBase.__init__(self, None, encoding)
00129         self.context = context
00130 
00131     def _getImportMapping(self):
00132 
00133         return {
00134           'plugin-registry':
00135             {'plugin-type': {KEY: 'plugin_types', DEFAULT: ()},
00136             },
00137           'plugin-type':
00138             {'id':          {KEY: 'id'},
00139              'interface':   {KEY: 'interface'},
00140              'title':       {KEY: 'title'},
00141              'description': {KEY: 'description'},
00142              'plugin':      {KEY: 'plugins', DEFAULT: ()}
00143             },
00144           'plugin':
00145             {'id':          {KEY: 'id'},
00146             },
00147          }
00148 
00149 class PluginRegistryFileExportImportAdapter(object):
00150     """ Designed for ues when exporting / importing PR's within a container.
00151     """
00152     implements(IFilesystemExporter, IFilesystemImporter)
00153 
00154     def __init__(self, context):
00155         self.context = context
00156 
00157     def export(self, export_context, subdir, root=False):
00158         """ See IFilesystemExporter.
00159         """
00160         context = self.context
00161         pre = PluginRegistryExporter(context).__of__(context)
00162         xml = pre.generateXML()
00163         export_context.writeDataFile(_FILENAME,
00164                                      xml,
00165                                      'text/xml',
00166                                      subdir,
00167                                     )
00168 
00169     def listExportableItems(self):
00170         """ See IFilesystemExporter.
00171         """
00172         return ()
00173 
00174     def import_(self, import_context, subdir, root=False):
00175         """ See IFilesystemImporter.
00176         """
00177         data = import_context.readDataFile(_FILENAME, subdir)
00178         if data is None:
00179             import_context.note('SGAIFA',
00180                                 'no pluginregistry.xml in %s' % subdir)
00181         else:
00182             request = FauxDAVRequest(BODY=data, BODYFILE=StringIO(data))
00183             response = FauxDAVResponse()
00184             _updatePluginRegistry(self.context,
00185                                   data,
00186                                   import_context.shouldPurge(),
00187                                   import_context.getEncoding(),
00188                                  )