Commit b444381a authored by Guido van Rossum's avatar Guido van Rossum
parent aa3e9a03
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
Make an exact copy of a DOM document (sub)tree.
"""
from xml.dom import Node
from DOMVisitor import DOMVisitor
class CopyingDOMVisitor(DOMVisitor):
def __init__(self, rootNode, documentFactory):
DOMVisitor.__init__(self, rootNode)
self.documentFactory = documentFactory
def __call__(self):
self.newDocument = None
self.curNode = None
DOMVisitor.__call__(self)
return self.newDocument
def visitElement(self, node):
self.copyElement(node)
DOMVisitor.visitElement(self, node)
def endVisitElement(self, node):
self.curNode = self.curNode.parentNode
def copyElement(self, node):
if self.newDocument is None:
# This must be the documentElement node. Create the
# document now; this also creates the documentElement node
self.newDocument = self.documentFactory.createDocument(
None, node.nodeName, None)
newNode = self.newDocument.documentElement
else:
newNode = self.newDocument.createElement(node.nodeName)
self.curNode.appendChild(newNode)
self.curNode = newNode
def visitText(self, node):
newNode = self.newDocument.createTextNode(node.nodeValue)
self.curNode.appendChild(newNode)
def visitComment(self, node):
newNode = self.newDocument.createComment(node.nodeValue)
self.curNode.appendChild(newNode)
def visitAttribute(self, node):
if node.namespaceURI:
self.curNode.setAttributeNS(
node.namespaceURI, node.nodeName, node.nodeValue)
else:
self.curNode.setAttribute(node.nodeName, node.nodeValue)
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
Visitor class for DOM trees.
XXX Assumptions: only Document and Element nodes have children worth
visiting. This is probably wrong, but good enough for now. Please
let me know which node types I should also deal with!
XXX This may not be as general as the Visitor class in product
ParsedXML.Printer.py, but that uses ParsedXML.DOM.Traversal, and I
don't want this class to depend on the DOM implementation there.
"""
from xml.dom import Node
class DOMVisitor:
"""
Visitor class for DOM trees.
Subclass this class, overriding methods for visiting the various
node types. Instantiate your subclass with a particular DOM node
to create a visitor instance for the DOM subtree rooted at that
node. Call your instance to visit each node in that subtree once,
in document order.
There's a visit<NodeType>() method for each node type. There's
also a visitUnknown() which is called for unrecognized node types
(which shouldn't happen if you are using a standard DOM
implementation).
You can influence which nodes are visited in which order by
overriding visitAllChildren() and visitAllAttributes(), and/or by
overriding visitDocument() and visitElement(). If you override
the latter two, be careful to either call the base class method or
call visitAllAttributes(), visitAllChildren() and
endVisitElement() as shown in their base class implementations,
otherwise the tree traversal will break.
"""
def __init__(self, rootNode):
"""
Construct a visitor instance.
Arguments:
rootNode: the root of the subtree to be traversed. This is
typically a document node or an element node.
"""
self.rootNode = rootNode
def __call__(self):
"""
Traverse the subtree given to the constructor.
"""
self.visitNode(self.rootNode)
def visitNode(self, node):
"""
Visit any type of node.
This switches out to one of the node-specific visitor methods.
The recursing down into children is handled by calling
visitAllChildren() in the node-specific visitor methods.
"""
methodName = self.visitSwitch.get(node.nodeType, "visitUnknown")
method = getattr(self, methodName)
method(node)
# Dictionary mapping node types to method names, used in visitNode
visitSwitch = {
Node.ELEMENT_NODE: "visitElement",
Node.ATTRIBUTE_NODE: "visitAttr",
Node.TEXT_NODE: "visitText",
Node.CDATA_SECTION_NODE: "visitCDATASection",
Node.ENTITY_REFERENCE_NODE: "visitEntityReference",
Node.ENTITY_NODE: "visitEntity",
Node.PROCESSING_INSTRUCTION_NODE: "visitProcessingInstruction",
Node.COMMENT_NODE: "visitComment",
Node.DOCUMENT_NODE: "visitDocument",
Node.DOCUMENT_TYPE_NODE: "visitDocumentType",
Node.DOCUMENT_FRAGMENT_NODE: "visitDocumentFragment",
Node.NOTATION_NODE: "visitNotation",
}
def visitUnknown(self, node):
"""
Visit a node of an unknown type.
"""
pass
def visitDocument(self, node):
"""
Visit a document node.
This calls visitAllChildren() to recurse into the document tree.
"""
self.visitAllChildren(node)
def visitElement(self, node):
"""
Visit an element node.
This calls visitAllAttributes() to visit the attributes, and
visitAllChildren() to recurse into the document tree. It also
calls endVisitElement() in order to signal the end of the visit.
"""
self.visitAllAttributes(node)
self.visitAllChildren(node)
self.endVisitElement(node)
def endVisitElement(self, node):
"""
This method is called after visitElement has finished visiting
all its children. It is useful for processing to be done
after the element's subtree has been visited, e.g. spitting
out an end tag or closing a scope.
"""
pass
def visitAllChildren(self, node):
"""
Call visitNode() for each child of the given node.
"""
for child in node.childNodes:
self.visitNode(child)
def visitAllAttributes(self, node):
"""
Call visitAttribute() for each attribute of the given node.
"""
for attr in node.attributes.values():
self.visitAttribute(attr)
def visitAttribute(self, node):
"""
Override this empty method to visit an attribute node.
"""
pass
def visitText(self, node):
"""
Override this empty method to visit a text node.
"""
pass
def visitCDATASection(self, node):
"""
Override this empty method to visit a CDATA section node.
"""
pass
def visitEntityReference(self, node):
"""
Override this empty method to visit an entity reference node.
"""
pass
def visitEntity(self, node):
"""
Override this empty method to visit an entity node.
"""
self.visitAllChildren(node)
def visitProcessingInstruction(self, node):
"""
Override this empty method to visit a processing instruction node.
"""
pass
def visitComment(self, node):
"""
Override this empty method to visit a comment node.
"""
pass
def visitDocumentType(self, node):
"""
Override this empty method to visit a document type node.
"""
pass
def visitDocumentFragment(self, node):
"""
Override this empty method to visit a document fragment node.
"""
pass
def visitNotation(self, node):
"""
Override this empty method to visit a notation node.
"""
pass
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
Dummy TALES engine so that I can test out the TAL implementation.
"""
import re
import string
from TALVisitor import NAME_RE
class DummyEngine:
def __init__(self):
self.locals = {}
self.globals = {}
# XXX scopes
def setLocal(self, name, value):
self.locals[name] = value
def setGlobal(self, name, value):
self.globals[name] = value
def evaluate(self, expression):
m = re.match(r"(%s):(.*)" % NAME_RE, expression)
if m:
type, expr = m.group(1, 2)
else:
type = "var"
expr = expression
if type == "str":
return expr
if type == "local":
return self.locals[string.strip(expr)]
if type == "global":
return self.globals[string.strip(expr)]
if type == "var":
expr = string.strip(expr)
if self.locals.has_key(expr):
return self.locals[expr]
else:
return self.globals[expr]
if type == "python":
return eval(expr, self.globals, self.locals)
print "Unrecognized expression:", `expression`
return None
def evaluateValue(self, expr):
return self.evaluate(expr)
def evaluateBoolean(self, expr):
return self.evaluate(expr)
def evaluateText(self, expr):
return self.evaluate(expr)
def evaluateStructure(self, expr):
return self.evaluate(expr)
def evaluateSequence(self, expr):
return self.evaluate(expr)
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
Copy a DOM tree, applying TAL (Template Attribute Language) transformations.
"""
import string
import re
from xml.dom import Node
from CopyingDOMVisitor import CopyingDOMVisitor
ZOPE_TAL_NS = "http://xml.zope.org/namespaces/tal"
NAME_RE = "[a-zA-Z_][a-zA-Z0-9_]*"
class TALVisitor(CopyingDOMVisitor):
"""
Copy a DOM tree while applying TAL transformations.
The DOM tree must have been created with XML namespace information
included (i.e. I'm not going to interpret your xmlns* attributes
for you), otherwise we will make an unmodified copy.
"""
def __init__(self, document, documentFactory, engine):
CopyingDOMVisitor.__init__(self, document, documentFactory)
self.engine = engine
def visitElement(self, node):
if not self.checkTAL(node):
CopyingDOMVisitor.visitElement(self, node)
def checkTAL(self, node):
# Do TAL expansion. Return value is 1 if node expansion
# complete, 0 if original node should be copied.
attrs = node.attributes
if not attrs:
return 0
# Collect TAL attributes
setOps = []
ifOps = []
modOps = []
attrOps = []
omit = 0
for attr in attrs.values():
if attr.namespaceURI == ZOPE_TAL_NS:
name = attr.localName
if name == "define":
setOps.append(attr)
elif name == "condition":
ifOps.append(attr)
elif name in ("insert", "replace"):
modOps.append(attr)
elif name == "attributes":
attrOps.append(attr)
elif name == "omit":
omit = 1
else:
print "Unrecognized ZOPE/TAL attribute:",
print "%s=%s" % (attr.nodeName, `attr.nodeValue`)
# This doesn't stop us from doing the rest!
# If any of these assertions fail, the DOM is broken
assert len(setOps) <= 1
assert len(ifOps) <= 1
assert len(attrOps) <= 1
# Execute TAL attributes in proper order:
# 0. omit, 1. define, 2. condition, 3. insert/replace, 4. attributes
if omit:
if setOps or ifOps or modOps or attrOps:
print "Note: z:omit conflicts with all other z:... attributes"
return 1
if setOps:
[attr] = setOps
self.doDefine(node, attr.nodeValue)
if ifOps:
[attr] = ifOps
if not self.doCondition(node, attr.nodeValue):
return 1
attrDict = {}
if attrOps:
[attr] = attrOps
attrDict = self.prepAttr(node, attr.nodeValue)
if len(modOps) > 1:
names = map(lambda a: a.nodeName, modOps)
print "Mutually exclusive ZOPE/TAL attributes:", [names]
elif modOps:
[attr] = modOps
return self.doModify(
node, attr.localName, attr.nodeValue, attrDict)
if attrDict:
##saveNode = self.curNode
self.copyElement(node)
self.copyAttributes(node, attrDict)
self.visitAllChildren(node)
self.endVisitElement(node)
##self.curNode = saveNode
return 1
return 0
def doDefine(self, node, arg):
for part in self.splitParts(arg):
m = re.match(
r"\s*(global\s+|local\s+)?(%s)\s+as\s+(.*)" % NAME_RE, part)
if not m:
print "Bad syntax in z:define argument:", `part`
else:
scope, name, expr = m.group(1, 2, 3)
scope = string.strip(scope or "local")
value = self.engine.evaluateValue(expr)
if scope == "local":
self.engine.setLocal(name, value)
else:
self.engine.setGlobal(name, value)
def doCondition(self, node, arg):
return self.engine.evaluateBoolean(arg)
def doModify(self, node, cmdName, arg, attrDict):
assert cmdName in ("insert", "replace")
inserting = (cmdName == "insert")
m = re.match(
r"(?:\s*(text|structure|for\s+(%s)\s+in)\s+)?(.*)" % NAME_RE, arg)
if not m:
print "Bad syntax in z:insert/replace:", `arg`
return 0
key, name, expr = m.group(1, 2, 3)
if not key:
key = "text"
saveNode = self.curNode
if key[:3] == "for":
if inserting:
rv = self.doInsertLoop(node, key, name, expr, attrDict)
else:
rv = self.doReplaceLoop(node, key, name, expr, attrDict)
else:
rv = self.doNonLoop(node, inserting, key, expr, attrDict)
self.curNode = saveNode
return rv
def doInsertLoop(self, node, key, name, expr, attrDict):
sequence = self.engine.evaluateSequence(expr)
self.copyElement(node)
self.copyAttributes(node, attrDict)
for item in sequence:
self.engine.setLocal(name, item)
self.visitAllChildren(node)
self.endVisitElement(node)
return 1
def doReplaceLoop(self, node, key, name, expr, attrDict):
if not self.newDocument:
print "Can't have a z:replace for loop on the documentElement"
return 0
sequence = self.engine.evaluateSequence(expr)
for item in sequence:
self.engine.setLocal(name, item)
self.copyElement(node)
self.copyAttributes(node, attrDict)
self.visitAllChildren(node)
self.endVisitElement(node)
return 1
def doNonLoop(self, node, inserting, key, expr, attrDict):
if inserting:
self.copyElement(node)
self.copyAttributes(node, attrDict)
if key == "text":
if attrDict:
print "Warning: z:attributes unused for text replacement"
data = self.engine.evaluateText(expr)
newChild = self.newDocument.createTextNode(str(data))
self.curNode.appendChild(newChild)
if key == "structure":
data = self.engine.evaluateStructure(expr)
attrDone = inserting or not attrDict
for newChild in data:
self.curNode.appendChild(newChild)
if not attrDone and newChild.nodeType == ELEMENT_NODE:
self.changeAttributes(newChild, attrDict)
attrDone = 1
if not attrDone:
# Apparently no element nodes were inserted
print "Warning: z:attributes unused for struct replacement"
return 1
def copyAttributes(self, node, attrDict):
for attr in node.attributes.values():
namespaceURI = attr.namespaceURI
attrName = attr.nodeName
attrValue = attr.nodeValue
if attrDict.has_key(attrName):
expr = attrDict[attrName]
if string.strip(expr) == "nothing":
continue
attrValue = self.engine.evaluateText(expr)
if attrValue is None:
continue
if namespaceURI:
self.curNode.setAttributeNS(namespaceURI, attrName, attrValue)
else:
self.curNode.setAttribute(attrName, attrValue)
def prepAttr(self, node, arg):
dict = {}
for part in self.splitParts(arg):
m = re.match(r"\s*([^\s=]+)\s*=\s*(.*)", part)
if not m:
print "Bad syntax in z:attributes:", `part`
continue
name, expr = m.group(1, 2)
if dict.has_key(name):
print "Duplicate attribute name in z:attributes:", `part`
continue
dict[name] = expr
return dict
def splitParts(self, arg):
# Break in pieces at undoubled semicolons and
# change double semicolons to singles:
parts = string.split(arg, ';')
while "" in parts:
i = parts.index("")
if i+1 >= len(parts):
break
parts[i-1:i+2] = ["%s;%s" % (parts[i-1], parts[i+1])]
return parts
#! /usr/bin/env python1.5
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
Driver program to test TALVisitor and its base class CopyingDOMVisitor.
"""
import sys
import getopt
import setpath # Local hack to tweak sys.path etc.
# Use the ParsedXML product and its DOM implementation
from Products.ParsedXML import Printer
from Products.ParsedXML.DOM import Core, ExpatBuilder
# Import local classes
from CopyingDOMVisitor import CopyingDOMVisitor
from TALVisitor import TALVisitor
from DummyEngine import DummyEngine
FILE = "test/test1.xml"
def main():
noVersionTest = 0
try:
opts, args = getopt.getopt(sys.argv[1:], "n")
except getopt.error, msg:
sys.stderr.write("%s\n" % str(msg))
sys.stderr.write("usage: driver.py [-n] [file]\n")
sys.stderr.write("-n turns of the Python 1.5.2 test\n")
sys.exit(2)
for o, a in opts:
if o == '-n':
noVersionTest = 1
if not noVersionTest:
if sys.version[:5] != "1.5.2":
sys.stderr.write(
"Use Python 1.5.2 only; use -n to disable this test\n")
sys.exit(2)
if args:
file = args[0]
else:
file = FILE
doc = parsefile(file)
doc = talizetree(doc)
printtree(doc)
def parsefile(file):
return ExpatBuilder.parse(file, 1)
def printtree(node, stream=None, encoding=None):
if stream is None:
stream = sys.stdout
Printer.PrintVisitor(node, stream, encoding)()
def copytree(root, dom=None):
if dom is None:
dom = Core.theDOMImplementation
return CopyingDOMVisitor(root, dom)()
def talizetree(root, dom=None, engine=None):
if dom is None:
dom = Core.theDOMImplementation
if engine is None:
engine = DummyEngine()
return TALVisitor(root, dom, engine)()
if __name__ == "__main__":
main()
"""
Edit this file to set the proper module search path.
"""
import os
import sys
home = os.path.expanduser("~")
projects = os.path.join(home, 'projects')
zope2 = os.path.join(projects, 'Zope2')
libPython = os.path.join(zope2, 'lib', 'python')
sys.path.append(libPython)
import ZODB # Must import this first to initialize Persistence properly
#! /usr/bin/env python1.5
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""
Helper program to time TALVisitor and other DOM tree operations.
"""
import sys
import time
import getopt
from driver import parsefile, copytree, talizetree, printtree, FILE
def main():
count = 10
try:
opts, args = getopt.getopt(sys.argv[1:], "n:")
except getopt.error, msg:
print msg
sys.exit(2)
for o, a in opts:
if o == "-n":
count = int(a)
if args:
file = args[0]
else:
file = FILE
doc = timefunc(count, parsefile, file)
doc = timefunc(count, copytree, doc)
doc = timefunc(count, talizetree, doc)
timefunc(count, printtree, doc, open("/dev/null", "w"))
def timefunc(count, func, *args):
t0 = time.clock()
for i in range(count):
result = apply(func, args)
t1 = time.clock()
sys.stderr.write("%.3f secs to %s %d times, i.e. %.0f msecs per call\n"
% ((t1-t0), func.__name__, count, 1000*(t1-t0)/count))
return result
if __name__ == "__main__":
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment