source: products/quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/marshall.py @ 1589

Last change on this file since 1589 was 1414, checked in by piv, 14 years ago

merge plone2.1 branche updates (r2426-2428,2433-2452): manifests with valid xml now, binary files fully dumped, local roles are imported, control characters are handled properly

File size: 6.0 KB
RevLine 
[453]1import traceback
[527]2from DateTime import DateTime
[453]3
[275]4from zope.interface import classProvides, implements
[428]5from zope import event
6
[275]7from ZODB.POSException import ConflictError
8
9from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
10from collective.transmogrifier.utils import defaultMatcher
11
[486]12from Products.CMFCore import utils
[275]13from Products.Marshall import registry
14from Products.Archetypes.interfaces import IBaseObject
[333]15from Products.Archetypes.event import ObjectInitializedEvent
16from Products.Archetypes.event import ObjectEditedEvent
[275]17
[1414]18# override Marshall atxml namespaces
19from quintagroup.transmogrifier import namespaces
20
21
[278]22class MarshallerSection(object):
[275]23    classProvides(ISectionBlueprint)
24    implements(ISection)
25
26    def __init__(self, transmogrifier, name, options, previous):
27        self.previous = previous
28        self.context = transmogrifier.context
29
30        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
[279]31        self.fileskey = options.get('files-key', '_files').strip()
[278]32
[275]33        self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_fields')
[278]34        self.exclude = filter(None, [i.strip() for i in 
35                              options.get('exclude', '').splitlines()])
[275]36
[278]37        self.atxml = registry.getComponent("atxml")
[275]38
39    def __iter__(self):
40        for item in self.previous:
41            pathkey = self.pathkey(*item.keys())[0]
42
43            if not pathkey:
44                yield item; continue
45
46            path = item[pathkey]
47            obj = self.context.unrestrictedTraverse(path, None)
48            if obj is None:         # path doesn't exist
49                yield item; continue
50
51            if IBaseObject.providedBy(obj):
[278]52                # get list of excluded fields given in options and in item
[275]53                excludekey = self.excludekey(*item.keys())[0]
[278]54                atns_exclude = tuple(self.exclude)
[275]55                if excludekey:
[278]56                    atns_exclude = tuple(set(item[excludekey]) | set(atns_exclude))
57
[275]58                try:
[278]59                    content_type, length, data = self.atxml.marshall(obj, atns_exclude=atns_exclude)
[275]60                except ConflictError:
61                    raise
62                except:
63                    data = None
[278]64
[275]65                if data or data is None:
66                    # None value has special meaning for IExportDataCorrector adapter for topic criterias
[278]67                    files = item.setdefault(self.fileskey, {})
68                    item[self.fileskey]['marshall'] = {
[275]69                        'name': '.marshall.xml',
70                        'data': data,
71                    }
72
73            yield item
[278]74
75class DemarshallerSection(object):
76    classProvides(ISectionBlueprint)
77    implements(ISection)
78
79    def __init__(self, transmogrifier, name, options, previous):
80        self.previous = previous
81        self.context = transmogrifier.context
82
83        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
84        self.fileskey = defaultMatcher(options, 'files-key', name, 'files')
85
86        # Marshall doesn't support excluding fields on demarshalling,
87        # we can do this with xml.dom.minodom, if it'll be needed in the future
88        # self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_fields')
89
90        # self.exclude = filter(None, [i.strip() for i in
91        #                     options.get('exclude', '').splitlines()])
92
93        self.atxml = registry.getComponent("atxml")
94
95    def __iter__(self):
96        for item in self.previous:
97            pathkey = self.pathkey(*item.keys())[0]
98            fileskey = self.fileskey(*item.keys())[0]
99
100            if not (pathkey and fileskey):
101                yield item; continue
102            if 'marshall' not in item[fileskey]:
103                yield item; continue
104
105            path = item[pathkey]
106            obj = self.context.unrestrictedTraverse(path, None)
107            if obj is None:         # path doesn't exist
108                yield item; continue
109
110            if IBaseObject.providedBy(obj):
111                try:
112                    data = item[fileskey]['marshall']['data']
113                    self.atxml.demarshall(obj, data)
[527]114
115                    # When we change workflow state of content through Plone interface,
116                    # effective date field will be updated to current date (the same
117                    # as modification date) if it was empty, so after demarshalling
118                    # (workflow history was updated) we need to do it manually.
119                    effective_field = obj.getField('effectiveDate')
120                    if effective_field is not None and effective_field.getAccessor(obj)() is None:
121                        date = obj.getField('modification_date').getAccessor(obj)()
122                        effective_field.getMutator(obj)(date)
123
[278]124                    # we don't want to call reindexObject because modification_date
125                    # will be updated, so we call only indexObject (reindexObject does
126                    # some things with uid catalog too)
[333]127                    is_new_object = obj.checkCreationFlag()
[278]128                    obj.indexObject()
[333]129                    # firing of events
130                    obj.unmarkCreationFlag()
131                    if is_new_object:
132                        event.notify(ObjectInitializedEvent(obj))
133                        obj.at_post_create_script()
134                    else:
135                        event.notify(ObjectEditedEvent(obj))
136                        obj.at_post_edit_script()
[278]137                except ConflictError:
138                    raise
[453]139                except Exception, e:
140                    print 'Exception in demarshaller section:'
141                    print '-'*60
142                    traceback.print_exc()
143                    print '-'*60
[278]144
145            yield item
[486]146
147        # updating security settings on demarshalled content
148        wtool = utils.getToolByName(self.context, 'portal_workflow')
149        wtool.updateRoleMappings()
150        catalog = utils.getToolByName(self.context, 'portal_catalog')
151        catalog.reindexIndex('allowedRolesAndUsers', None)
Note: See TracBrowser for help on using the repository browser.