Exemple #1
0
 def test_portalTypeToSchemaName_with_schema_and_prefix(self):
     self.assertEqual('prefix_0_type_0_schema',
         utils.portalTypeToSchemaName('type', 'schema', 'prefix'))
     self.assertEqual('prefix_0_type',
         utils.portalTypeToSchemaName('type', '', 'prefix'))
     self.assertEqual('prefix_0_type_1_one_2_two',
         utils.portalTypeToSchemaName('type one.two', '', 'prefix'))
Exemple #2
0
    def test_named_schema(self):

        # Mock schema model
        class IDummy(Interface):
            dummy = zope.schema.TextLine(title=u"Dummy")

        class INamedDummy(Interface):
            named = zope.schema.TextLine(title=u"Named")

        mock_model = Model({u"": IDummy, u"named": INamedDummy})

        # Mock FTI
        fti_mock = self.mocker.mock(DexterityFTI)
        fti_mock.lookupModel()
        self.mocker.result(mock_model)
        self.mock_utility(fti_mock, IDexterityFTI, u"testtype")

        self.mocker.replay()

        factory = schema.SchemaModuleFactory()

        schemaName = utils.portalTypeToSchemaName("testtype", schema=u"named", prefix="site")
        klass = factory(schemaName, schema.generated)

        self.failUnless(isinstance(klass, InterfaceClass))
        self.failIf(klass.isOrExtends(IDexteritySchema))  # only default schema gets this
        self.failIf(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals("plone.dexterity.schema.generated", klass.__module__)
        self.assertEquals(("named",), tuple(zope.schema.getFieldNames(klass)))
Exemple #3
0
    def test_concrete_schema_not_refreshed_on_modify_schema(self):
        portal_type = u"testtype"
        fti = self.mocker.proxy(DexterityFTI(portal_type))

        class IBlank(Interface):
            pass

        class INew(Interface):
            title = zope.schema.TextLine(title=u"title")

        model_dummy = Model({u"": INew})
        self.expect(fti.lookupModel()).result(model_dummy).count(0, None)
        self.create_dummy()

        site_dummy = self.create_dummy(getPhysicalPath=lambda: ("", "siteid"))
        self.mock_utility(site_dummy, ISiteRoot)

        self.replay()

        # Set schema to something so that hasDynamicSchema is false
        fti.schema = IBlank.__identifier__
        assert not fti.hasDynamicSchema

        # Set source for dynamic FTI - should not be used
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)

        # Sync should not happen now

        ftiModified(fti, ObjectModifiedEvent(fti, DexterityFTIModificationDescription("schema", "")))

        self.failIf("title" in IBlank)
Exemple #4
0
    def test_dynamic_schema_refreshed_on_modify_model_source(self):
        portal_type = u"testtype"
        fti = self.mocker.proxy(DexterityFTI(portal_type))

        class INew(Interface):
            title = zope.schema.TextLine(title=u"title")

        model_dummy = Model({u"": INew})

        self.expect(fti.lookupModel()).result(model_dummy)
        self.create_dummy()

        site_dummy = self.create_dummy(getPhysicalPath=lambda: ("", "siteid"))
        self.mock_utility(site_dummy, ISiteRoot)

        class IBlank(Interface):
            pass

        self.replay()

        # Set source interface
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)

        # Sync this with schema
        ftiModified(fti, ObjectModifiedEvent(fti, DexterityFTIModificationDescription("model_source", "")))

        self.failUnless("title" in IBlank)
        self.failUnless(IBlank["title"].title == u"title")
