Exemple #1
0
def serializeSchema(schema):
    """ Finds the FTI and model associated with a schema, and synchronizes
        the schema to the FTI model_source attribute.

        This method only works for schemas that were created from an FTI's
        model_source property

        BBB - deprecated
    """

    # determine portal_type
    try:
        prefix, portal_type, schemaName = splitSchemaName(schema.__name__)
    except ValueError:
        # not a dexterity schema
        return

    # find the FTI and model
    fti = queryUtility(IDexterityFTI, name=portal_type)
    if fti.model_source:
        model = fti.lookupModel()

        # synchronize changes to the model
        syncSchema(schema, model.schemata[schemaName], overwrite=True)
        fti.model_source = serializeModel(model)
    else:
        raise TypeError("Changes to non-dynamic schemata not yet supported.")
Exemple #2
0
    def __call__(self):
        interface = self.interface
        filename = interface.queryTaggedValue(FILENAME_KEY, None)
        if filename is None:
            return
        schema = interface.queryTaggedValue(SCHEMA_NAME_KEY, u"")

        moduleName = interface.__module__
        module = sys.modules.get(moduleName, None)

        directory = moduleName

        if hasattr(module, '__path__'):
            directory = module.__path__[0]
        else:
            while "." in moduleName:
                moduleName, _ = moduleName.rsplit('.', 1)
                module = sys.modules.get(moduleName, None)
                if hasattr(module, '__path__'):
                    directory = module.__path__[0]
                    break

        directory = os.path.abspath(directory)
        # Let / act as path separator on all platforms
        filename = filename.replace('/', os.path.sep)
        filename = os.path.abspath(os.path.join(directory, filename))

        model = loadFile(filename)
        if schema not in model.schemata:
            raise ValueError(
                    u"Schema '%s' specified for interface %s does not exist in %s." % 
                        (schema, interface.__identifier__, filename,)) 

        syncSchema(model.schemata[schema], interface, overwrite=False)
def serializeSchema(schema):
    """ Finds the FTI and model associated with a schema, and synchronizes
        the schema to the FTI model_source attribute.

        This method only works for schemas that were created from an FTI's
        model_source property

        BBB - deprecated
    """

    # determine portal_type
    try:
        prefix, portal_type, schemaName = splitSchemaName(schema.__name__)
    except ValueError:
        # not a dexterity schema
        return

    # find the FTI and model
    fti = queryUtility(IDexterityFTI, name=portal_type)
    if fti.model_source:
        model = fti.lookupModel()

        # synchronize changes to the model
        syncSchema(schema, model.schemata[schemaName], overwrite=True)
        fti.model_source = serializeModel(model)
    else:
        raise TypeError("Changes to non-dynamic schemata not yet supported.")
Exemple #4
0
def ftiModified(object, event):
    """When an FTI is modified, re-sync and invalidate the schema, if
    necessary.
    """

    if not IDexterityFTI.providedBy(event.object):
        return

    fti = event.object
    portal_type = fti.getId()

    mod = {}
    for desc in event.descriptions:
        if IDexterityFTIModificationDescription.providedBy(desc):
            mod[desc.attribute] = desc.oldValue

    # If the factory utility name was modified, we may get an orphan if one
    # was registered as a local utility to begin with. If so, remove the
    # orphan.

    if 'factory' in mod:
        old_factory = mod['factory']

        site_manager = getGlobalSiteManager()

        # Remove previously registered factory, if no other type uses it.
        unregister_factory(old_factory, site_manager)

        # Register a new local factory if one doesn't exist already
        new_factory_utility = queryUtility(IFactory, name=fti.factory)
        if new_factory_utility is None:
            site_manager.registerUtility(DexterityFactory(portal_type),
                                         IFactory,
                                         fti.factory,
                                         info='plone.dexterity.dynamic')

    # Determine if we need to invalidate the schema at all
    if 'behaviors' in mod \
       or 'schema' in mod \
       or 'model_source' in mod \
       or 'model_file' in mod \
       or 'schema_policy' in mod:

        # Determine if we need to re-sync a dynamic schema
        if ((fti.model_source or fti.model_file)
                and ('model_source' in mod or 'model_file' in mod
                     or 'schema_policy' in mod)):

            schemaName = portalTypeToSchemaName(portal_type)
            schema = getattr(plone.dexterity.schema.generated, schemaName)

            model = fti.lookupModel()
            sync_bases = 'schema_policy' in mod
            syncSchema(model.schema,
                       schema,
                       overwrite=True,
                       sync_bases=sync_bases)

        notify(SchemaInvalidatedEvent(portal_type))
