~sidnei/zope3/ztk-1.0a1

« back to all changes in this revision

Viewing changes to src/zope/app/apidoc/codemodule/zcml.py

  • Committer: Sidnei da Silva
  • Date: 2010-03-03 03:29:50 UTC
  • mfrom: (12.1.16 trunk)
  • Revision ID: sidnei.da.silva@canonical.com-20100303032950-duivfaoqsxaf9dgg
Merged newer-from-ztk [r=jkakar,bigkevmcd,free][qa=andreas][f=522474].

Update our monolithic Zope 3 tree to a kgs-based, generated,
monolithic Zope 3 tree built from eggs using the
collective.buildout.omelette recipe.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
##############################################################################
2
 
#
3
 
# Copyright (c) 2004 Zope Corporation and Contributors.
4
 
# All Rights Reserved.
5
 
#
6
 
# This software is subject to the provisions of the Zope Public License,
7
 
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
 
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
 
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
 
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
 
# FOR A PARTICULAR PURPOSE.
12
 
#
13
 
##############################################################################
14
 
"""ZCML File Representation
15
 
 
16
 
$Id: zcml.py 71107 2006-11-10 23:58:55Z shane $
17
 
"""
18
 
__docformat__ = "reStructuredText"
19
 
import copy
20
 
from xml.sax import make_parser
21
 
from xml.sax.xmlreader import InputSource
22
 
from xml.sax.handler import feature_namespaces
23
 
 
24
 
from zope.cachedescriptors.property import Lazy
25
 
from zope.configuration import xmlconfig, config
26
 
from zope.interface import implements, directlyProvides
27
 
from zope.location.interfaces import ILocation
28
 
 
29
 
import zope.app.appsetup.appsetup
30
 
 
31
 
from interfaces import IDirective, IRootDirective, IZCMLFile
32
 
 
33
 
 
34
 
class MyConfigHandler(xmlconfig.ConfigurationHandler, object):
35
 
    """Special configuration handler to generate an XML tree."""
36
 
 
37
 
    def __init__(self, context):
38
 
        super(MyConfigHandler, self).__init__(context)
39
 
        self.rootElement = self.currentElement = None
40
 
        self.prefixes = {}
41
 
 
42
 
    def startPrefixMapping(self, prefix, uri):
43
 
        self.prefixes[uri] = prefix
44
 
 
45
 
    def evaluateCondition(self, expression):
46
 
        # We always want to process/show all ZCML directives.
47
 
        return True
48
 
 
49
 
    def startElementNS(self, name, qname, attrs):
50
 
        # The last stack item is parent of the stack item that we are about to
51
 
        # create
52
 
        stackitem = self.context.stack[-1]
53
 
        super(MyConfigHandler, self).startElementNS(name, qname, attrs)
54
 
 
55
 
        # Get the parser info from the correct context
56
 
        info = self.context.stack[-1].context.info
57
 
 
58
 
        # complex stack items behave a bit different than the other ones, so
59
 
        # we need to handle it separately
60
 
        if isinstance(stackitem, config.ComplexStackItem):
61
 
            schema = stackitem.meta.get(name[1])[0]
62
 
        else:
63
 
            schema = stackitem.context.factory(stackitem.context, name).schema
64
 
 
65
 
        # Now we have all the necessary information to create the directive
66
 
        element = Directive(name, schema, attrs, stackitem.context, info,
67
 
                            self.prefixes)
68
 
        # Now we place the directive into the XML directive tree.
69
 
        if self.rootElement is None:
70
 
            self.rootElement = element
71
 
        else:
72
 
            self.currentElement.subs.append(element)
73
 
 
74
 
        element.__parent__ = self.currentElement
75
 
        self.currentElement = element
76
 
 
77
 
 
78
 
    def endElementNS(self, name, qname):
79
 
        super(MyConfigHandler, self).endElementNS(name, qname)
80
 
        self.currentElement = self.currentElement.__parent__
81
 
 
82
 
 
83
 
class Directive(object):
84
 
    """Representation of a ZCML directive."""
85
 
    implements(IDirective)
86
 
 
87
 
    def __init__(self, name, schema, attrs, context, info, prefixes):
88
 
        self.name = name
89
 
        self.schema = schema
90
 
        self.attrs = attrs
91
 
        self.context = context
92
 
        self.info = info
93
 
        self.__parent__ = None
94
 
        self.subs = []
95
 
        self.prefixes = prefixes
96
 
 
97
 
    def __repr__(self):
98
 
        return '<Directive %s>' %str(self.name)
99
 
 
100
 
 
101
 
class ZCMLFile(object):
102
 
    """Representation of an entire ZCML file."""
103
 
    implements(ILocation, IZCMLFile)
104
 
 
105
 
    def __init__(self, filename, package, parent, name):
106
 
        # Retrieve the directive registry
107
 
        self.filename = filename
108
 
        self.package = package
109
 
        self.__parent__ = parent
110
 
        self.__name__ = name
111
 
 
112
 
    def rootElement(self):
113
 
        # Get the context that was originally generated during startup and
114
 
        # create a new context using its registrations
115
 
        real_context = zope.app.appsetup.appsetup.getConfigContext()
116
 
        context = config.ConfigurationMachine()
117
 
        context._registry = copy.copy(real_context._registry)
118
 
        context._features = copy.copy(real_context._features)
119
 
        context.package = self.package
120
 
 
121
 
        # Shut up i18n domain complaints
122
 
        context.i18n_domain = 'zope'
123
 
 
124
 
        # Since we want to use a custom configuration handler, we need to
125
 
        # instantiate the parser object ourselves
126
 
        parser = make_parser()
127
 
        handler = MyConfigHandler(context)
128
 
        parser.setContentHandler(handler)
129
 
        parser.setFeature(feature_namespaces, True)
130
 
 
131
 
        # Now open the file
132
 
        file = open(self.filename)
133
 
        src = InputSource(getattr(file, 'name', '<string>'))
134
 
        src.setByteStream(file)
135
 
 
136
 
        # and parse it
137
 
        parser.parse(src)
138
 
 
139
 
        # Finally we retrieve the root element, have it provide a special root
140
 
        # directive interface and give it a location, so that we can do local
141
 
        # lookups.
142
 
        root = handler.rootElement
143
 
        directlyProvides(root, IRootDirective)
144
 
        root.__parent__ = self
145
 
        return root
146
 
 
147
 
    rootElement = Lazy(rootElement)