Exemple #5
0
    def test_dynamic_schema_refreshed_on_modify_model_source(self):
        portal_type = u"testtype"
        fti = DexterityFTI(portal_type)

        class INew(Interface):
            title = zope.schema.TextLine(title=u"title")

        model_dummy = Model({u"": INew})

        fti.lookupModel = Mock(return_value=model_dummy)
        self.create_dummy()

        site_dummy = self.create_dummy(
            getPhysicalPath=lambda: ('', 'siteid')
        )
        self.mock_utility(site_dummy, ISiteRoot)

        class IBlank(Interface):
            pass

        # Set source interface
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)

        # Sync this with schema
        ftiModified(
            fti,
            ObjectModifiedEvent(
                fti,
                DexterityFTIModificationDescription('model_source', '')
            )
        )

        self.assertTrue('title' in IBlank)
        self.assertTrue(IBlank['title'].title == u"title")
 def test_concrete_default_schema(self):
     
     # Mock schema model
     class IDummy(Interface):
         dummy = zope.schema.TextLine(title=u"Dummy")
     mock_model = Model({u"": IDummy})
     
     # Mock FTI
     fti_mock = self.mocker.mock(DexterityFTI)
     fti_mock.lookupModel()
     self.mocker.result(mock_model)
     self.mock_utility(fti_mock, IDexterityFTI, u'testtype')
     
     self.mocker.replay()
     
     factory = schema.SchemaModuleFactory()
     
     schemaName = utils.portalTypeToSchemaName('testtype', prefix='site')
     klass = factory(schemaName, schema.generated)
     
     self.failUnless(isinstance(klass, InterfaceClass))
     self.failUnless(klass.isOrExtends(IDexteritySchema))
     self.failUnless(IContentType.providedBy(klass))
     self.assertEquals(schemaName, klass.__name__)
     self.assertEquals('plone.dexterity.schema.generated', klass.__module__)
     self.assertEquals(('dummy',), tuple(zope.schema.getFieldNames(klass)))
Exemple #7
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 = utils.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 #8
0
    def test_portalTypeToSchemaName_looks_up_portal_for_prefix(self):
        portal_mock = self.mocker.mock()
        self.expect(portal_mock.getPhysicalPath()).result(('', 'foo', 'portalid'))
        self.mock_utility(portal_mock, ISiteRoot)

        self.replay()

        self.assertEqual('foo_4_portalid_0_type',
            utils.portalTypeToSchemaName('type'))
Exemple #9
0
 def test_lookupSchema_with_nonexistant_schema(self):
     """ Tests the case where a dexterity type is not removed cleanly
     from the fti, but the code has been removed.
     """
     fti = DexterityFTI(u"testtype")
     fti.schema = 'model.wont.be.imported'
     portal = self.create_dummy(getPhysicalPath=lambda: ('', 'site'))
     self.mock_utility(portal, ISiteRoot)
     schemaName = utils.portalTypeToSchemaName(fti.getId())
     setattr(plone.dexterity.schema.generated, schemaName, ITestSchema)
     self.assertEqual(ITestSchema, fti.lookupSchema())
     delattr(plone.dexterity.schema.generated, schemaName)
Exemple #10
0
    def test_dynamic_schema_refreshed_on_modify_schema_policy(self):
        portal_type = u"testtype"
        fti = self.mocker.proxy(DexterityFTI(portal_type))

        class INew(Interface):
            title = zope.schema.TextLine(title=u"title")

        class IBlank(Interface):
            pass

        class TestSchemaPolicy(DexteritySchemaPolicy):
            def bases(self, schemaName, tree):
                return (INew,)

        gsm = getGlobalSiteManager()
        policy = TestSchemaPolicy()
        gsm.registerUtility(
            policy,
            plone.supermodel.interfaces.ISchemaPolicy,
            name=u"test"
        )

        self.expect(fti.schema_policy).passthrough().count(0, None)

        site_dummy = self.create_dummy(
            getPhysicalPath=lambda: ('', 'siteid')
        )
        self.mock_utility(site_dummy, ISiteRoot)

        self.replay()

        # Set source interface
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)
        original = getattr(plone.dexterity.schema.generated, schemaName)
        self.assertNotIn(INew, original.__bases__)
        self.assertNotIn('title', original)

        # Set new schema_policy
        fti.schema_policy = "test"

        # Sync this with schema
        ftiModified(
            fti,
            ObjectModifiedEvent(
                fti,
                DexterityFTIModificationDescription('schema_policy', '')
            )
        )
        updated = getattr(plone.dexterity.schema.generated, schemaName)
        self.assertIn('title', updated)
        self.assertIn(INew, updated.__bases__)