Exemple #5
0
def ftiModified(object, event):
    """When an FTI is modified, re-sync and invalidate the schema, if
    necessary.
    """

    if not IDexterityFTI.providedBy(event.object):
        return

    fti = event.object
    portal_type = fti.getId()

    mod = {}
    for desc in event.descriptions:
        if IDexterityFTIModificationDescription.providedBy(desc):
            mod[desc.attribute] = desc.oldValue

    # If the factory utility name was modified, we may get an orphan if one
    # was registered as a local utility to begin with. If so, remove the
    # orphan.

    if 'factory' in mod:
        old_factory = mod['factory']

        site = getUtility(ISiteRoot)
        site_manager = getSiteManager(site)

        # Remove previously registered factory, if no other type uses it.
        unregister_factory(old_factory, site_manager)

        # Register a new local factory if one doesn't exist already
        new_factory_utility = queryUtility(IFactory, name=fti.factory)
        if new_factory_utility is None:
            site_manager.registerUtility(
                DexterityFactory(portal_type),
                IFactory,
                fti.factory,
                info='plone.dexterity.dynamic'
            )

    # Determine if we need to invalidate the schema at all
    if 'behaviors' in mod \
       or 'schema' in mod \
       or 'model_source' in mod \
       or 'model_file' in mod \
       or 'schema_policy' in mod:

        # Determine if we need to re-sync a dynamic schema
        if (fti.model_source or fti.model_file) \
           and ('model_source' in mod or 'model_file' in mod or 'schema_policy' in mod):

            schemaName = portalTypeToSchemaName(portal_type)
            schema = getattr(plone.dexterity.schema.generated, schemaName)

            model = fti.lookupModel()
            sync_bases = 'schema_policy' in mod
            syncSchema(model.schema, schema, overwrite=True, sync_bases=sync_bases)

        notify(SchemaInvalidatedEvent(portal_type))
Exemple #6
0
    def __call__(self, name, module):
        """Someone tried to load a dynamic interface that has not yet been
        created yet. We will attempt to load it from the FTI if we can. If
        the FTI doesn't exist, create a temporary marker interface that we
        can fill later.

        The goal here is to ensure that we create exactly one interface
        instance for each name. If we can't find an FTI, we'll cache the
        interface so that we don't get a new one with a different id later.
        This cache is global, so we synchronise the method with a thread
        lock.

        Once we have a properly populated interface, we set it onto the
        module using setattr(). This means that the factory will not be
        invoked again.
        """

        try:
            prefix, portal_type, schemaName = splitSchemaName(name)
        except ValueError:
            return None

        if name in self._transient_SCHEMA_CACHE:
            schema = self._transient_SCHEMA_CACHE[name]
        else:
            bases = ()

            is_default_schema = not schemaName
            if is_default_schema:
                bases += (IDexteritySchema,)

            schema = InterfaceClass(name, bases, __module__=module.__name__)

            if is_default_schema:
                alsoProvides(schema, IContentType)
        if portal_type is not None:
            fti = queryUtility(IDexterityFTI, name=portal_type)
        else:
            fti = None
        if fti is None and name not in self._transient_SCHEMA_CACHE:
            self._transient_SCHEMA_CACHE[name] = schema
        elif fti is not None:
            model = fti.lookupModel()
            syncSchema(model.schemata[schemaName], schema, sync_bases=True)

            # Save this schema in the module - this factory will not be
            # called again for this name

            if name in self._transient_SCHEMA_CACHE:
                del self._transient_SCHEMA_CACHE[name]

            setattr(module, name, schema)

        return schema
Exemple #7
0
    def test_syncSchema_always_overwrites_fields_from_bases(self):
        class IBase(Interface):
            one = schema.TextLine(title=u'A')

        class ISource(Interface):
            one = schema.TextLine(title=u'B')

        class IDest(IBase):
            pass

        utils.syncSchema(ISource, IDest, overwrite=False)

        self.assertTrue(IDest['one'].interface is IDest)
Exemple #8
0
    def test_syncSchema_always_overwrites_fields_from_bases(self):
        class IBase(Interface):
            one = schema.TextLine(title=u"A")

        class ISource(Interface):
            one = schema.TextLine(title=u"B")

        class IDest(IBase):
            pass

        utils.syncSchema(ISource, IDest, overwrite=False)

        self.assertTrue(IDest["one"].interface is IDest)
def serializeSchemaContext(schema_context, event=None):
    """ Serializes the schema associated with a schema context.

    The serialized schema is saved to the model_source property of the FTI
    associated with the schema context.
    """
    # find the FTI and model
    fti = schema_context.fti
    schemaName = schema_context.schemaName
    schema = schema_context.schema
    model = fti.lookupModel()

    # synchronize changes to the model
    syncSchema(schema, model.schemata[schemaName], overwrite=True)
    fti.model_source = serializeModel(model)
Exemple #10
0
def serializeSchemaContext(schema_context, event=None):
    """ Serializes the schema associated with a schema context.

    The serialized schema is saved to the model_source property of the FTI
    associated with the schema context.
    """
    # find the FTI and model
    fti = schema_context.fti
    schemaName = schema_context.schemaName
    schema = schema_context.schema
    model = fti.lookupModel()

    # synchronize changes to the model
    syncSchema(schema, model.schemata[schemaName], overwrite=True)
    fti.model_source = serializeModel(model)
Exemple #11
0
    def test_syncSchema_overwrite_no_bases(self):
        class IBase(Interface):
            base = schema.TextLine(title=u"Base")

        class ISource(IBase):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=False, sync_bases=False)

        self.assertEqual((Interface,), IDest.__bases__)
        self.assertEqual(["two", "one", "three"], getFieldNamesInOrder(IDest))
Exemple #12
0
    def test_syncSchema_overwrite_no_bases(self):
        class IBase(Interface):
            base = schema.TextLine(title=u"Base")

        class ISource(IBase):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=False, sync_bases=False)

        self.assertEquals((Interface, ), IDest.__bases__)
        self.assertEquals(['two', 'one', 'three'], getFieldNamesInOrder(IDest))
Exemple #13
0
    def test_syncSchema_overwrite_with_bases(self):
        class IBase(Interface):
            base = schema.TextLine(title=u"Base")

        class IOtherBase(Interface):
            foo = schema.TextLine(title=u"Foo")

        class ISource(IBase):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")

        class IDest(IOtherBase):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=True, sync_bases=True)

        self.assertEqual((IBase, ), IDest.__bases__)
        self.assertEqual(['base', 'one', 'two'], getFieldNamesInOrder(IDest))
Exemple #14
0
    def test_syncSchema_overwrite_with_bases_and_no_overwrite_with_old_bases(self):

        class IBase(Interface):
            base = schema.TextLine(title=u"Base")

        class IOtherBase(Interface):
            foo = schema.TextLine(title=u"Foo")

        class ISource(IBase):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")

        class IDest(IOtherBase, IBase):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=False, sync_bases=True)

        self.assertEquals((IBase, IOtherBase, ), IDest.__bases__)
        self.assertEquals(['base', 'foo', 'two', 'one', 'three'], getFieldNamesInOrder(IDest))
Exemple #15
0
def serializeSchema(schema):
    """Taken from plone.app.dexterity.serialize
    Finds the FTI and model associated with a schema, and synchronizes
    the schema to the FTI model_source attribute.
    """

    # determine portal_type
    try:
        prefix, portal_type, schemaName = splitSchemaName(schema.__name__)
    except ValueError:
        # not a dexterity schema
        return

    # find the FTI and model
    fti = queryUtility(IDexterityFTI, name=portal_type)
    model = fti.lookupModel()

    # synchronize changes to the model
    syncSchema(schema, model.schemata[schemaName], overwrite=True)
    fti.model_source = serializeModel(model)
