annotate PageTemplates/Expressions.py @ 1042:adcfdeac4e76

not sure how useful this is...
author Richard Jones <richard@users.sourceforge.net>
date Wed, 04 Sep 2002 04:47:28 +0000
parents a3a8ac7b8c40
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
984
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
1 ##############################################################################
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
2 #
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
4 #
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
5 # This software is subject to the provisions of the Zope Public License,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
6 # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
10 # FOR A PARTICULAR PURPOSE
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
11 #
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
12 ##############################################################################
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
13
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
14 """Page Template Expression Engine
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
15
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
16 Page Template-specific implementation of TALES, with handlers
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
17 for Python expressions, string literals, and paths.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
18 """
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
19
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
20 __version__='$Revision: 1.1 $'[11:-2]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
21
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
22 import re, sys
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
23 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
24 Undefined, Default, _parse_expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
25 from string import strip, split, join, replace, lstrip
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
26 from Acquisition import aq_base, aq_inner, aq_parent
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
27
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
28
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
29 _engine = None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
30 def getEngine():
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
31 global _engine
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
32 if _engine is None:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
33 from PathIterator import Iterator
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
34 _engine = Engine(Iterator)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
35 installHandlers(_engine)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
36 return _engine
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
37
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
38 def installHandlers(engine):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
39 reg = engine.registerType
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
40 pe = PathExpr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
41 for pt in ('standard', 'path', 'exists', 'nocall'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
42 reg(pt, pe)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
43 reg('string', StringExpr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
44 reg('python', PythonExpr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
45 reg('not', NotExpr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
46 reg('defer', DeferExpr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
47
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
48 if sys.modules.has_key('Zope'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
49 import AccessControl
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
50 from AccessControl import getSecurityManager
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
51 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
52 from AccessControl import Unauthorized
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
53 except ImportError:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
54 Unauthorized = "Unauthorized"
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
55 if hasattr(AccessControl, 'full_read_guard'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
56 from ZRPythonExpr import PythonExpr, _SecureModuleImporter, \
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
57 call_with_ns
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
58 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
59 from ZPythonExpr import PythonExpr, _SecureModuleImporter, \
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
60 call_with_ns
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
61 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
62 from PythonExpr import getSecurityManager, PythonExpr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
63 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
64 from zExceptions import Unauthorized
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
65 except ImportError:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
66 Unauthorized = "Unauthorized"
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
67 def call_with_ns(f, ns, arg=1):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
68 if arg==2:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
69 return f(None, ns)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
70 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
71 return f(ns)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
72
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
73 class _SecureModuleImporter:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
74 """Simple version of the importer for use with trusted code."""
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
75 __allow_access_to_unprotected_subobjects__ = 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
76 def __getitem__(self, module):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
77 __import__(module)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
78 return sys.modules[module]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
79
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
80 SecureModuleImporter = _SecureModuleImporter()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
81
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
82 Undefs = (Undefined, AttributeError, KeyError,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
83 TypeError, IndexError, Unauthorized)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
84
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
85 def render(ob, ns):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
86 """
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
87 Calls the object, possibly a document template, or just returns it if
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
88 not callable. (From DT_Util.py)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
89 """
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
90 if hasattr(ob, '__render_with_namespace__'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
91 ob = call_with_ns(ob.__render_with_namespace__, ns)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
92 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
93 base = aq_base(ob)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
94 if callable(base):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
95 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
96 if getattr(base, 'isDocTemp', 0):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
97 ob = call_with_ns(ob, ns, 2)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
98 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
99 ob = ob()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
100 except AttributeError, n:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
101 if str(n) != '__call__':
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
102 raise
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
103 return ob
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
104
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
105 class SubPathExpr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
106 def __init__(self, path):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
107 self._path = path = split(strip(path), '/')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
108 self._base = base = path.pop(0)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
109 if not _valid_name(base):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
110 raise CompilerError, 'Invalid variable name "%s"' % base
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
111 # Parse path
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
112 self._dp = dp = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
113 for i in range(len(path)):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
114 e = path[i]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
115 if e[:1] == '?' and _valid_name(e[1:]):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
116 dp.append((i, e[1:]))
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
117 dp.reverse()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
118
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
119 def _eval(self, econtext,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
120 list=list, isinstance=isinstance, StringType=type('')):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
121 vars = econtext.vars
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
122 path = self._path
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
123 if self._dp:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
124 path = list(path) # Copy!
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
125 for i, varname in self._dp:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
126 val = vars[varname]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
127 if isinstance(val, StringType):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
128 path[i] = val
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
129 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
130 # If the value isn't a string, assume it's a sequence
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
131 # of path names.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
132 path[i:i+1] = list(val)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
133 __traceback_info__ = base = self._base
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
134 if base == 'CONTEXTS':
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
135 ob = econtext.contexts
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
136 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
137 ob = vars[base]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
138 if isinstance(ob, DeferWrapper):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
139 ob = ob()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
140 if path:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
141 ob = restrictedTraverse(ob, path, getSecurityManager())
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
142 return ob
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
143
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
144 class PathExpr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
145 def __init__(self, name, expr, engine):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
146 self._s = expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
147 self._name = name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
148 paths = split(expr, '|')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
149 self._subexprs = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
150 add = self._subexprs.append
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
151 for i in range(len(paths)):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
152 path = lstrip(paths[i])
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
153 if _parse_expr(path):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
154 # This part is the start of another expression type,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
155 # so glue it back together and compile it.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
156 add(engine.compile(lstrip(join(paths[i:], '|'))))
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
157 break
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
158 add(SubPathExpr(path)._eval)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
159
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
160 def _exists(self, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
161 for expr in self._subexprs:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
162 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
163 expr(econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
164 except Undefs:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
165 pass
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
166 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
167 return 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
168 return 0
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
169
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
170 def _eval(self, econtext,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
171 isinstance=isinstance, StringType=type(''), render=render):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
172 for expr in self._subexprs[:-1]:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
173 # Try all but the last subexpression, skipping undefined ones.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
174 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
175 ob = expr(econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
176 except Undefs:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
177 pass
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
178 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
179 break
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
180 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
181 # On the last subexpression allow exceptions through.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
182 ob = self._subexprs[-1](econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
183
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
184 if self._name == 'nocall' or isinstance(ob, StringType):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
185 return ob
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
186 # Return the rendered object
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
187 return render(ob, econtext.vars)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
188
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
189 def __call__(self, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
190 if self._name == 'exists':
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
191 return self._exists(econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
192 return self._eval(econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
193
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
194 def __str__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
195 return '%s expression %s' % (self._name, `self._s`)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
196
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
197 def __repr__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
198 return '%s:%s' % (self._name, `self._s`)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
199
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
200
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
201 _interp = re.compile(r'\$(%(n)s)|\${(%(n)s(?:/%(n)s)*)}' % {'n': NAME_RE})
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
202
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
203 class StringExpr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
204 def __init__(self, name, expr, engine):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
205 self._s = expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
206 if '%' in expr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
207 expr = replace(expr, '%', '%%')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
208 self._vars = vars = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
209 if '$' in expr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
210 parts = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
211 for exp in split(expr, '$$'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
212 if parts: parts.append('$')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
213 m = _interp.search(exp)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
214 while m is not None:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
215 parts.append(exp[:m.start()])
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
216 parts.append('%s')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
217 vars.append(PathExpr('path', m.group(1) or m.group(2),
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
218 engine))
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
219 exp = exp[m.end():]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
220 m = _interp.search(exp)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
221 if '$' in exp:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
222 raise CompilerError, (
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
223 '$ must be doubled or followed by a simple path')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
224 parts.append(exp)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
225 expr = join(parts, '')
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
226 self._expr = expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
227
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
228 def __call__(self, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
229 vvals = []
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
230 for var in self._vars:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
231 v = var(econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
232 if isinstance(v, Exception):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
233 raise v
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
234 vvals.append(v)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
235 return self._expr % tuple(vvals)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
236
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
237 def __str__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
238 return 'string expression %s' % `self._s`
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
239
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
240 def __repr__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
241 return 'string:%s' % `self._s`
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
242
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
243 class NotExpr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
244 def __init__(self, name, expr, compiler):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
245 self._s = expr = lstrip(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
246 self._c = compiler.compile(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
247
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
248 def __call__(self, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
249 return not econtext.evaluateBoolean(self._c)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
250
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
251 def __repr__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
252 return 'not:%s' % `self._s`
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
253
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
254 class DeferWrapper:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
255 def __init__(self, expr, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
256 self._expr = expr
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
257 self._econtext = econtext
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
258
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
259 def __str__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
260 return str(self())
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
261
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
262 def __call__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
263 return self._expr(self._econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
264
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
265 class DeferExpr:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
266 def __init__(self, name, expr, compiler):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
267 self._s = expr = lstrip(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
268 self._c = compiler.compile(expr)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
269
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
270 def __call__(self, econtext):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
271 return DeferWrapper(self._c, econtext)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
272
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
273 def __repr__(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
274 return 'defer:%s' % `self._s`
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
275
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
276
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
277 def restrictedTraverse(self, path, securityManager,
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
278 get=getattr, has=hasattr, N=None, M=[],
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
279 TupleType=type(()) ):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
280
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
281 REQUEST = {'path': path}
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
282 REQUEST['TraversalRequestNameStack'] = path = path[:] # Copy!
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
283 if not path[0]:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
284 # If the path starts with an empty string, go to the root first.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
285 self = self.getPhysicalRoot()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
286 if not securityManager.validateValue(self):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
287 raise Unauthorized, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
288 path.pop(0)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
289
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
290 path.reverse()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
291 validate = securityManager.validate
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
292 object = self
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
293 #print 'TRAVERSE', (object, path)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
294 while path:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
295 __traceback_info__ = REQUEST
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
296 name = path.pop()
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
297
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
298 if isinstance(name, TupleType):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
299 object = apply(object, name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
300 continue
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
301
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
302 if name[0] == '_':
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
303 # Never allowed in a URL.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
304 raise AttributeError, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
305
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
306 if name=='..':
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
307 o = get(object, 'aq_parent', M)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
308 if o is not M:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
309 if not validate(object, object, name, o):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
310 raise Unauthorized, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
311 object=o
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
312 continue
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
313
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
314 t = get(object, '__bobo_traverse__', N)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
315 if t is not N:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
316 o=t(REQUEST, name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
317
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
318 container = None
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
319 if has(o, 'im_self'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
320 container = o.im_self
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
321 elif (has(get(object, 'aq_base', object), name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
322 and get(object, name) == o):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
323 container = object
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
324 if not validate(object, container, name, o):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
325 raise Unauthorized, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
326 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
327 # Try an attribute.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
328 o = get(object, name, M)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
329 # print '...', (object, name, M, o)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
330 if o is not M:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
331 # Check access to the attribute.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
332 if has(object, 'aq_acquire'):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
333 object.aq_acquire(
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
334 name, validate2, validate)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
335 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
336 if not validate(object, object, name, o):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
337 raise Unauthorized, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
338 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
339 # Try an item.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
340 try:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
341 # XXX maybe in Python 2.2 we can just check whether
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
342 # the object has the attribute "__getitem__"
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
343 # instead of blindly catching exceptions.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
344 # print 'Try an item', (object, name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
345 o = object[name]
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
346 except AttributeError, exc:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
347 if str(exc).find('__getitem__') >= 0:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
348 # The object does not support the item interface.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
349 # Try to re-raise the original attribute error.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
350 # XXX I think this only happens with
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
351 # ExtensionClass instances.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
352 get(object, name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
353 raise
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
354 except TypeError, exc:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
355 if str(exc).find('unsubscriptable') >= 0:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
356 # The object does not support the item interface.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
357 # Try to re-raise the original attribute error.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
358 # XXX This is sooooo ugly.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
359 get(object, name)
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
360 raise
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
361 else:
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
362 # Check access to the item.
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
363 if not validate(object, object, name, o):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
364 raise Unauthorized, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
365 #print '... object is now', `o`
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
366 object = o
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
367
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
368 return object
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
369
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
370
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
371 def validate2(orig, inst, name, v, real_validate):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
372 if not real_validate(orig, inst, name, v):
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
373 raise Unauthorized, name
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
374 return 1
a3a8ac7b8c40 Adding PageTemplates to the dist
Richard Jones <richard@users.sourceforge.net>
parents:
diff changeset
375

Roundup Issue Tracker: http://roundup-tracker.org/