source: products/quintagroup.transmogrifier/trunk/quintagroup/transmogrifier/interfacemanager.py @ 1470

Last change on this file since 1470 was 1470, checked in by mylan, 14 years ago

Minor updated interfaces importer/exportes steps

  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1import os.path
2from xml.dom import minidom
3
4from zope.interface import classProvides, implements
5from zope.interface import providedBy, alsoProvides
6from zope.annotation.interfaces import IAnnotations
7
8from collective.transmogrifier.interfaces import ISection, ISectionBlueprint
9from collective.transmogrifier.utils import defaultMatcher
10
11from quintagroup.transmogrifier.logger import VALIDATIONKEY
12
13class InterfacesExporterSection(object):
14    classProvides(ISectionBlueprint)
15    implements(ISection)
16
17    def __init__(self, transmogrifier, name, options, previous):
18        self.previous = previous
19        self.context = transmogrifier.context
20
21        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
22        self.fileskey = options.get('files-key', '_files').strip()
23
24        self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_interfaces')
25        self.exclude = filter(None, [i.strip() for i in
26                              options.get('exclude', '').splitlines()])
27
28        self.includekey = defaultMatcher(options, 'include-key', name, 'included_interfaces')
29        self.include = filter(None, [i.strip() for i in
30                              options.get('include', '').splitlines()])
31
32        self.doc = minidom.Document()
33
34    def __iter__(self):
35        for item in self.previous:
36            pathkey = self.pathkey(*item.keys())[0]
37
38            if not pathkey:
39                yield item; continue
40
41            path = item[pathkey]
42            obj = self.context.unrestrictedTraverse(path, None)
43            if obj is None:         # path doesn't exist
44                yield item; continue
45
46            ifaces = self.getInterfaces(obj)
47
48            if ifaces:
49                files = item.setdefault('_files', {})
50                item[self.fileskey]['interfaces'] = {
51                    'name': '.interfaces.xml',
52                    'data': ifaces,
53                }
54
55            yield item
56
57    def getInterfaces(self, obj):
58        if not obj:
59            return None
60
61        doc = self.doc
62        root = doc.createElement('interfaces')
63
64        ifaces = [i.__identifier__ for i in providedBy(obj)]
65        if self.include:
66            ifaces = filter(lambda i: i in self.include, ifaces)
67        elif self.exclude:
68            ifaces = filter(lambda i: not i in self.include, ifaces)
69
70        if ifaces == []:
71            return None
72
73        for iface in ifaces:
74            # create record
75            record = doc.createElement('record')
76
77            # set type attribute
78            #attr = doc.createAttribute('type')
79            #attr.value = obj_type
80            #record.setAttributeNode(attr)
81
82            # add object id
83            text = doc.createTextNode(iface)
84            record.appendChild(text)
85
86            root.appendChild(record)
87
88        doc.appendChild(root)
89
90        try:
91            data = doc.toprettyxml(indent='  ', encoding='utf-8')
92        except UnicodeDecodeError, e:
93            # all comments are strings encoded in 'utf-8' and they will properly
94            # saved in xml file, but if we explicitly give 'utf-8' encoding
95            # UnicodeDecodeError will be raised when they have non-ascii chars
96            data = doc.toprettyxml(indent='  ')
97
98        doc.unlink()
99        return data
100
101
102class InterfacesImporterSection(object):
103    classProvides(ISectionBlueprint)
104    implements(ISection)
105
106    def __init__(self, transmogrifier, name, options, previous):
107        self.previous = previous
108        self.context = transmogrifier.context
109
110        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
111        self.fileskey = defaultMatcher(options, 'files-key', name, 'files')
112
113        self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_properties')
114        self.exclude = filter(None, [i.strip() for i in
115                            options.get('exclude', '').splitlines()])
116
117        self.includekey = defaultMatcher(options, 'include-key', name, 'included_properties')
118        self.include = filter(None, [i.strip() for i in
119                              options.get('include', '').splitlines()])
120
121
122    def __iter__(self):
123
124        for item in self.previous:
125            pathkey = self.pathkey(*item.keys())[0]
126            fileskey = self.fileskey(*item.keys())[0]
127
128            if not (pathkey and fileskey):
129                yield item; continue
130            if 'interfaces' not in item[fileskey]:
131                yield item; continue
132
133            path = item[pathkey]
134            obj = self.context.unrestrictedTraverse(path, None)
135            if obj is None:         # path doesn't exist
136                yield item; continue
137
138            ifaces = self.extractIfaces(obj, item[fileskey]['interfaces']['data'])
139
140            if ifaces == []:         # no interfaces
141                yield item; continue
142
143            alsoProvides(obj, *ifaces)
144
145            yield item
146
147
148    def extractIfaces(self, obj, data):
149        doc = minidom.parseString(data)
150        ifaces = []
151        for record in doc.getElementsByTagName('record'):
152            iface_name = str(record.firstChild.nodeValue.strip())
153
154            # filter interfaces
155            if self.include and not iface_name in self.include:
156                continue
157            elif self.exclude and iface_name in self.exclude:
158                continue
159               
160            iface = self.getIfaceById(iface_name)
161            if iface:
162                ifaces.append(iface)
163        return ifaces
164
165
166    def getIfaceById(self, name):
167        components = name.split('.'); components.reverse()
168        try:
169            obj = __import__(components.pop())
170        except (ImportError, ValueError):
171            return None
172        while obj is not None and components:
173            obj = getattr(obj, components.pop(), None)
174        return obj
175
Note: See TracBrowser for help on using the repository browser.