Exemple #16
0
    def test_syncSchema_with_markers_overwrite(self):
        class IMarker(Interface):
            pass

        class ISource(Interface):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")
            four = schema.Text(title=u"C")

        alsoProvides(ISource['one'], IMarker)
        alsoProvides(ISource['four'], IMarker)

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=True)

        self.failUnless(IMarker.providedBy(IDest['one']))
        self.failIf(IMarker.providedBy(IDest['two']))
        self.failUnless(IMarker.providedBy(IDest['four']))
Exemple #17
0
    def test_syncSchema_with_markers_overwrite(self):
        class IMarker(Interface):
            pass

        class ISource(Interface):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")
            four = schema.Text(title=u"C")

        alsoProvides(ISource["one"], IMarker)
        alsoProvides(ISource["four"], IMarker)

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=True)

        self.assertTrue(IMarker.providedBy(IDest["one"]))
        self.assertFalse(IMarker.providedBy(IDest["two"]))
        self.assertTrue(IMarker.providedBy(IDest["four"]))
Exemple #18
0
    def test_syncSchema(self):
        class ISource(Interface):
            one = schema.TextLine(title=u"A")  # order: 0
            two = schema.Int(title=u"B")  # order: 1

        class IDest(Interface):
            one = schema.TextLine(title=u"C")  # order: 0
            three = schema.Int(title=u"D")  # order: 1

        ISource.setTaggedValue("tag1", "tag one")
        ISource.setTaggedValue("tag2", "tag two")
        IDest.setTaggedValue("tag1", "first tag")

        utils.syncSchema(ISource, IDest)

        self.assertEqual(u"C", IDest['one'].title)

        self.assertEqual(['one', 'two'], getFieldNamesInOrder(ISource))
        self.assertEqual(['two', 'one', 'three'], getFieldNamesInOrder(IDest))

        self.assertEqual("first tag", IDest.getTaggedValue("tag1"))
        self.assertEqual("tag two", IDest.getTaggedValue("tag2"))
Exemple #19
0
    def test_syncSchema_with_markers_overwrite(self):

        class IMarker(Interface):
            pass

        class ISource(Interface):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")
            four = schema.Text(title=u"C")

        alsoProvides(ISource['one'], IMarker)
        alsoProvides(ISource['four'], IMarker)

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        utils.syncSchema(ISource, IDest, overwrite=True)

        self.failUnless(IMarker.providedBy(IDest['one']))
        self.failIf(IMarker.providedBy(IDest['two']))
        self.failUnless(IMarker.providedBy(IDest['four']))
Exemple #20
0
    def test_syncSchema_overwrite(self):
        class ISource(Interface):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        ISource.setTaggedValue("tag1", "tag one")
        ISource.setTaggedValue("tag2", "tag two")
        IDest.setTaggedValue("tag1", "first tag")

        utils.syncSchema(ISource, IDest, overwrite=True)

        self.assertEqual(u"A", IDest["one"].title)

        self.assertEqual(["one", "two"], getFieldNamesInOrder(ISource))
        self.assertEqual(["one", "two"], getFieldNamesInOrder(IDest))

        self.assertEqual("tag one", IDest.getTaggedValue("tag1"))
        self.assertEqual("tag two", IDest.getTaggedValue("tag2"))
Exemple #21
0
    def test_syncSchema_overwrite(self):
        class ISource(Interface):
            one = schema.TextLine(title=u"A")
            two = schema.Int(title=u"B")

        class IDest(Interface):
            one = schema.TextLine(title=u"C")
            three = schema.Int(title=u"D")

        ISource.setTaggedValue("tag1", "tag one")
        ISource.setTaggedValue("tag2", "tag two")
        IDest.setTaggedValue("tag1", "first tag")

        utils.syncSchema(ISource, IDest, overwrite=True)

        self.assertEquals(u"A", IDest['one'].title)

        self.assertEquals(['one', 'two'], getFieldNamesInOrder(ISource))
        self.assertEquals(['one', 'two'], getFieldNamesInOrder(IDest))

        self.assertEquals("tag one", IDest.getTaggedValue("tag1"))
        self.assertEquals("tag two", IDest.getTaggedValue("tag2"))
    def __call__(self):
        interface = self.interface
        filename = interface.queryTaggedValue(FILENAME_KEY, None)
        if filename is None:
            return
        schema = interface.queryTaggedValue(SCHEMA_NAME_KEY, u"")

        moduleName = interface.__module__
        module = sys.modules.get(moduleName, None)

        directory = moduleName

        if hasattr(module, '__path__'):
            directory = module.__path__[0]
        else:
            while "." in moduleName:
                moduleName, _ = moduleName.rsplit('.', 1)
                module = sys.modules.get(moduleName, None)
                if hasattr(module, '__path__'):
                    directory = module.__path__[0]
                    break

        directory = os.path.abspath(directory)
        # Let / act as path separator on all platforms
        filename = filename.replace('/', os.path.sep)
        filename = os.path.abspath(os.path.join(directory, filename))

        model = loadFile(filename)
        if schema not in model.schemata:
            raise ValueError(
                u"Schema '{0}' specified for interface {1} does not exist "
                "in {2}.".format(
                    schema,
                    interface.__identifier__,
                    filename,
                )
            )

        syncSchema(model.schemata[schema], interface, overwrite=False)
