* fix: do not raise error when encoding/formatting an optional class elt.
* cleanup * make autoxml pass the basic tests
This commit is contained in:
+26
-34
@@ -1,4 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (C) 2005, TUBITAK/UEKAE
|
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||||
#
|
#
|
||||||
@@ -160,7 +161,7 @@ class autoxml(type):
|
|||||||
|
|
||||||
def __init__(cls, name, bases, dict):
|
def __init__(cls, name, bases, dict):
|
||||||
"""entry point for metaclass code"""
|
"""entry point for metaclass code"""
|
||||||
print 'generating class', name
|
#print 'generating class', name
|
||||||
|
|
||||||
# add XmlFile as one of the superclasses, we're smart
|
# add XmlFile as one of the superclasses, we're smart
|
||||||
bases = list(bases)
|
bases = list(bases)
|
||||||
@@ -227,55 +228,42 @@ class autoxml(type):
|
|||||||
|
|
||||||
def gen_attr_member(cls, attr):
|
def gen_attr_member(cls, attr):
|
||||||
"""generate readers and writers for an attribute member"""
|
"""generate readers and writers for an attribute member"""
|
||||||
print 'attr:', attr
|
#print 'attr:', attr
|
||||||
spec = getattr(cls, 'a_' + attr)
|
spec = getattr(cls, 'a_' + attr)
|
||||||
tag_type = spec[0]
|
tag_type = spec[0]
|
||||||
assert type(tag_type) == type(type)
|
assert type(tag_type) == type(type)
|
||||||
def readtext(node, attr):
|
def readtext(node, attr):
|
||||||
return getNodeAttribute(node, attr)
|
return getNodeAttribute(node, attr)
|
||||||
def createnode(xml, attr_name):
|
|
||||||
print 'create attr', attr_name
|
|
||||||
return xml.newAttribute(attr_name) # create an attribute node
|
|
||||||
def writetext(xml, node, attr, text):
|
def writetext(xml, node, attr, text):
|
||||||
print 'write attr', attr, text
|
#print 'write attr', attr, text
|
||||||
node.setAttribute(attr, text)
|
node.setAttribute(attr, text)
|
||||||
anonfuns = cls.gen_anon_basic(attr, spec, readtext, createnode, writetext)
|
anonfuns = cls.gen_anon_basic(attr, spec, readtext, writetext)
|
||||||
def mergetext(node, newattr):
|
return cls.gen_named_comp(attr, spec, anonfuns)
|
||||||
print 'merge attr', node, attr
|
|
||||||
node.setAttributeNode(newattr)
|
|
||||||
return cls.gen_named_comp(attr, spec, anonfuns, mergetext)
|
|
||||||
|
|
||||||
def gen_tag_member(cls, tag):
|
def gen_tag_member(cls, tag):
|
||||||
"""generate helper funs for tag member of class"""
|
"""generate helper funs for tag member of class"""
|
||||||
print 'tag:', tag
|
#print 'tag:', tag
|
||||||
spec = getattr(cls, 't_' + tag)
|
spec = getattr(cls, 't_' + tag)
|
||||||
anonfuns = cls.gen_tag(tag, spec)
|
anonfuns = cls.gen_tag(tag, spec)
|
||||||
def mergetext(node, newnode):
|
return cls.gen_named_comp(tag, spec, anonfuns)
|
||||||
print 'merge tag', node, newnode
|
|
||||||
node.appendChild(newnode)
|
|
||||||
return cls.gen_named_comp(tag, spec, anonfuns, mergetext)
|
|
||||||
|
|
||||||
def gen_tag(cls, tag, spec):
|
def gen_tag(cls, tag, spec):
|
||||||
"""generate readers and writers for the tag"""
|
"""generate readers and writers for the tag"""
|
||||||
tag_type = spec[0]
|
tag_type = spec[0]
|
||||||
if type(tag_type) is types.TypeType:
|
if type(tag_type) is types.TypeType:
|
||||||
def readtext(node, tagpath):
|
def readtext(node, tagpath):
|
||||||
print 'read tag', node, tagpath
|
#print 'read tag', node, tagpath
|
||||||
return getNodeText(node, tagpath)
|
return getNodeText(node, tagpath)
|
||||||
def createnode(xml, tag):
|
|
||||||
print 'create node', tag
|
|
||||||
return xml.newNode(tag)
|
|
||||||
def writetext(xml, node, tagpath, text):
|
def writetext(xml, node, tagpath, text):
|
||||||
print 'write tag', node, tagpath, text
|
#print 'write tag', node, tagpath, text
|
||||||
xml.addTextNodeUnder(node, tagpath, text)
|
xml.addTextNodeUnder(node, tagpath, text)
|
||||||
return cls.gen_anon_basic(tag, spec, readtext,
|
return cls.gen_anon_basic(tag, spec, readtext, writetext)
|
||||||
createnode, writetext)
|
|
||||||
elif type(tag_type) is types.ListType:
|
elif type(tag_type) is types.ListType:
|
||||||
return cls.gen_list_tag(tag, spec)
|
return cls.gen_list_tag(tag, spec)
|
||||||
elif type(tag_type) is autoxml or type(tag_type) is types.ClassType:
|
elif type(tag_type) is autoxml or type(tag_type) is types.ClassType:
|
||||||
return cls.gen_class_tag(tag, spec)
|
return cls.gen_class_tag(tag, spec)
|
||||||
|
|
||||||
def gen_named_comp(cls, token, spec, anonfuns, mergetext):
|
def gen_named_comp(cls, token, spec, anonfuns):
|
||||||
"""generate a named component tag/attr. a decoration of
|
"""generate a named component tag/attr. a decoration of
|
||||||
anonymous functions that do not bind to variable names"""
|
anonymous functions that do not bind to variable names"""
|
||||||
name = cls.mixed_case(token)
|
name = cls.mixed_case(token)
|
||||||
@@ -345,7 +333,7 @@ class autoxml(type):
|
|||||||
# the token
|
# the token
|
||||||
return name, token_type, req, path
|
return name, token_type, req, path
|
||||||
|
|
||||||
def gen_anon_basic(cls, token, spec, readtext, createnode, writetext):
|
def gen_anon_basic(cls, token, spec, readtext, writetext):
|
||||||
"""Generate a tag or attribute with one of the basic
|
"""Generate a tag or attribute with one of the basic
|
||||||
types like integer. This has got to be pretty generic
|
types like integer. This has got to be pretty generic
|
||||||
so that we can invoke it from the complex types such as Class
|
so that we can invoke it from the complex types such as Class
|
||||||
@@ -361,7 +349,7 @@ class autoxml(type):
|
|||||||
def decode(node):
|
def decode(node):
|
||||||
"""decode from DOM node, the value, watching the spec"""
|
"""decode from DOM node, the value, watching the spec"""
|
||||||
text = readtext(node, token)
|
text = readtext(node, token)
|
||||||
print 'read text ', text
|
#print 'read text ', text
|
||||||
if text:
|
if text:
|
||||||
try:
|
try:
|
||||||
value = autoxml.basic_cons_map[token_type](text)
|
value = autoxml.basic_cons_map[token_type](text)
|
||||||
@@ -377,7 +365,6 @@ class autoxml(type):
|
|||||||
def encode(xml, node, value):
|
def encode(xml, node, value):
|
||||||
"""encode given value inside DOM node"""
|
"""encode given value inside DOM node"""
|
||||||
if value:
|
if value:
|
||||||
#node = createnode(xml, token)
|
|
||||||
writetext(xml, node, token, str(value))
|
writetext(xml, node, token, str(value))
|
||||||
return node
|
return node
|
||||||
else:
|
else:
|
||||||
@@ -422,16 +409,22 @@ class autoxml(type):
|
|||||||
classnode = node.ownerDocument.createElement(tag)
|
classnode = node.ownerDocument.createElement(tag)
|
||||||
obj.encode(xml, classnode)
|
obj.encode(xml, classnode)
|
||||||
node.appendChild(classnode)
|
node.appendChild(classnode)
|
||||||
return
|
|
||||||
except Error:
|
except Error:
|
||||||
raise Error('Object cannot be encoded')
|
if req == mandatory:
|
||||||
|
# note: we can receive an error if obj has no content
|
||||||
|
raise Error('Object cannot be encoded')
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
raise Error('Mandatory argument not available')
|
||||||
|
|
||||||
def format(obj):
|
def format(obj):
|
||||||
return obj.format()
|
try:
|
||||||
|
return obj.format()
|
||||||
|
except Error:
|
||||||
|
if req == mandatory:
|
||||||
|
raise Error('Mandatory argument not available')
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
return (init, decode, encode, format)
|
return (init, decode, encode, format)
|
||||||
|
|
||||||
def gen_list_tag(cls, tag, spec):
|
def gen_list_tag(cls, tag, spec):
|
||||||
@@ -451,8 +444,7 @@ class autoxml(type):
|
|||||||
def decode(node):
|
def decode(node):
|
||||||
l = []
|
l = []
|
||||||
nodes = getAllNodes(node, tag + '/' + comp_tag)
|
nodes = getAllNodes(node, tag + '/' + comp_tag)
|
||||||
print node, tag + '/' + comp_tag
|
#print node, tag + '/' + comp_tag, nodes
|
||||||
print 'F U', nodes
|
|
||||||
if len(nodes) is 0 and req is mandatory:
|
if len(nodes) is 0 and req is mandatory:
|
||||||
raise Error('Mandatory list empty')
|
raise Error('Mandatory list empty')
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
@@ -462,7 +454,7 @@ class autoxml(type):
|
|||||||
return l
|
return l
|
||||||
|
|
||||||
def encode(xml, node, l):
|
def encode(xml, node, l):
|
||||||
if len(l) > 0:
|
if l and len(l) > 0:
|
||||||
listnode = xml.newNode(tag)
|
listnode = xml.newNode(tag)
|
||||||
for item in l:
|
for item in l:
|
||||||
encode_item(xml, listnode, item)
|
encode_item(xml, listnode, item)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class XmlFileTestCase(unittest.TestCase):
|
|||||||
__metaclass__ = xmlfile.autoxml
|
__metaclass__ = xmlfile.autoxml
|
||||||
t_BirthDate = [types.StringType, xmlfile.mandatory]
|
t_BirthDate = [types.StringType, xmlfile.mandatory]
|
||||||
t_Interest = [types.StringType, xmlfile.optional]
|
t_Interest = [types.StringType, xmlfile.optional]
|
||||||
#t_CodesWith = [ [types.StringType], xmlfile.optional, 'Person']
|
t_CodesWith = [ [types.StringType], xmlfile.optional, 'Person']
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
__metaclass__ = xmlfile.autoxml
|
__metaclass__ = xmlfile.autoxml
|
||||||
@@ -58,17 +58,16 @@ class XmlFileTestCase(unittest.TestCase):
|
|||||||
xml = xmlfile.XmlFile('A')
|
xml = xmlfile.XmlFile('A')
|
||||||
xml.newDOM()
|
xml.newDOM()
|
||||||
a.encode(xml, xml.rootNode())
|
a.encode(xml, xml.rootNode())
|
||||||
#xml.rootNode().appendChild(node)
|
xml.rootNode().appendChild(node)
|
||||||
xml.writexml('/tmp/a.xml')
|
xml.writexml('/tmp/a.xml')
|
||||||
print '/tmp/a.xml written'
|
#print '/tmp/a.xml written'
|
||||||
return
|
|
||||||
xml = xmlfile.XmlFile('A')
|
xml = xmlfile.XmlFile('A')
|
||||||
a2 = A()
|
a2 = A()
|
||||||
a2.name = "Baris Metin"
|
a2.name = "Baris Metin"
|
||||||
a2.email = "baris@uludag.org.tr"
|
a2.email = "baris@uludag.org.tr"
|
||||||
a2.href = 'http://cekirdek.uludag.org.tr/~baris'
|
a2.href = 'http://cekirdek.uludag.org.tr/~baris'
|
||||||
a2.projects = [ 'pisi', 'tasma', 'plasma' ]
|
a2.projects = [ 'pisi', 'tasma', 'plasma' ]
|
||||||
a2.encode(xml)
|
a2.encode(xml, xml.rootNode())
|
||||||
xml.writexml('/tmp/a2.xml')
|
xml.writexml('/tmp/a2.xml')
|
||||||
string = a2.format()
|
string = a2.format()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user