Skip to content

Commit

Permalink
Add a ICustomMigrator interface to the migration framework, which ca…
Browse files Browse the repository at this point in the history
…n be used

  to register custom migrator adapters. This can be useful to add custom
  migrators to more than one or all content types. For example for
  schemaextenders, which are registered on a interface, which is provided by
  several content types.
  • Loading branch information
thet committed Mar 20, 2014
1 parent e3cbf99 commit bea3e57
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 11 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,13 @@ Changelog
1.2a2 (unreleased)
------------------

- Add a ICustomMigrator interface to the migration framework, which can be used
to register custom migrator adapters. This can be useful to add custom
migrators to more than one or all content types, for example for
schemaextenders, which are registered on a interface, which is provided by
several content types.
[thet]

- In the migration framework, fix queries for Archetype objects, where only
interfaces are used to skip brains with no or Dexterity meta_type. In some
cases Dexterity and Archetype objects might provide the same marker
Expand Down
2 changes: 2 additions & 0 deletions plone/app/contenttypes/migration/configure.zcml
Expand Up @@ -63,4 +63,6 @@
name="plone.app.contenttypes.migration.extendedtypes"
provides="zope.schema.interfaces.IVocabularyFactory" />

<adapter name="nullmigrator" factory=".migration.BaseCustomMigator"/>

</configure>
70 changes: 59 additions & 11 deletions plone/app/contenttypes/migration/migration.py
Expand Up @@ -26,11 +26,16 @@
from plone.namedfile.file import NamedBlobFile
from plone.namedfile.file import NamedBlobImage
from z3c.relationfield import RelationValue
from zope.component import adapter
from zope.component import getAdapters
from zope.component import getUtility
from zope.event import notify
from zope.interface import Interface
from zope.interface import implementer
from zope.intid.interfaces import IIntIds
from zope.lifecycleevent import ObjectModifiedEvent


import logging
logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -191,10 +196,39 @@ def migrate_relatedItems(self):
self.new._relatedItemsOrder = self.old._relatedItemsOrder


class ATCTBaseMigrator(CMFItemMigrator, ReferenceMigrator):
class ICustomMigrator(Interface):
"""Adapter implementer interface for custom migrators.
Please note that you have to register named adapters in order to be able to
register multiple adapters to the same adaptee.
"""
def migrate(old, new):
"""Start the custom migraton.
:param old: The old content object.
:param new: The new content object.
"""


@implementer(ICustomMigrator)
@adapter(Interface)
class BaseCustomMigator(object):
"""Base custom migration class. Does nothing.
You can use this as base class for your custom migrator adapters.
You might register it to some specific orginal content interface.
"""
def __init__(self, context):
self.context = context

def migrate(self, old, new):
return


class ATCTContentMigrator(CMFItemMigrator, ReferenceMigrator):
"""Base for contentish ATCT
"""

def __init__(self, *args, **kwargs):
super(ATCTBaseMigrator, self).__init__(*args, **kwargs)
super(ATCTContentMigrator, self).__init__(*args, **kwargs)
logger.info(
"Migrating object %s" %
'/'.join(self.old.getPhysicalPath())
Expand All @@ -204,20 +238,34 @@ def migrate_atctmetadata(self):
field = self.old.getField('excludeFromNav')
self.new.exclude_from_nav = field.get(self.old)


class ATCTContentMigrator(ATCTBaseMigrator,
CMFItemMigrator,
ReferenceMigrator):
"""Base for contentish ATCT
"""
def migrate_custom(self):
"""Get all ICustomMigrator registered migrators and run the migration.
"""
for _, migrator in getAdapters((self.old, ), ICustomMigrator):
migrator.migrate(self.old, self.new)


class ATCTFolderMigrator(ATCTBaseMigrator,
CMFFolderMigrator,
ReferenceMigrator):
class ATCTFolderMigrator(CMFFolderMigrator, ReferenceMigrator):
"""Base for folderish ATCT
"""

def __init__(self, *args, **kwargs):
super(ATCTFolderMigrator, self).__init__(*args, **kwargs)
logger.info(
"Migrating object %s" %
'/'.join(self.old.getPhysicalPath())
)

def migrate_atctmetadata(self):
field = self.old.getField('excludeFromNav')
self.new.exclude_from_nav = field.get(self.old)

def migrate_custom(self):
"""Get all ICustomMigrator registered migrators and run the migration.
"""
for _, migrator in getAdapters((self.old, ), ICustomMigrator):
migrator.migrate(self.old, self.new)


class DocumentMigrator(ATCTContentMigrator):

Expand Down

1 comment on commit bea3e57

@mister-roboto
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TESTS FAILED
Mr.roboto url : http://jenkins.plone.org/roboto/get_info?push=542465528a8f405f85376094fb3074a5
plone-5.0-python-2.7 [FAILURE]
plone-4.3-python-2.6 [FAILURE]
plone-4.3-python-2.7 [SUCCESS]

Please sign in to comment.