Exemple #23
0
    def test_syncSchema(self):

        class ISource(Interface):
            one = schema.TextLine(title=u"A") # order: 0
            two = schema.Int(title=u"B")      # order: 1

        class IDest(Interface):
            one = schema.TextLine(title=u"C") # order: 0
            three = schema.Int(title=u"D")    # order: 1

        ISource.setTaggedValue("tag1", "tag one")
        ISource.setTaggedValue("tag2", "tag two")
        IDest.setTaggedValue("tag1", "first tag")

        utils.syncSchema(ISource, IDest)

        self.assertEquals(u"C", IDest['one'].title)

        self.assertEquals(['one', 'two'], getFieldNamesInOrder(ISource))
        self.assertEquals(['two', 'one', 'three'], getFieldNamesInOrder(IDest))

        self.assertEquals("first tag", IDest.getTaggedValue("tag1"))
        self.assertEquals("tag two", IDest.getTaggedValue("tag2"))
    def run(self):
        logger.info('Migrating to imio.dms.mail 1.0...')
        self.cleanRegistries()
        self.upgradeProfile('collective.dms.mailcontent:default')
        # We have to reapply type info before doing other subproducts migration
        self.runProfileSteps('imio.dms.mail', steps=['typeinfo'])
        # We have to update type schema because plone.dexterity doesn't detect schema_policy modification. BUG #44
        for portal_type in ['dmsincomingmail', 'dmsoutgoingmail']:
            schemaName = dxutils.portalTypeToSchemaName(portal_type)
            schema = getattr(plone.dexterity.schema.generated, schemaName)
            fti = getUtility(IDexterityFTI, name=portal_type)
            model = fti.lookupModel()
            syncSchema(model.schema, schema, overwrite=True, sync_bases=True)
            notify(plone.dexterity.schema.SchemaInvalidatedEvent(portal_type))

        self.upgradeProfile('collective.task:default')
        self.upgradeProfile('dexterity.localroles:default')
        self.upgradeProfile('dexterity.localrolesfield:default')
        self.upgradeProfile('collective.contact.plonegroup:default')
        self.runProfileSteps('imio.dms.mail', steps=['actions', 'componentregistry', 'controlpanel',
                                                     'plone.app.registry', 'portlets', 'repositorytool',
                                                     'rolemap', 'sharing', 'workflow'])
        self.portal.portal_workflow.updateRoleMappings()
        self.runProfileSteps('collective.dms.mailcontent', steps=['controlpanel'])
        self.runProfileSteps('collective.contact.plonegroup', steps=['controlpanel'])
        self.reinstall([
            'collective.messagesviewlet:messages',
            'collective.querynextprev:default',
            'imio.dashboard:default',
        ])

        # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work
        self.registry['collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False

        # delete old dmsmail portlet
        self.delete_portlet(self.portal, 'portlet_maindmsmail')

        # remove deprecated interfaces
        self.remove_contact_interfaces()

        # moved notes content to task_description
        catalog = api.portal.get_tool('portal_catalog')
        brains = catalog.searchResults(portal_type='dmsincomingmail')
        for brain in brains:
            obj = brain.getObject()
            if not base_hasattr(obj, 'notes') or not obj.notes:
                continue
            text = u'<p>%s</p>\r\n' % obj.notes.replace('\r\n', '<br />\r\n')
            obj.task_description = create_richtextval(text)
            delattr(obj, 'notes')
        #    obj.reindexObject()

        # replace collections by Dashboard collections
        im_folder = self.portal['incoming-mail']
        alsoProvides(im_folder, INextPrevNotNavigable)
        alsoProvides(im_folder, IIMDashboard)
        self.replaceCollections(im_folder)

        # apply contact faceted config
        reimport_faceted_config(self.portal['contacts'], 'contacts-faceted.xml')

        # add new indexes for dashboard
        addOrUpdateIndexes(self.portal, indexInfos={'mail_type': ('FieldIndex', {}),
                                                    'mail_date': ('DateIndex', {}),
                                                    'in_out_date': ('DateIndex', {}),
                                                    })

        # set dashboard on incoming mail
        configure_faceted_folder(im_folder, xml='default_dashboard_widgets.xml',
                                 default_UID=im_folder['mail-searches']['all_mails'].UID())

        # set task local roles configuration
        configure_task_rolefields(self.portal)

        # update dexterity local roles configuration
        self.update_local_roles()

        # add task actionspanel config
        if not self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions']:
            self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] = []
        self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] += \
            ['task.back_in_created|', 'task.back_in_to_assign|', 'task.back_in_to_do|',
             'task.back_in_progress|', 'task.back_in_realized|']

        # activate ckeditor
        configure_ckeditor(self.portal, custom='ged')

        # Set markup allowed types
        adapter = MarkupControlPanelAdapter(self.portal)
        adapter.set_allowed_types(['text/html'])

        # update searchabletext
        self.update_dmsmainfile()

        self.upgradeAll()
        for prod in ['plone.formwidget.autocomplete', 'collective.documentviewer', 'plone.formwidget.masterselect',
                     'collective.contact.core', 'collective.contact.duplicated', 'collective.dms.basecontent',
                     'collective.dms.scanbehavior', 'collective.externaleditor', 'plone.app.collection',
                     'plone.app.intid', 'collective.contact.facetednav', 'plonetheme.imioapps', 'PasswordStrength',
                     'imio.dms.mail']:
            mark_last_version(self.portal, product=prod)

        self.portal.manage_permission('CMFEditions: Revert to previous versions', ('Manager', 'Site Administrator'),
                                      acquire=0)

        #self.refreshDatabase()
        self.finish()
