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

Last change on this file since 527 was 527, checked in by chervol, 18 years ago

fixed the version restriction code

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