* autoxml'e error altyapisi ekle
* todo'da muhtelif ilerlemeler * sittiimin DOM'u
This commit is contained in:
@@ -74,15 +74,9 @@ Legend:
|
|||||||
3. Beta
|
3. Beta
|
||||||
|
|
||||||
- configure-pending (eray)
|
- configure-pending (eray)
|
||||||
/ autoxml: automated xml processing (eray)
|
|
||||||
+ design
|
|
||||||
+ basic types
|
|
||||||
+ list type
|
|
||||||
+ class type
|
|
||||||
/ localtext type
|
|
||||||
/ components (eray)
|
/ components (eray)
|
||||||
+ requirements
|
+ requirements
|
||||||
- xml format
|
/ xml format
|
||||||
- query components: list of components/packages in a component
|
- query components: list of components/packages in a component
|
||||||
- install/remove components
|
- install/remove components
|
||||||
/ API: we even have application users (eray)
|
/ API: we even have application users (eray)
|
||||||
@@ -123,6 +117,12 @@ Legend:
|
|||||||
+ Files
|
+ Files
|
||||||
- Index (o kadar onemli degil)
|
- Index (o kadar onemli degil)
|
||||||
? non-interactive use (baris)
|
? non-interactive use (baris)
|
||||||
|
+ autoxml: automated xml processing (eray)
|
||||||
|
+ design
|
||||||
|
+ basic types
|
||||||
|
+ list type
|
||||||
|
+ class type
|
||||||
|
+ localtext type
|
||||||
+ implement missing unit tests
|
+ implement missing unit tests
|
||||||
+ sourcedb
|
+ sourcedb
|
||||||
+ package (baris)
|
+ package (baris)
|
||||||
|
|||||||
+7
-2
@@ -17,21 +17,26 @@ __metaclass__ = xmlfile.autoxml
|
|||||||
|
|
||||||
class Distribution:
|
class Distribution:
|
||||||
t_Name = [xmlfile.Text, xmlfile.mandatory]
|
t_Name = [xmlfile.Text, xmlfile.mandatory]
|
||||||
|
t_Description = [xmlfile.LocalText, xmlfile.mandatory]
|
||||||
t_Version = [xmlfile.Text, xmlfile.mandatory]
|
t_Version = [xmlfile.Text, xmlfile.mandatory]
|
||||||
t_Type = [xmlfile.Text, xmlfile.mandatory]
|
t_Type = [xmlfile.Text, xmlfile.mandatory]
|
||||||
t_Dependencies = [ [xmlfile.Text], xmlfile.optional, "Distribution"]
|
t_Dependencies = [ [xmlfile.Text], xmlfile.optional, "Distribution"]
|
||||||
|
|
||||||
class Component:
|
class Component:
|
||||||
"part-of representation for component declarations"
|
"part-of representation for component declarations"
|
||||||
t_Name = [xmlfile.Text, xmlfile.mandatory]
|
|
||||||
|
t_Name = [xmlfile.Text, xmlfile.mandatory] # fully qualified name
|
||||||
t_PartOf = [xmlfile.Text, xmlfile.mandatory]
|
t_PartOf = [xmlfile.Text, xmlfile.mandatory]
|
||||||
|
t_LocalName = [xmlfile.LocalText, xmlfile.mandatory]
|
||||||
|
t_Description = [xmlfile.LocalText, xmlfile.mandatory]
|
||||||
#t_Icon = [xmlfile.Binary, xmlfile.mandatory]
|
#t_Icon = [xmlfile.Binary, xmlfile.mandatory]
|
||||||
t_Dependencies = [ [xmlfile.String], xmlfile.optional, "Component"]
|
t_Dependencies = [ [xmlfile.String], xmlfile.optional, "Component"]
|
||||||
|
|
||||||
class ComponentTree:
|
class ComponentTree:
|
||||||
"index representation for the component structure"
|
"index representation for the component structure"
|
||||||
tag = "Component"
|
tag = "Component"
|
||||||
t_Name = [xmlfile.Text, xmlfile.mandatory]
|
|
||||||
|
t_Name = [xmlfile.Text, xmlfile.mandatory] # fully qualified name
|
||||||
#t_Icon = [xmlfile.Binary, xmlfile.mandatory]
|
#t_Icon = [xmlfile.Binary, xmlfile.mandatory]
|
||||||
t_Dependencies = [ [xmlfile.Text], xmlfile.optional, "Component"]
|
t_Dependencies = [ [xmlfile.Text], xmlfile.optional, "Component"]
|
||||||
t_Parts = [ [ComponentTree], xmlfile.optional, "Component"]
|
t_Parts = [ [ComponentTree], xmlfile.optional, "Component"]
|
||||||
|
|||||||
+62
-73
@@ -47,7 +47,6 @@ import pisi.context as ctx
|
|||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
mandatory, optional = range(2) # poor man's enum
|
mandatory, optional = range(2) # poor man's enum
|
||||||
|
|
||||||
# basic types
|
# basic types
|
||||||
@@ -69,20 +68,20 @@ class LocalText(object):
|
|||||||
self.req = spec[1]
|
self.req = spec[1]
|
||||||
self.locs = {}
|
self.locs = {}
|
||||||
|
|
||||||
def decode(self, node):
|
def decode(self, node, errs):
|
||||||
# flags, tag name, instance attribute
|
# flags, tag name, instance attribute
|
||||||
nodes = getAllNodes(node, self.tag)
|
nodes = getAllNodes(node, self.tag)
|
||||||
if not nodes:
|
if not nodes:
|
||||||
if self.req == mandatory:
|
if self.req == mandatory:
|
||||||
pass
|
errs.append("LocalText '%s' should have at least one '%s' tag\n" %
|
||||||
#errs.append("Tag '%s' should have at least one '%s' tag\n" % (parent.tagName, d[2]))
|
self.tag)
|
||||||
else:
|
else:
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
lang = getNodeAttribute(node, "xml:lang")
|
lang = getNodeAttribute(node, "xml:lang")
|
||||||
c = getNodeText(node)
|
c = getNodeText(node)
|
||||||
if not c:
|
if not c:
|
||||||
#errs.append("Tag '%s' should have some text data\n" % node.tagName)
|
errs.append("'%s' language of tag '%s' should have some text data\n" %
|
||||||
break
|
(lang, self.tag))
|
||||||
# FIXME: check for dups and 'en'
|
# FIXME: check for dups and 'en'
|
||||||
if not lang:
|
if not lang:
|
||||||
lang = 'en'
|
lang = 'en'
|
||||||
@@ -96,7 +95,7 @@ class LocalText(object):
|
|||||||
# return ""
|
# return ""
|
||||||
#retur
|
#retur
|
||||||
|
|
||||||
def encode(self, xml, node):
|
def encode(self, xml, node, errs):
|
||||||
for key in self.locs.iterkeys():
|
for key in self.locs.iterkeys():
|
||||||
newnode = newNode(node, self.tag)
|
newnode = newNode(node, self.tag)
|
||||||
newnode.setAttribute('xml:lang', key)
|
newnode.setAttribute('xml:lang', key)
|
||||||
@@ -104,7 +103,7 @@ class LocalText(object):
|
|||||||
newnode.appendChild(newtext)
|
newnode.appendChild(newtext)
|
||||||
node.appendChild(newnode)
|
node.appendChild(newnode)
|
||||||
|
|
||||||
def format(self):
|
def format(self, errs):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
class autoxml(type):
|
class autoxml(type):
|
||||||
@@ -223,22 +222,22 @@ class autoxml(type):
|
|||||||
cls.__init__ = initialize
|
cls.__init__ = initialize
|
||||||
|
|
||||||
cls.decoders = decoders
|
cls.decoders = decoders
|
||||||
def decode(self, node):
|
def decode(self, node, errs):
|
||||||
for decode_member in self.__class__.decoders:
|
for decode_member in self.__class__.decoders:
|
||||||
decode_member(self, node)
|
decode_member(self, node, errs)
|
||||||
cls.decode = decode
|
cls.decode = decode
|
||||||
|
|
||||||
cls.encoders = encoders
|
cls.encoders = encoders
|
||||||
def encode(self, xml, node):
|
def encode(self, xml, node, errs):
|
||||||
for encode_member in self.__class__.encoders:
|
for encode_member in self.__class__.encoders:
|
||||||
encode_member(self, xml, node)
|
encode_member(self, xml, node, errs)
|
||||||
cls.encode = encode
|
cls.encode = encode
|
||||||
|
|
||||||
cls.formatters = formatters
|
cls.formatters = formatters
|
||||||
def format(self):
|
def format(self, errs):
|
||||||
string = ''
|
string = ''
|
||||||
for formatter in self.__class__.formatters:
|
for formatter in self.__class__.formatters:
|
||||||
string += formatter(self)
|
string += formatter(self, errs)
|
||||||
return string
|
return string
|
||||||
cls.format = format
|
cls.format = format
|
||||||
if not dict.has_key('__str__'):
|
if not dict.has_key('__str__'):
|
||||||
@@ -299,29 +298,22 @@ class autoxml(type):
|
|||||||
"""initialize component"""
|
"""initialize component"""
|
||||||
setattr(self, name, init_a())
|
setattr(self, name, init_a())
|
||||||
|
|
||||||
def decode(self, node):
|
def decode(self, node, errs):
|
||||||
"""decode component from DOM node"""
|
"""decode component from DOM node"""
|
||||||
setattr(self, name, decode_a(node))
|
setattr(self, name, decode_a(node, errs))
|
||||||
|
|
||||||
def encode(self, xml, node):
|
def encode(self, xml, node, errs):
|
||||||
"""encode self inside, possibly new, DOM node using xml"""
|
"""encode self inside, possibly new, DOM node using xml"""
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
value = getattr(self, name)
|
value = getattr(self, name)
|
||||||
else:
|
else:
|
||||||
value = None
|
value = None
|
||||||
encode_a(xml, node, value)
|
encode_a(xml, node, value, errs)
|
||||||
#newnode =
|
|
||||||
#if newnode:
|
|
||||||
# mergetext(node, newnode)
|
|
||||||
#else:
|
|
||||||
# if req == mandatory:
|
|
||||||
# raise Error('Mandatory variable %s not available' % name)
|
|
||||||
|
|
||||||
|
|
||||||
def format(self):
|
def format(self, errs):
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
value = getattr(self,name)
|
value = getattr(self,name)
|
||||||
return '%s: %s\n' % (token, format_a(value))
|
return '%s: %s\n' % (token, format_a(value, errs))
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory variable %s not available' % name)
|
raise Error('Mandatory variable %s not available' % name)
|
||||||
@@ -370,7 +362,7 @@ class autoxml(type):
|
|||||||
"""default value for all basic types is None"""
|
"""default value for all basic types is None"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def decode(node):
|
def decode(node, errs):
|
||||||
"""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
|
||||||
@@ -378,24 +370,23 @@ class autoxml(type):
|
|||||||
try:
|
try:
|
||||||
value = autoxml.basic_cons_map[token_type](text)
|
value = autoxml.basic_cons_map[token_type](text)
|
||||||
except Error:
|
except Error:
|
||||||
raise Error('Type mismatch: read text cannot be decoded')
|
value = None
|
||||||
|
errs.append('Type mismatch: read text cannot be decoded')
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory token %s not available' % token)
|
errs.append('Mandatory token %s not available' % token)
|
||||||
else:
|
return None
|
||||||
return None
|
|
||||||
|
|
||||||
def encode(xml, node, value):
|
def encode(xml, node, value, errs):
|
||||||
"""encode given value inside DOM node"""
|
"""encode given value inside DOM node"""
|
||||||
if value:
|
if value:
|
||||||
writetext(xml, node, token, str(value))
|
writetext(xml, node, token, str(value))
|
||||||
return node
|
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
|
|
||||||
def format(value):
|
def format(value, errs):
|
||||||
"""format value for pretty printing"""
|
"""format value for pretty printing"""
|
||||||
return str(value)
|
return str(value)
|
||||||
|
|
||||||
@@ -413,44 +404,43 @@ class autoxml(type):
|
|||||||
def init():
|
def init():
|
||||||
return make_object()
|
return make_object()
|
||||||
|
|
||||||
def decode(node):
|
def decode(node, errs):
|
||||||
node = getNode(node, tag)
|
node = getNode(node, tag)
|
||||||
if node:
|
if node:
|
||||||
try:
|
try:
|
||||||
obj = make_object()
|
obj = make_object()
|
||||||
obj.decode(node)
|
obj.decode(node, errs)
|
||||||
return obj
|
return obj
|
||||||
except Error:
|
except Error:
|
||||||
raise Error('Type mismatch: DOM cannot be decoded')
|
errs.append('Type mismatch: DOM cannot be decoded')
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
else:
|
return None
|
||||||
return None
|
|
||||||
|
def encode(xml, node, obj, errs):
|
||||||
def encode(xml, node, obj):
|
|
||||||
if node and obj:
|
if node and obj:
|
||||||
try:
|
try:
|
||||||
#FIXME: this doesn't look pretty
|
#FIXME: this doesn't look pretty
|
||||||
classnode = node.ownerDocument.createElement(tag)
|
classnode = node.ownerDocument.createElement(tag)
|
||||||
obj.encode(xml, classnode)
|
obj.encode(xml, classnode, errs)
|
||||||
node.appendChild(classnode)
|
node.appendChild(classnode)
|
||||||
except Error:
|
except Error:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
# note: we can receive an error if obj has no content
|
# note: we can receive an error if obj has no content
|
||||||
raise Error('Object cannot be encoded')
|
errs.append('Object cannot be encoded')
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
|
|
||||||
def format(obj):
|
def format(obj, errs):
|
||||||
try:
|
try:
|
||||||
return obj.format()
|
return obj.format(errs)
|
||||||
except Error:
|
except Error:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
else:
|
else:
|
||||||
return ""
|
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):
|
||||||
@@ -467,33 +457,33 @@ class autoxml(type):
|
|||||||
def init():
|
def init():
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def decode(node):
|
def decode(node, errs):
|
||||||
l = []
|
l = []
|
||||||
nodes = getAllNodes(node, tag + '/' + comp_tag)
|
nodes = getAllNodes(node, tag + '/' + comp_tag)
|
||||||
#print node, tag + '/' + comp_tag, nodes
|
#print node, tag + '/' + comp_tag, nodes
|
||||||
if len(nodes) is 0 and req is mandatory:
|
if len(nodes) is 0 and req is mandatory:
|
||||||
raise Error('Mandatory list empty')
|
errs.append('Mandatory list empty')
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
dummy = node.ownerDocument.createElement("Dummy")
|
dummy = node.ownerDocument.createElement("Dummy")
|
||||||
dummy.appendChild(node)
|
dummy.appendChild(node)
|
||||||
l.append(decode_item(dummy))
|
l.append(decode_item(dummy, errs))
|
||||||
return l
|
return l
|
||||||
|
|
||||||
def encode(xml, node, l):
|
def encode(xml, node, l, errs):
|
||||||
if l and 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, errs)
|
||||||
node.appendChild(listnode)
|
node.appendChild(listnode)
|
||||||
else:
|
else:
|
||||||
if req is mandatory:
|
if req is mandatory:
|
||||||
raise Error('Mandatory list empty')
|
errs.append('Mandatory list empty')
|
||||||
|
|
||||||
def format(l):
|
def format(l, errs):
|
||||||
#print 'format:', name
|
#print 'format:', name
|
||||||
s = ''
|
s = ''
|
||||||
for ix in range(len(l)):
|
for ix in range(len(l)):
|
||||||
s += str(ix+1) + ': ' + format_item(l[ix])
|
s += str(ix+1) + ': ' + format_item(l[ix], errs)
|
||||||
if ix != len(l)-1:
|
if ix != len(l)-1:
|
||||||
s += ', '
|
s += ', '
|
||||||
return s
|
return s
|
||||||
@@ -516,41 +506,40 @@ class autoxml(type):
|
|||||||
def init():
|
def init():
|
||||||
return make_object()
|
return make_object()
|
||||||
|
|
||||||
def decode(node):
|
def decode(node, errs):
|
||||||
if node:
|
if node:
|
||||||
try:
|
try:
|
||||||
obj = make_object()
|
obj = make_object()
|
||||||
obj.decode(node)
|
obj.decode(node, errs)
|
||||||
return obj
|
return obj
|
||||||
except Error:
|
except Error:
|
||||||
raise Error('Type mismatch: DOM cannot be decoded')
|
errs.append('Type mismatch: DOM cannot be decoded')
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
else:
|
return None
|
||||||
return None
|
|
||||||
|
|
||||||
def encode(xml, node, obj):
|
def encode(xml, node, obj, errs):
|
||||||
if node and obj:
|
if node and obj:
|
||||||
try:
|
try:
|
||||||
#FIXME: this doesn't look pretty
|
#FIXME: this doesn't look pretty
|
||||||
obj.encode(xml, node)
|
obj.encode(xml, node, errs)
|
||||||
except Error:
|
except Error:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
# note: we can receive an error if obj has no content
|
# note: we can receive an error if obj has no content
|
||||||
raise Error('Object cannot be encoded')
|
errs.append('Object cannot be encoded')
|
||||||
else:
|
else:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
|
|
||||||
def format(obj):
|
def format(obj, errs):
|
||||||
try:
|
try:
|
||||||
return obj.format()
|
return obj.format(errs)
|
||||||
except Error:
|
except Error:
|
||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
raise Error('Mandatory argument not available')
|
errs.append('Mandatory argument not available')
|
||||||
else:
|
else:
|
||||||
return ""
|
return ''
|
||||||
return (init, decode, encode, format)
|
return (init, decode, encode, format)
|
||||||
|
|
||||||
basic_cons_map = {
|
basic_cons_map = {
|
||||||
|
|||||||
+11
-5
@@ -49,16 +49,20 @@ class XmlFileTestCase(unittest.TestCase):
|
|||||||
dom = mdom.parse('tests/a.xml')
|
dom = mdom.parse('tests/a.xml')
|
||||||
node = getNode(dom, 'A')
|
node = getNode(dom, 'A')
|
||||||
self.assert_(len(A.decoders)>0)
|
self.assert_(len(A.decoders)>0)
|
||||||
a.decode(node)
|
errs = []
|
||||||
|
print 'errs', errs
|
||||||
|
a.decode(node, errs)
|
||||||
self.assert_(a.href.startswith('http'))
|
self.assert_(a.href.startswith('http'))
|
||||||
self.assertEqual(a.number, 868)
|
self.assertEqual(a.number, 868)
|
||||||
self.assertEqual(a.name, 'Eray Ozkural')
|
self.assertEqual(a.name, 'Eray Ozkural')
|
||||||
string = a.format()
|
string = a.format(errs)
|
||||||
print '*', string
|
print '*', string
|
||||||
#self.assert_(string.startswith('Name'))
|
#self.assert_(string.startswith('Name'))
|
||||||
xml = xmlfile.XmlFile('A')
|
xml = xmlfile.XmlFile('A')
|
||||||
xml.newDOM()
|
xml.newDOM()
|
||||||
a.encode(xml, xml.rootNode())
|
errs2 = []
|
||||||
|
a.encode(xml, xml.rootNode(), errs2)
|
||||||
|
print 'errs2', errs2
|
||||||
xml.writexml('/tmp/a.xml')
|
xml.writexml('/tmp/a.xml')
|
||||||
print '/tmp/a.xml written'
|
print '/tmp/a.xml written'
|
||||||
xml = xmlfile.XmlFile('A')
|
xml = xmlfile.XmlFile('A')
|
||||||
@@ -67,8 +71,10 @@ class XmlFileTestCase(unittest.TestCase):
|
|||||||
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, xml.rootNode())
|
errs3 = []
|
||||||
|
a2.encode(xml, xml.rootNode(), errs3)
|
||||||
|
print 'errs3', errs3
|
||||||
xml.writexml('/tmp/a2.xml')
|
xml.writexml('/tmp/a2.xml')
|
||||||
string = a2.format()
|
string = a2.format(errs3)
|
||||||
|
|
||||||
suite = unittest.makeSuite(XmlFileTestCase)
|
suite = unittest.makeSuite(XmlFileTestCase)
|
||||||
|
|||||||
Reference in New Issue
Block a user