Exemple #25
0
    def run(self):
        logger.info('Migrating to imio.dms.mail 1.0...')
        self.cleanRegistries()
        self.upgradeProfile('collective.dms.mailcontent:default')
        # We have to reapply type info before doing other subproducts migration
        self.runProfileSteps('imio.dms.mail', steps=['typeinfo'])
        # We have to update type schema because plone.dexterity doesn't detect schema_policy modification. BUG #44
        for portal_type in ['dmsincomingmail', 'dmsoutgoingmail']:  # i_e ok
            schemaName = dxutils.portalTypeToSchemaName(portal_type)
            schema = getattr(plone.dexterity.schema.generated, schemaName)
            fti = getUtility(IDexterityFTI, name=portal_type)
            model = fti.lookupModel()
            syncSchema(model.schema, schema, overwrite=True, sync_bases=True)
            notify(plone.dexterity.schema.SchemaInvalidatedEvent(portal_type))

        self.upgradeProfile('collective.task:default')
        self.upgradeProfile('dexterity.localroles:default')
        self.upgradeProfile('dexterity.localrolesfield:default')
        self.upgradeProfile('collective.contact.plonegroup:default')
        self.runProfileSteps('imio.dms.mail',
                             steps=[
                                 'actions', 'componentregistry',
                                 'controlpanel', 'plone.app.registry',
                                 'portlets', 'repositorytool', 'rolemap',
                                 'sharing', 'workflow'
                             ])
        self.portal.portal_workflow.updateRoleMappings()
        self.runProfileSteps('collective.dms.mailcontent',
                             steps=['controlpanel'])
        self.runProfileSteps('collective.contact.plonegroup',
                             steps=['controlpanel'])
        self.reinstall([
            'collective.messagesviewlet:messages',
            'collective.querynextprev:default',
            'imio.dashboard:default',
        ])

        # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work
        self.registry[
            'collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False

        # delete old dmsmail portlet
        self.delete_portlet(self.portal, 'portlet_maindmsmail')

        # remove deprecated interfaces
        self.remove_contact_interfaces()

        # moved notes content to task_description
        catalog = api.portal.get_tool('portal_catalog')
        brains = catalog.searchResults(portal_type='dmsincomingmail')  # i_e ok
        for brain in brains:
            obj = brain.getObject()
            if not base_hasattr(obj, 'notes') or not obj.notes:
                continue
            text = u'<p>%s</p>\r\n' % obj.notes.replace('\r\n', '<br />\r\n')
            obj.task_description = richtextval(text)
            delattr(obj, 'notes')
        #    obj.reindexObject()

        # replace collections by Dashboard collections
        im_folder = self.portal['incoming-mail']
        alsoProvides(im_folder, INextPrevNotNavigable)
        alsoProvides(im_folder, IIMDashboard)
        self.replaceCollections(im_folder)

        # apply contact faceted config
        reimport_faceted_config(self.portal['contacts'],
                                'contacts-faceted.xml')

        # add new indexes for dashboard
        addOrUpdateIndexes(self.portal,
                           indexInfos={
                               'mail_type': ('FieldIndex', {}),
                               'mail_date': ('DateIndex', {}),
                               'in_out_date': ('DateIndex', {}),
                           })

        # set dashboard on incoming mail
        configure_faceted_folder(
            im_folder,
            xml='default_dashboard_widgets.xml',
            default_UID=im_folder['mail-searches']['all_mails'].UID())

        # set task local roles configuration
        configure_task_rolefields(self.portal)

        # update dexterity local roles configuration
        self.update_local_roles()

        # add task actionspanel config
        if not self.registry[
                'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions']:
            self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] = []
        self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] += \
            ['task.back_in_created|', 'task.back_in_to_assign|', 'task.back_in_to_do|',
             'task.back_in_progress|', 'task.back_in_realized|']

        # activate ckeditor
        configure_ckeditor(self.portal, custom='ged')

        # Set markup allowed types
        adapter = MarkupControlPanelAdapter(self.portal)
        adapter.set_allowed_types(['text/html'])

        # update searchabletext
        self.update_dmsmainfile()

        self.upgradeAll()
        for prod in [
                'plone.formwidget.autocomplete', 'collective.documentviewer',
                'plone.formwidget.masterselect', 'collective.contact.core',
                'collective.contact.duplicated', 'collective.dms.basecontent',
                'collective.dms.scanbehavior', 'collective.externaleditor',
                'plone.app.collection', 'plone.app.intid',
                'collective.contact.facetednav', 'plonetheme.imioapps',
                'PasswordStrength', 'imio.dms.mail'
        ]:
            mark_last_version(self.portal, product=prod)

        self.portal.manage_permission(
            'CMFEditions: Revert to previous versions',
            ('Manager', 'Site Administrator'),
            acquire=0)

        #self.refreshDatabase()
        self.finish()