Exemple #11
0
    def test_transient_schema(self):

        # No IDexterityFTI registered
        factory = schema.SchemaModuleFactory()
        schemaName = utils.portalTypeToSchemaName("testtype", prefix="site")
        klass = factory(schemaName, schema.generated)

        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals("plone.dexterity.schema.generated", klass.__module__)
        self.assertEquals((), tuple(zope.schema.getFields(klass)))
Exemple #12
0
    def test_lookupSchema_with_dynamic_schema(self):
        fti = DexterityFTI(u"testtype")
        fti.schema = None  # use dynamic schema

        portal = self.create_dummy(getPhysicalPath=lambda: ('', 'site'))
        self.mock_utility(portal, ISiteRoot)

        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, ITestSchema)

        self.assertEqual(ITestSchema, fti.lookupSchema())

        # cleanup
        delattr(plone.dexterity.schema.generated, schemaName)
Exemple #13
0
    def test_lookupSchema_with_dynamic_schema(self):
        fti = DexterityFTI(u"testtype")
        fti.schema = None  # use dynamic schema

        portal = self.create_dummy(getPhysicalPath=lambda: ('', 'site'))
        self.mock_utility(portal, ISiteRoot)

        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, ITestSchema)

        self.assertEqual(ITestSchema, fti.lookupSchema())

        # cleanup
        delattr(plone.dexterity.schema.generated, schemaName)
Exemple #14
0
    def test_transient_schema_made_concrete(self):

        factory = schema.SchemaModuleFactory()
        schemaName = utils.portalTypeToSchemaName("testtype", prefix="site")

        # No IDexterityFTI registered

        klass = factory(schemaName, schema.generated)
        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals("plone.dexterity.schema.generated", klass.__module__)
        self.assertEquals((), tuple(zope.schema.getFields(klass)))

        # Calling it again gives the same result

        klass = factory(schemaName, schema.generated)
        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals("plone.dexterity.schema.generated", klass.__module__)
        self.assertEquals((), tuple(zope.schema.getFields(klass)))

        # Now register a mock FTI and try again

        class IDummy(Interface):
            dummy = zope.schema.TextLine(title=u"Dummy")

        mock_model = Model({u"": IDummy})

        fti_mock = self.mocker.mock(DexterityFTI)
        fti_mock.lookupModel()
        self.mocker.result(mock_model)
        self.mock_utility(fti_mock, IDexterityFTI, u"testtype")

        self.mocker.replay()

        klass = factory(schemaName, schema.generated)

        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals("plone.dexterity.schema.generated", klass.__module__)

        # Now we get the fields from the FTI's model
        self.assertEquals(("dummy",), tuple(zope.schema.getFieldNames(klass)))
Exemple #15
0
    def test_transient_schema_made_concrete(self):

        factory = schema.SchemaModuleFactory()
        schemaName = utils.portalTypeToSchemaName('testtype', prefix='site')

        # No IDexterityFTI registered

        klass = factory(schemaName, schema.generated)
        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals('plone.dexterity.schema.generated', klass.__module__)
        self.assertEquals((), tuple(zope.schema.getFields(klass)))

        # Calling it again gives the same result

        klass = factory(schemaName, schema.generated)
        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals('plone.dexterity.schema.generated', klass.__module__)
        self.assertEquals((), tuple(zope.schema.getFields(klass)))

        # Now register a mock FTI and try again

        class IDummy(Interface):
            dummy = zope.schema.TextLine(title=u"Dummy")

        mock_model = Model({u"": IDummy})

        fti_mock = self.mocker.mock(DexterityFTI)
        fti_mock.lookupModel()
        self.mocker.result(mock_model)
        self.mock_utility(fti_mock, IDexterityFTI, u'testtype')

        self.mocker.replay()

        klass = factory(schemaName, schema.generated)

        self.failUnless(isinstance(klass, InterfaceClass))
        self.failUnless(klass.isOrExtends(IDexteritySchema))
        self.failUnless(IContentType.providedBy(klass))
        self.assertEquals(schemaName, klass.__name__)
        self.assertEquals('plone.dexterity.schema.generated', klass.__module__)

        # Now we get the fields from the FTI's model
        self.assertEquals(('dummy', ), tuple(zope.schema.getFieldNames(klass)))
