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
Line 
1import traceback
2from DateTime import DateTime
3
4from zope.interface import classProvides, implements
5from zope import event
6
7from ZODB.POSException import ConflictError
8
9from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
10from collective.transmogrifier.utils import defaultMatcher
11
12from Products.CMFCore import utils
13from Products.Marshall import registry
14from Products.Archetypes.interfaces import IBaseObject
15from Products.Archetypes.event import ObjectInitializedEvent
16from Products.Archetypes.event import ObjectEditedEvent
17
18class MarshallerSection(object):
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')
27        self.fileskey = options.get('files-key', '_files').strip()
28
29        self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_fields')
30        self.exclude = filter(None, [i.strip() for i in 
31                              options.get('exclude', '').splitlines()])
32
33        self.atxml = registry.getComponent("atxml")
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):
48                # get list of excluded fields given in options and in item
49                excludekey = self.excludekey(*item.keys())[0]
50                atns_exclude = tuple(self.exclude)
51                if excludekey:
52                    atns_exclude = tuple(set(item[excludekey]) | set(atns_exclude))
53
54                try:
55                    content_type, length, data = self.atxml.marshall(obj, atns_exclude=atns_exclude)
56                except ConflictError:
57                    raise
58                except:
59                    data = None
60
61                if data or data is None:
62                    # None value has special meaning for IExportDataCorrector adapter for topic criterias
63                    files = item.setdefault(self.fileskey, {})
64                    item[self.fileskey]['marshall'] = {
65                        'name': '.marshall.xml',
66                        'data': data,
67                    }
68
69            yield item
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)
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
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)
123                    is_new_object = obj.checkCreationFlag()
124                    obj.indexObject()
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()
133                except ConflictError:
134                    raise
135                except Exception, e:
136                    print 'Exception in demarshaller section:'
137                    print '-'*60
138                    traceback.print_exc()
139                    print '-'*60
140
141            yield item
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.