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

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

Revert last commit - different changes commited under one commit

  • Property svn:eol-style set to native
File size: 5.5 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            # add object interface
78            text = doc.createTextNode(iface)
79            record.appendChild(text)
80
81            root.appendChild(record)
82
83        doc.appendChild(root)
84
85        try:
86            data = doc.toprettyxml(indent='  ', encoding='utf-8')
87        except UnicodeDecodeError, e:
88            # all comments are strings encoded in 'utf-8' and they will properly
89            # saved in xml file, but if we explicitly give 'utf-8' encoding
90            # UnicodeDecodeError will be raised when they have non-ascii chars
91            data = doc.toprettyxml(indent='  ')
92
93        doc.unlink()
94        return data
95
96
97class InterfacesImporterSection(object):
98    classProvides(ISectionBlueprint)
99    implements(ISection)
100
101    def __init__(self, transmogrifier, name, options, previous):
102        self.previous = previous
103        self.context = transmogrifier.context
104
105        self.pathkey = defaultMatcher(options, 'path-key', name, 'path')
106        self.fileskey = defaultMatcher(options, 'files-key', name, 'files')
107
108        self.excludekey = defaultMatcher(options, 'exclude-key', name, 'excluded_properties')
109        self.exclude = filter(None, [i.strip() for i in
110                            options.get('exclude', '').splitlines()])
111
112        self.includekey = defaultMatcher(options, 'include-key', name, 'included_properties')
113        self.include = filter(None, [i.strip() for i in
114                              options.get('include', '').splitlines()])
115
116
117    def __iter__(self):
118
119        for item in self.previous:
120            pathkey = self.pathkey(*item.keys())[0]
121            fileskey = self.fileskey(*item.keys())[0]
122
123            if not (pathkey and fileskey):
124                yield item; continue
125            if 'interfaces' not in item[fileskey]:
126                yield item; continue
127
128            path = item[pathkey]
129            obj = self.context.unrestrictedTraverse(path, None)
130            if obj is None:         # path doesn't exist
131                yield item; continue
132
133            ifaces = self.extractIfaces(obj, item[fileskey]['interfaces']['data'])
134
135            if ifaces == []:         # no interfaces
136                yield item; continue
137
138            alsoProvides(obj, *ifaces)
139
140            yield item
141
142
143    def extractIfaces(self, obj, data):
144        doc = minidom.parseString(data)
145        ifaces = []
146        for record in doc.getElementsByTagName('record'):
147            iface_name = str(record.firstChild.nodeValue.strip())
148
149            # filter interfaces
150            if self.include and not iface_name in self.include:
151                continue
152            elif self.exclude and iface_name in self.exclude:
153                continue
154               
155            iface = self.getIfaceById(iface_name)
156            if iface:
157                ifaces.append(iface)
158        return ifaces
159
160
161    def getIfaceById(self, name):
162        components = name.split('.'); components.reverse()
163        try:
164            obj = __import__(components.pop())
165        except (ImportError, ValueError):
166            return None
167        while obj is not None and components:
168            obj = getattr(obj, components.pop(), None)
169        return obj
170
Note: See TracBrowser for help on using the repository browser.