Exemple #16
0
    def lookupSchema(self):

        # If a specific schema is given, use it
        if self.schema:
            schema = utils.resolveDottedName(self.schema)
            if schema is None:
                raise ValueError(u"Schema %s set for type %s cannot be resolved" % (self.schema, self.getId()))
            return schema

        # Otherwise, look up a dynamic schema. This will query the model for
        # an unnamed schema if it is the first time it is looked up.
        # See schema.py

        schemaName = utils.portalTypeToSchemaName(self.getId())
        return getattr(plone.dexterity.schema.generated, schemaName)
Exemple #17
0
    def lookupSchema(self):

        # If a specific schema is given, use it
        if self.schema:
            schema = utils.resolveDottedName(self.schema)
            if schema is None:
                raise ValueError(
                    u"Schema %s set for type %s cannot be resolved" %
                    (self.schema, self.getId()))
            return schema

        # Otherwise, look up a dynamic schema. This will query the model for
        # an unnamed schema if it is the first time it is looked up.
        # See schema.py

        schemaName = utils.portalTypeToSchemaName(self.getId())
        return getattr(plone.dexterity.schema.generated, schemaName)
Exemple #18
0
    def test_dynamic_schema_refreshed_on_modify_schema_policy(self):
        portal_type = 'testtype'
        fti = self.mocker.proxy(DexterityFTI(portal_type))

        class INew(Interface):
            title = zope.schema.TextLine(title='title')

        class IBlank(Interface):
            pass

        class TestSchemaPolicy(DexteritySchemaPolicy):
            def bases(self, schemaName, tree):
                return (INew, )

        gsm = getGlobalSiteManager()
        policy = TestSchemaPolicy()
        gsm.registerUtility(policy,
                            plone.supermodel.interfaces.ISchemaPolicy,
                            name='test')

        self.expect(fti.schema_policy).passthrough().count(0, None)

        site_dummy = self.create_dummy(getPhysicalPath=lambda: ('', 'siteid'))
        self.mock_utility(site_dummy, Interface)

        self.replay()

        # Set source interface
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)
        original = getattr(plone.dexterity.schema.generated, schemaName)
        self.assertNotIn(INew, original.__bases__)
        self.assertNotIn('title', original)

        # Set new schema_policy
        fti.schema_policy = 'test'

        # Sync this with schema
        ftiModified(
            fti,
            ObjectModifiedEvent(
                fti, DexterityFTIModificationDescription('schema_policy', '')))
        updated = getattr(plone.dexterity.schema.generated, schemaName)
        self.assertIn('title', updated)
        self.assertIn(INew, updated.__bases__)
Exemple #19
0
    def lookupSchema(self):
        schema = None
        
        # If a specific schema is given, use it
        if self.schema:
            try:
                schema = utils.resolveDottedName(self.schema)
            except ImportError:
                logging.warning(u"Schema %s set for type %s cannot be resolved" % (self.schema, self.getId()))
                # fall through to return a fake class with no
                # fields so that end user code doesn't break
                
        if schema:
            return schema
        
        # Otherwise, look up a dynamic schema. This will query the model for
        # an unnamed schema if it is the first time it is looked up. 
        # See schema.py

        schemaName = utils.portalTypeToSchemaName(self.getId())
        return getattr(plone.dexterity.schema.generated, schemaName)
Exemple #20
0
    def lookupSchema(self):
        schema = None

        # If a specific schema is given, use it
        if self.schema:
            try:
                schema = utils.resolveDottedName(self.schema)
            except ImportError:
                logging.warning(
                    u"Schema %s set for type %s cannot be resolved" %
                    (self.schema, self.getId()))
                # fall through to return a fake class with no
                # fields so that end user code doesn't break

        if schema:
            return schema

        # Otherwise, look up a dynamic schema. This will query the model for
        # an unnamed schema if it is the first time it is looked up.
        # See schema.py

        schemaName = utils.portalTypeToSchemaName(self.getId())
        return getattr(plone.dexterity.schema.generated, schemaName)
Exemple #21
0
    def test_concrete_schema_not_refreshed_on_modify_schema(self):
        portal_type = u"testtype"
        fti = DexterityFTI(portal_type)

        class IBlank(Interface):
            pass

        class INew(Interface):
            title = zope.schema.TextLine(title=u"title")

        model_dummy = Model({u"": INew})
        fti.lookupModel = Mock(return_value=model_dummy)

        site_dummy = self.create_dummy(
            getPhysicalPath=lambda: ('', 'siteid')
        )
        self.mock_utility(site_dummy, ISiteRoot)

        # Set schema to something so that hasDynamicSchema is false
        fti.schema = IBlank.__identifier__
        assert not fti.hasDynamicSchema

        # Set source for dynamic FTI - should not be used
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)

        # Sync should not happen now

        ftiModified(
            fti,
            ObjectModifiedEvent(
                fti,
                DexterityFTIModificationDescription('schema', '')
            )
        )

        self.assertFalse('title' in IBlank)
Exemple #22
0
    def test_named_schema(self):

        # Mock schema model
        class IDummy(Interface):
            dummy = zope.schema.TextLine(title=u"Dummy")

        class INamedDummy(Interface):
            named = zope.schema.TextLine(title=u"Named")
        mock_model = Model({u"": IDummy,
                            u"named": INamedDummy})

        # Mock FTI
        fti_mock = self.mocker.mock(DexterityFTI)
        fti_mock.lookupModel()
        self.mocker.result(mock_model)
        self.mock_utility(fti_mock, IDexterityFTI, u'testtype')

        self.mocker.replay()

        factory = schema.SchemaModuleFactory()

        schemaName = utils.portalTypeToSchemaName(
            'testtype',
            schema=u"named",
            prefix='site'
        )
        klass = factory(schemaName, schema.generated)

        self.assertTrue(isinstance(klass, InterfaceClass))

        # only default schema gets this:
        self.assertFalse(klass.isOrExtends(IDexteritySchema))

        self.assertFalse(IContentType.providedBy(klass))
        self.assertEqual(schemaName, klass.__name__)
        self.assertEqual('plone.dexterity.schema.generated', klass.__module__)
        self.assertEqual(('named',), tuple(zope.schema.getFieldNames(klass)))
Exemple #23
0
    def test_dynamic_schema_refreshed_on_modify_model_source(self):
        portal_type = 'testtype'
        fti = self.mocker.proxy(DexterityFTI(portal_type))

        class INew(Interface):
            title = zope.schema.TextLine(title='title')

        model_dummy = Model({'': INew})

        self.expect(fti.lookupModel()).result(model_dummy)
        self.create_dummy()

        site_dummy = self.create_dummy(
            getPhysicalPath=lambda: ('', 'siteid')
        )
        self.mock_utility(site_dummy, Interface)

        class IBlank(Interface):
            pass

        self.replay()

        # Set source interface
        schemaName = utils.portalTypeToSchemaName(fti.getId())
        setattr(plone.dexterity.schema.generated, schemaName, IBlank)

        # Sync this with schema
        ftiModified(
            fti,
            ObjectModifiedEvent(
                fti,
                DexterityFTIModificationDescription('model_source', '')
            )
        )

        self.assertTrue('title' in IBlank)
        self.assertTrue(IBlank['title'].title == 'title')
Exemple #24
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()
    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()