Usually just a word or punctuation; occasionally I rewrote a sentence if I had a hard time determining what was meant by the original. (N.B. if I misunderstood something, then my re-wording will be wrong!) Also added eol to many files that were missing it, which throws off 'cat somefile' at a shell prompt (but did not yet touch anything under src/, which also has many files without eol). I did not re-line-wrap the text I changed, so that the diffs are minimized and meaningful changes are easier to spot.
		
			
				
	
	
		
			2190 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			2190 lines
		
	
	
		
			67 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
 | 
						|
import re
 | 
						|
import time
 | 
						|
import getopt
 | 
						|
import imp
 | 
						|
import sys
 | 
						|
import types
 | 
						|
import errno
 | 
						|
 | 
						|
__version__ = 0.5
 | 
						|
 | 
						|
from xml.etree import cElementTree as ElementTree
 | 
						|
 | 
						|
INDENT = 4*" "
 | 
						|
DEBUG = False
 | 
						|
 | 
						|
XMLSCHEMA = "http://www.w3.org/2001/XMLSchema"
 | 
						|
XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'
 | 
						|
 | 
						|
CLASS_PROP = [("c_children", ".copy()"), 
 | 
						|
                ("c_attributes", ".copy()"),
 | 
						|
                ("c_child_order", "[:]"),
 | 
						|
                ("c_cardinality", ".copy()")]
 | 
						|
                
 | 
						|
BASE_ELEMENT = ["text", "extension_elements", "extension_attributes"]
 | 
						|
    
 | 
						|
class MissingPrerequisite(Exception):
 | 
						|
    pass
 | 
						|
 | 
						|
def sd_copy(arg):
 | 
						|
    try:
 | 
						|
        return arg.copy()
 | 
						|
    except AttributeError:
 | 
						|
        return {}
 | 
						|
        
 | 
						|
# ------------------------------------------------------------------------
 | 
						|
 | 
						|
def class_pyify(ref):
 | 
						|
    return ref.replace("-","_")
 | 
						|
 | 
						|
PROTECTED_KEYWORDS = ["import", "def", "if", "else", "return", "for",
 | 
						|
                      "while", "not", "try", "except", "in"]
 | 
						|
 | 
						|
 | 
						|
def def_init(imports, attributes):
 | 
						|
    indent = INDENT+INDENT
 | 
						|
    indent3 = INDENT+INDENT+INDENT
 | 
						|
    line = ["%sdef __init__(self," % INDENT]
 | 
						|
 | 
						|
    for elem in attributes:
 | 
						|
        if elem[0] in PROTECTED_KEYWORDS:
 | 
						|
            _name = elem[0] +"_"
 | 
						|
        else:
 | 
						|
            _name = elem[0]
 | 
						|
 | 
						|
        if elem[2]:
 | 
						|
            line.append("%s%s='%s'," % (indent3, _name, elem[2]))
 | 
						|
        else:
 | 
						|
            line.append("%s%s=%s," % (indent3, _name, elem[2]))
 | 
						|
 | 
						|
    for _, elems in imports.items():
 | 
						|
        for elem in elems:
 | 
						|
            if elem in PROTECTED_KEYWORDS:
 | 
						|
                _name = elem +"_"
 | 
						|
            else:
 | 
						|
                _name = elem
 | 
						|
            line.append("%s%s=None," % (indent3, _name))
 | 
						|
 | 
						|
    line.append("%stext=None," % indent3)
 | 
						|
    line.append("%sextension_elements=None," % indent3)
 | 
						|
    line.append("%sextension_attributes=None," % indent3)
 | 
						|
    line.append("%s):" % indent)
 | 
						|
    return line
 | 
						|
    
 | 
						|
 | 
						|
def base_init(imports):
 | 
						|
    line = []
 | 
						|
    indent4 = INDENT+INDENT+INDENT+INDENT
 | 
						|
    if not imports:
 | 
						|
        line.append("%sSamlBase.__init__(self, " % (INDENT+INDENT))
 | 
						|
        for attr in BASE_ELEMENT:
 | 
						|
            if attr in PROTECTED_KEYWORDS:
 | 
						|
                _name = attr + "_"
 | 
						|
            else:
 | 
						|
                _name = attr
 | 
						|
            line.append("%s%s=%s," % (indent4, _name, _name))
 | 
						|
        line.append("%s)" % indent4)
 | 
						|
    else:
 | 
						|
        # TODO have to keep apart which properties come from which superior
 | 
						|
        for sup, elems in imports.items():
 | 
						|
            line.append("%s%s.__init__(self, " % (INDENT+INDENT, sup))
 | 
						|
            lattr = elems[:]
 | 
						|
            lattr.extend(BASE_ELEMENT)
 | 
						|
            for attr in lattr:
 | 
						|
                if attr in PROTECTED_KEYWORDS:
 | 
						|
                    _name = attr + "_"
 | 
						|
                else:
 | 
						|
                    _name = attr
 | 
						|
                line.append("%s%s=%s," % (indent4, _name, _name))
 | 
						|
            line.append("%s)" % indent4)
 | 
						|
    return line
 | 
						|
    
 | 
						|
 | 
						|
def initialize(attributes):
 | 
						|
    indent = INDENT+INDENT
 | 
						|
    line = []
 | 
						|
    for prop, val, _default in attributes:
 | 
						|
        if prop in PROTECTED_KEYWORDS:
 | 
						|
            _name = prop +"_"
 | 
						|
        else:
 | 
						|
            _name = prop
 | 
						|
 | 
						|
        if val in PROTECTED_KEYWORDS:
 | 
						|
            _vname = val +"_"
 | 
						|
        else:
 | 
						|
            _vname = val
 | 
						|
            
 | 
						|
        line.append("%sself.%s=%s" % (indent, _name, _vname))
 | 
						|
    return line
 | 
						|
 | 
						|
 | 
						|
def _mod_typ(prop):
 | 
						|
    try:
 | 
						|
        (mod, typ) = prop.type
 | 
						|
    except ValueError:
 | 
						|
        typ = prop.type
 | 
						|
        mod = None
 | 
						|
    except TypeError: # No type property
 | 
						|
        try:
 | 
						|
            (mod, typ) = prop.ref
 | 
						|
        except ValueError:
 | 
						|
            if prop.class_name:
 | 
						|
                typ = prop.class_name
 | 
						|
            else:
 | 
						|
                typ = prop.ref
 | 
						|
            mod = None
 | 
						|
    
 | 
						|
    return mod, typ
 | 
						|
 | 
						|
 | 
						|
def _mod_cname(prop, cdict):
 | 
						|
    if hasattr(prop, "scoped"):
 | 
						|
        cname = prop.class_name
 | 
						|
        mod = None
 | 
						|
    else:
 | 
						|
        (mod, typ) = _mod_typ(prop)
 | 
						|
        if not mod:
 | 
						|
            try:
 | 
						|
                cname = cdict[typ].class_name
 | 
						|
            except KeyError:
 | 
						|
                cname = cdict[class_pyify(typ)].class_name
 | 
						|
        else:
 | 
						|
            cname = typ
 | 
						|
        
 | 
						|
    return mod, cname
 | 
						|
 | 
						|
 | 
						|
def leading_uppercase(string):
 | 
						|
    try:
 | 
						|
        return string[0].upper()+string[1:]
 | 
						|
    except IndexError:
 | 
						|
        return string
 | 
						|
    except TypeError:
 | 
						|
        return ""
 | 
						|
 | 
						|
 | 
						|
def leading_lowercase(string):
 | 
						|
    try:
 | 
						|
        return string[0].lower()+string[1:]
 | 
						|
    except IndexError:
 | 
						|
        return string
 | 
						|
    except TypeError:
 | 
						|
        return ""
 | 
						|
 | 
						|
 | 
						|
def rm_duplicates(properties):
 | 
						|
    keys = []
 | 
						|
    clist = []
 | 
						|
    for prop in properties:
 | 
						|
        if prop.name in keys:
 | 
						|
            continue
 | 
						|
        else:
 | 
						|
            clist.append(prop)
 | 
						|
            keys.append(prop.name)
 | 
						|
    return clist
 | 
						|
 | 
						|
# def rm_duplicates(lista):
 | 
						|
#     res = []
 | 
						|
#     for item in lista:
 | 
						|
#         if item not in res:
 | 
						|
#             res.append(item)
 | 
						|
#     return res
 | 
						|
 | 
						|
 | 
						|
def klass_namn(obj):
 | 
						|
    if obj.class_name:
 | 
						|
        return obj.class_name
 | 
						|
    else:
 | 
						|
        return obj.name
 | 
						|
    
 | 
						|
 | 
						|
class PyObj(object):
 | 
						|
    def __init__(self, name=None, pyname=None, root=None):
 | 
						|
        self.name = name
 | 
						|
        self.done = False
 | 
						|
        self.local = True
 | 
						|
        self.root = root
 | 
						|
        self.superior = []
 | 
						|
        self.value_type = ""
 | 
						|
        self.properties = ([], [])
 | 
						|
        self.abstract = False
 | 
						|
        self.class_name = ""
 | 
						|
        
 | 
						|
        if pyname:
 | 
						|
            self.pyname = pyname
 | 
						|
        elif name:
 | 
						|
            self.pyname = pyify(name)
 | 
						|
        else:
 | 
						|
            self.pyname = name
 | 
						|
 | 
						|
        self.type = None
 | 
						|
            
 | 
						|
    def child_spec(self, target_namespace, prop, mod, typ, lista):
 | 
						|
        if mod:
 | 
						|
            namesp = external_namespace(self.root.modul[mod])
 | 
						|
            pkey = '{%s}%s' % (namesp, prop.name)
 | 
						|
            typ = "%s.%s" % (mod, typ)
 | 
						|
        else:
 | 
						|
            pkey = '{%s}%s' % (target_namespace, prop.name)
 | 
						|
 | 
						|
        if lista:
 | 
						|
            return "c_children['%s'] = ('%s', [%s])" % (
 | 
						|
                        pkey, prop.pyname, typ)
 | 
						|
        else:
 | 
						|
            return "c_children['%s'] = ('%s', %s)" % (
 | 
						|
                        pkey, prop.pyname, typ)
 | 
						|
    
 | 
						|
    def knamn(self, sup, cdict):
 | 
						|
        cname = cdict[sup].class_name
 | 
						|
        if not cname:
 | 
						|
            (namesp, tag) = cdict[sup].name.split('.')
 | 
						|
            if namesp:
 | 
						|
                ctag = self.root.modul[namesp].factory(tag).__class__.__name__
 | 
						|
                cname = '%s.%s' % (namesp, ctag)
 | 
						|
            else:
 | 
						|
                cname = tag + "_"
 | 
						|
        return cname
 | 
						|
    
 | 
						|
    def _do_properties(self, line, cdict, ignore, target_namespace):
 | 
						|
        args = []
 | 
						|
        child = []
 | 
						|
 | 
						|
        try:
 | 
						|
            (own, inh) = self.properties
 | 
						|
        except AttributeError:
 | 
						|
            (own, inh) = ([], [])
 | 
						|
            
 | 
						|
        for prop in own:
 | 
						|
            if isinstance(prop, PyAttribute):
 | 
						|
                line.append("%sc_attributes['%s'] = %s" % (INDENT, 
 | 
						|
                                                    prop.name, prop.spec()))
 | 
						|
                if prop.fixed:
 | 
						|
                    args.append((prop.pyname, prop.fixed, None))
 | 
						|
                else:
 | 
						|
                    if prop.default:
 | 
						|
                        args.append((prop.pyname, prop.pyname, prop.default))
 | 
						|
                    else:
 | 
						|
                        args.append((prop.pyname, prop.pyname, None))
 | 
						|
                        
 | 
						|
            elif isinstance(prop, PyElement):
 | 
						|
 | 
						|
                (mod, cname) = _mod_cname(prop, cdict)
 | 
						|
                
 | 
						|
                if prop.max == "unbounded":
 | 
						|
                    lista = True
 | 
						|
                    pmax = 0 # just has to be different from 1
 | 
						|
                else:
 | 
						|
                    pmax = int(prop.max)
 | 
						|
                    lista = False
 | 
						|
                    
 | 
						|
                if prop.name in ignore:
 | 
						|
                    pass
 | 
						|
                else:
 | 
						|
                    line.append("%s%s" % (INDENT, self.child_spec(
 | 
						|
                                                        target_namespace, prop,
 | 
						|
                                                        mod, cname,
 | 
						|
                                                        lista)))
 | 
						|
 | 
						|
                pmin = int(getattr(prop, 'min', 1))
 | 
						|
 | 
						|
                if pmax == 1 and pmin == 1:
 | 
						|
                    pass
 | 
						|
                elif prop.max == "unbounded":
 | 
						|
                    line.append( "%sc_cardinality['%s'] = {\"min\":%s}" % (
 | 
						|
                                    INDENT, prop.pyname, pmin))
 | 
						|
                else:
 | 
						|
                    line.append(
 | 
						|
                        "%sc_cardinality['%s'] = {\"min\":%s, \"max\":%d}" % (
 | 
						|
                                    INDENT, prop.pyname, pmin, pmax))
 | 
						|
 | 
						|
                child.append(prop.pyname)
 | 
						|
                if lista:
 | 
						|
                    args.append((prop.pyname, "%s or []" % (prop.pyname,), 
 | 
						|
                                    None))
 | 
						|
                else:
 | 
						|
                    args.append((prop.pyname, prop.pyname, None))
 | 
						|
        
 | 
						|
        return args, child, inh
 | 
						|
        
 | 
						|
    def _superiors(self, cdict):
 | 
						|
        imps = {}
 | 
						|
 | 
						|
        try:
 | 
						|
            superior = self.superior
 | 
						|
            sups = []
 | 
						|
            for sup in superior:
 | 
						|
                klass = self.knamn(sup, cdict)
 | 
						|
                sups.append(klass)
 | 
						|
                
 | 
						|
                imps[klass] = []
 | 
						|
                for cla in cdict[sup].properties[0]:
 | 
						|
                    if cla.pyname and cla.pyname not in imps[klass]: 
 | 
						|
                        imps[klass].append(cla.pyname)
 | 
						|
        except AttributeError:
 | 
						|
            superior = []
 | 
						|
            sups = []
 | 
						|
        
 | 
						|
        return superior, sups, imps
 | 
						|
        
 | 
						|
    def class_definition(self, target_namespace, cdict=None, ignore=None):
 | 
						|
        line = []
 | 
						|
 | 
						|
        if self.root:
 | 
						|
            if self.name not in [c.name for c in self.root.elems]:
 | 
						|
                self.root.elems.append(self)
 | 
						|
 | 
						|
        (superior, sups, imps) = self._superiors(cdict)
 | 
						|
 | 
						|
        c_name = klass_namn(self)
 | 
						|
            
 | 
						|
        if not superior:
 | 
						|
            line.append("class %s(SamlBase):" % (c_name,))
 | 
						|
        else:
 | 
						|
            line.append("class %s(%s):" % (c_name, ",".join(sups)))
 | 
						|
 | 
						|
        if hasattr(self, 'scoped'):
 | 
						|
            pass
 | 
						|
        else:
 | 
						|
            line.append("%s\"\"\"The %s:%s element \"\"\"" % (INDENT, 
 | 
						|
                                                        target_namespace,
 | 
						|
                                                        self.name))
 | 
						|
        line.append("")
 | 
						|
        line.append("%sc_tag = '%s'" % (INDENT, self.name))
 | 
						|
        line.append("%sc_namespace = NAMESPACE" % (INDENT,))
 | 
						|
        try:
 | 
						|
            if self.value_type:
 | 
						|
                if isinstance(self.value_type, basestring):
 | 
						|
                    line.append("%sc_value_type = '%s'" % (INDENT, 
 | 
						|
                                                            self.value_type))
 | 
						|
                else:
 | 
						|
                    line.append("%sc_value_type = %s" % (INDENT, 
 | 
						|
                                                        self.value_type))
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
 | 
						|
        if not superior:
 | 
						|
            for var, cps in CLASS_PROP:
 | 
						|
                line.append("%s%s = SamlBase.%s%s" % (INDENT, var, var, cps))
 | 
						|
        else:
 | 
						|
            for sup in sups:
 | 
						|
                for var, cps in CLASS_PROP:
 | 
						|
                    line.append("%s%s = %s.%s%s" % (INDENT, var, sup, var, 
 | 
						|
                                                    cps))
 | 
						|
 | 
						|
        (args, child, inh) = self._do_properties(line, cdict, ignore, 
 | 
						|
                                                target_namespace)
 | 
						|
        
 | 
						|
        if child:
 | 
						|
            line.append("%sc_child_order.extend([%s])" % (INDENT,
 | 
						|
                            "'"+"', '".join(child)+"'"))
 | 
						|
            
 | 
						|
        if args:
 | 
						|
            if inh:
 | 
						|
                cname = self.knamn(self.superior[0], cdict)
 | 
						|
                imps = {cname: [c.pyname for c in inh if c.pyname]}
 | 
						|
            line.append("")
 | 
						|
            line.extend(def_init(imps, args))
 | 
						|
            line.extend(base_init(imps))
 | 
						|
            line.extend(initialize(args))
 | 
						|
        
 | 
						|
        line.append("")
 | 
						|
        if not self.abstract or not self.class_name.endswith("_"):
 | 
						|
            line.append("def %s_from_string(xml_string):" % pyify(
 | 
						|
                                                            self.class_name))
 | 
						|
            line.append(
 | 
						|
                "%sreturn saml2.create_class_from_xml_string(%s, xml_string)" % (
 | 
						|
                            INDENT, self.class_name))
 | 
						|
            line.append("")
 | 
						|
        
 | 
						|
        self.done = True
 | 
						|
        return "\n".join(line)
 | 
						|
    
 | 
						|
def prepend(add, orig):
 | 
						|
    # return a list which is the lists concatenated with the second list first
 | 
						|
    res = [add]
 | 
						|
    if orig:
 | 
						|
        res.extend(orig)
 | 
						|
    return res
 | 
						|
    
 | 
						|
def pyobj_factory(name, value_type, elms=None):
 | 
						|
    pyobj = PyObj(name, pyify(name))
 | 
						|
    pyobj.value_type = value_type
 | 
						|
    if elms:
 | 
						|
        if name not in [c.name for c in elms]:
 | 
						|
            elms.append(pyobj)
 | 
						|
    return pyobj
 | 
						|
 | 
						|
def pyelement_factory(name, value_type, elms=None):
 | 
						|
    obj = PyElement(name, pyify(name))
 | 
						|
    obj.value_type = value_type
 | 
						|
    if elms:
 | 
						|
        if name not in [c.name for c in elms]:
 | 
						|
            elms.append(obj)
 | 
						|
    return obj
 | 
						|
    
 | 
						|
def expand_groups(properties, cdict):
 | 
						|
    res = []
 | 
						|
    for prop in properties:
 | 
						|
        if isinstance(prop, PyGroup):
 | 
						|
            # only own, what about inherited ? Not on groups ?
 | 
						|
            cname = prop.ref[1]
 | 
						|
            res.extend(cdict[cname].properties[0])
 | 
						|
        else:
 | 
						|
            res.append(prop)
 | 
						|
            
 | 
						|
    return res
 | 
						|
    
 | 
						|
class PyElement(PyObj):
 | 
						|
    def __init__(self, name=None, pyname=None, root=None, parent=""):
 | 
						|
        PyObj.__init__(self, name, pyname, root)
 | 
						|
        if parent:
 | 
						|
            self.class_name = "%s_%s" % (leading_uppercase(parent), self.name)
 | 
						|
        else:
 | 
						|
            self.class_name = leading_uppercase(self.name)
 | 
						|
        self.ref = None
 | 
						|
        self.min = 1
 | 
						|
        self.max = 1
 | 
						|
        self.definition = None
 | 
						|
        self.orig = None
 | 
						|
    
 | 
						|
    # def prereq(self, prop):
 | 
						|
    #     prtext = prop.text(target_namespace, cdict)
 | 
						|
    #     if prtext == None:
 | 
						|
    #         return []
 | 
						|
    #     else:
 | 
						|
    #         prop.done = True
 | 
						|
    #         return prtext
 | 
						|
        
 | 
						|
    def undefined(self, cdict):
 | 
						|
        try:
 | 
						|
            (mod, typ) = self.type
 | 
						|
            if not mod:
 | 
						|
                cname = leading_uppercase(typ)
 | 
						|
                if not cdict[cname].done:
 | 
						|
                    return [cdict[cname]], []
 | 
						|
        except ValueError:
 | 
						|
            pass
 | 
						|
        except TypeError: # could be a ref then or a PyObj instance
 | 
						|
            if isinstance(self.type, PyType):
 | 
						|
                return self.type.undefined(cdict)
 | 
						|
            elif isinstance(self.ref, tuple):
 | 
						|
                pass
 | 
						|
            else:
 | 
						|
                cname = leading_uppercase(self.ref)
 | 
						|
                if not cdict[cname].done:
 | 
						|
                    return [cdict[cname]], []
 | 
						|
        return [], []
 | 
						|
    
 | 
						|
    def _local_class(self, typ, cdict, child, target_namespace, ignore):
 | 
						|
        if typ in cdict and not cdict[typ].done:
 | 
						|
            raise MissingPrerequisite(typ)
 | 
						|
        else:
 | 
						|
            self.orig = {"type": self.type}
 | 
						|
            try:
 | 
						|
                self.orig["superior"] = self.superior
 | 
						|
            except AttributeError:
 | 
						|
                self.orig["superior"] = []
 | 
						|
            self.superior = [typ]
 | 
						|
            req = self.class_definition(target_namespace, cdict, 
 | 
						|
                                        ignore)
 | 
						|
            if not child:
 | 
						|
                req = [req]
 | 
						|
            
 | 
						|
            if not hasattr(self, 'scoped'):
 | 
						|
                cdict[self.name] = self
 | 
						|
                cdict[self.name].done = True
 | 
						|
                if child:
 | 
						|
                    cdict[self.name].local = True
 | 
						|
            self.type = (None, self.name)
 | 
						|
        
 | 
						|
        return req
 | 
						|
        
 | 
						|
    def _external_class(self, mod, typ, cdict, child, target_namespace, 
 | 
						|
                        ignore):
 | 
						|
        # Will raise exception if class can't be found
 | 
						|
        cname = self.root.modul[mod].factory(typ).__class__.__name__
 | 
						|
        imp_name = "%s.%s" % (mod, cname)
 | 
						|
            
 | 
						|
        if imp_name not in cdict:
 | 
						|
            # create import object so I can get the properties from it 
 | 
						|
            # later
 | 
						|
            impo = pyelement_factory(imp_name, None, None)
 | 
						|
            impo.properties = [_import_attrs(self.root.modul[mod], typ, 
 | 
						|
                                            self.root),[]]
 | 
						|
            impo.class_name = imp_name
 | 
						|
            cdict[imp_name] = impo
 | 
						|
            impo.done = True
 | 
						|
            if child:
 | 
						|
                impo.local = True
 | 
						|
        # and now for this object
 | 
						|
        self.superior = [imp_name]
 | 
						|
        text = self.class_definition(target_namespace, cdict, 
 | 
						|
                                        ignore=ignore)
 | 
						|
        
 | 
						|
        return text
 | 
						|
        
 | 
						|
    def text(self, target_namespace, cdict, child=True, ignore=None):
 | 
						|
        if ignore is None:
 | 
						|
            ignore = []
 | 
						|
 | 
						|
        if child:
 | 
						|
            text = []
 | 
						|
        else:
 | 
						|
            text = None
 | 
						|
        req = []
 | 
						|
        try:
 | 
						|
            (mod, typ) = self.type
 | 
						|
            if not mod:
 | 
						|
                req = self._local_class(typ, cdict, child, 
 | 
						|
                                        target_namespace, ignore)
 | 
						|
            else:
 | 
						|
                text = self._external_class(mod, typ, cdict, child, 
 | 
						|
                                            target_namespace, ignore)
 | 
						|
        except ValueError: # Simple type element
 | 
						|
            if self.type:
 | 
						|
                text = self.class_definition(target_namespace, cdict, 
 | 
						|
                                                ignore=ignore)
 | 
						|
                if child:
 | 
						|
                    self.local = True
 | 
						|
                self.done = True
 | 
						|
                    
 | 
						|
        except TypeError: # could be a ref then or a PyObj instance
 | 
						|
            if isinstance(self.type, PyObj):
 | 
						|
                pyobj = self.type
 | 
						|
                pyobj.name = self.name
 | 
						|
                pyobj.pyname = self.pyname
 | 
						|
                pyobj.class_name = self.class_name
 | 
						|
                cdict[self.name] = pyobj
 | 
						|
                return pyobj.text(target_namespace, cdict, ignore=ignore)
 | 
						|
            elif isinstance(self.ref, tuple):
 | 
						|
                (mod, typ) = self.ref
 | 
						|
                if mod:
 | 
						|
                    #self.superior = ["%s.%s" % (mod, typ)]
 | 
						|
                    if verify_import(self.root.modul[mod], typ):
 | 
						|
                        return req, text
 | 
						|
                    else:
 | 
						|
                        raise Exception(
 | 
						|
            "Import attempted on %s from %s module failed - wasn't there" % (
 | 
						|
                                typ,mod))
 | 
						|
                elif not child:
 | 
						|
                    self.superior = [typ]
 | 
						|
                    text = self.class_definition(target_namespace, cdict,
 | 
						|
                                                    ignore=ignore)
 | 
						|
            else:
 | 
						|
                if not cdict[class_pyify(self.ref)].done:
 | 
						|
                    raise MissingPrerequisite(self.ref)
 | 
						|
                
 | 
						|
        self.done = True
 | 
						|
        return req, text
 | 
						|
        
 | 
						|
def _do(obj, target_namespace, cdict, prep):
 | 
						|
    try:
 | 
						|
        (req, text) = obj.text(target_namespace, cdict)
 | 
						|
    except MissingPrerequisite:
 | 
						|
        return [], None
 | 
						|
        
 | 
						|
    if text is None:
 | 
						|
        if req:
 | 
						|
            #prep = prepend(req, prep)
 | 
						|
            prep.append(req)
 | 
						|
        return prep, None
 | 
						|
    else:
 | 
						|
        obj.done = True
 | 
						|
        if req:
 | 
						|
            if isinstance(req, basestring):
 | 
						|
                prep.append(req)
 | 
						|
            else:
 | 
						|
                prep.extend(req)
 | 
						|
        if text:
 | 
						|
            #prep = prepend(text, prep)
 | 
						|
            prep.append(text)
 | 
						|
    return prep
 | 
						|
 | 
						|
def reqursive_superior(supc, cdict):
 | 
						|
    properties = supc.properties[0]
 | 
						|
    for sup in supc.superior:
 | 
						|
        rsup = cdict[sup]
 | 
						|
        if rsup.properties[1]:
 | 
						|
            properties.extend(rsup.properties[1])
 | 
						|
        else:
 | 
						|
            properties.extend(reqursive_superior(rsup, cdict))
 | 
						|
    return properties
 | 
						|
    
 | 
						|
class PyType(PyObj):
 | 
						|
    def __init__(self, name=None, pyname=None, root=None, superior=None, 
 | 
						|
                internal=True, namespace=None):
 | 
						|
        PyObj.__init__(self, name, pyname, root)
 | 
						|
        self.class_name = leading_uppercase(self.name + '_')
 | 
						|
        self.properties = ([], [])
 | 
						|
        if superior:
 | 
						|
            self.superior = [superior]
 | 
						|
        else:
 | 
						|
            self.superior = []
 | 
						|
        self.value_type = None
 | 
						|
        self.internal = internal
 | 
						|
        self.namespace = namespace
 | 
						|
 | 
						|
    def text(self, target_namespace, cdict, _child=True, ignore=None,
 | 
						|
             _session=None):
 | 
						|
        if not self.properties and not self.type \
 | 
						|
                and not self.superior:
 | 
						|
            self.done = True
 | 
						|
            return [], self.class_definition(target_namespace, cdict)
 | 
						|
 | 
						|
        if ignore is None:
 | 
						|
            ignore = []
 | 
						|
        req = []
 | 
						|
        inherited_properties = []
 | 
						|
        for sup in self.superior:
 | 
						|
            try:
 | 
						|
                supc = cdict[sup]
 | 
						|
            except KeyError:
 | 
						|
                (mod, typ) = sup.split('.')
 | 
						|
                supc = pyobj_factory(sup, None, None)
 | 
						|
                if mod:
 | 
						|
                    supc.properties = [_import_attrs(self.root.modul[mod], 
 | 
						|
                                                        typ, self.root),[]]
 | 
						|
                cdict[sup] = supc
 | 
						|
                supc.done = True
 | 
						|
                
 | 
						|
            if not supc.done:
 | 
						|
                res = _do(supc, target_namespace, cdict, req)
 | 
						|
                if isinstance(res, tuple):
 | 
						|
                    return res
 | 
						|
            
 | 
						|
            if not self.properties[1]:
 | 
						|
                inherited_properties = reqursive_superior(supc, cdict)
 | 
						|
        
 | 
						|
        if inherited_properties:
 | 
						|
            self.properties = (self.properties[0], 
 | 
						|
                                rm_duplicates(inherited_properties))
 | 
						|
            
 | 
						|
        (own, inh) = self.properties
 | 
						|
        own = rm_duplicates(expand_groups(own, cdict))
 | 
						|
        self.properties = (own, inh)
 | 
						|
        for prop in own:
 | 
						|
            if not prop.name: # Ignore
 | 
						|
                continue 
 | 
						|
            if not prop.done:
 | 
						|
                if prop.name in ignore:
 | 
						|
                    continue
 | 
						|
                res = _do(prop, target_namespace, cdict, req)
 | 
						|
                if res == ([], None):
 | 
						|
                    # # Cleaning up
 | 
						|
                    # for prp in own:
 | 
						|
                    #     if prp == prop:
 | 
						|
                    #         break
 | 
						|
                    #     try:
 | 
						|
                    #         if cdict[prp.name].local:
 | 
						|
                    #             del cdict[prp.name]
 | 
						|
                    #             if hasattr(prp, "orig") and prp.orig:
 | 
						|
                    #                 for key, val in prp.orig.items():
 | 
						|
                    #                     setattr(prp, key, val)
 | 
						|
                    #             prp.done = False
 | 
						|
                    #             prp.local = False
 | 
						|
                    #     except KeyError:
 | 
						|
                    #         pass
 | 
						|
                    res = (req, None)
 | 
						|
                if isinstance(res, tuple):
 | 
						|
                    return res
 | 
						|
        
 | 
						|
        return req, self.class_definition(target_namespace, cdict, ignore)
 | 
						|
    
 | 
						|
    def undefined(self, cdict):
 | 
						|
        undef = ([], [])
 | 
						|
 | 
						|
        for sup in self.superior:
 | 
						|
            supc = cdict[sup]
 | 
						|
            if not supc.done:
 | 
						|
                undef[0].append(supc)
 | 
						|
 | 
						|
        (own, _) = self.properties
 | 
						|
        for prop in own:
 | 
						|
            if not prop.name: # Ignore
 | 
						|
                continue 
 | 
						|
            if isinstance(prop, PyAttribute):
 | 
						|
                continue
 | 
						|
            if not prop.done:
 | 
						|
                undef[1].append(prop)
 | 
						|
        return undef
 | 
						|
 | 
						|
class PyAttribute(PyObj):
 | 
						|
    def __init__(self, name=None, pyname=None, root=None, external=False, 
 | 
						|
                    namespace="", required=False, typ=""):
 | 
						|
        PyObj.__init__(self, name, pyname, root)
 | 
						|
 | 
						|
        self.required = required
 | 
						|
        self.external = external
 | 
						|
        self.namespace = namespace
 | 
						|
        self.base = None
 | 
						|
        self.type = typ
 | 
						|
        self.fixed = False
 | 
						|
        self.default = None
 | 
						|
 | 
						|
    def text(self, _target_namespace, cdict, _child=True):
 | 
						|
        if isinstance(self.type, PyObj):
 | 
						|
            if not cdict[self.type.name].done:
 | 
						|
                raise MissingPrerequisite(self.type.name)
 | 
						|
                
 | 
						|
        return [], [] # Means this elements definition is empty
 | 
						|
        
 | 
						|
    def spec(self):
 | 
						|
        if isinstance(self.type, PyObj):
 | 
						|
            return "('%s', %s, %s)" % (self.pyname, self.type.class_name, 
 | 
						|
                                        self.required)
 | 
						|
        else:
 | 
						|
            if self.type:
 | 
						|
                return "('%s', '%s', %s)" % (self.pyname, self.type, 
 | 
						|
                                                self.required)
 | 
						|
            else:
 | 
						|
                return "('%s', '%s', %s)" % (self.pyname, self.base, 
 | 
						|
                                                self.required)
 | 
						|
       
 | 
						|
class PyAny(PyObj):
 | 
						|
    def __init__(self, name=None, pyname=None, _external=False, _namespace=""):
 | 
						|
        PyObj.__init__(self, name, pyname)
 | 
						|
        self.done = True
 | 
						|
 | 
						|
class PyAttributeGroup(object):
 | 
						|
    def __init__(self, name, root):
 | 
						|
        self.name = name
 | 
						|
        self.root = root
 | 
						|
        self.properties = []
 | 
						|
 | 
						|
class PyGroup(object):
 | 
						|
    def __init__(self, name, root):
 | 
						|
        self.name = name
 | 
						|
        self.root = root
 | 
						|
        self.properties = []
 | 
						|
        self.done = False
 | 
						|
        self.ref = []
 | 
						|
    
 | 
						|
    def text(self, _target_namespace, _dict, _child, _ignore):
 | 
						|
        return [], []
 | 
						|
        
 | 
						|
    def undefined(self, _cdict):
 | 
						|
        undef = ([], [])
 | 
						|
 | 
						|
        (own, _) = self.properties
 | 
						|
        for prop in own:
 | 
						|
            if not prop.name: # Ignore
 | 
						|
                continue 
 | 
						|
            if not prop.done:
 | 
						|
                undef[1].append(prop)
 | 
						|
        return undef
 | 
						|
    
 | 
						|
# -----------------------------------------------------------------------------
 | 
						|
def verify_import(modul, tag):
 | 
						|
    try:
 | 
						|
        _ = modul.factory(tag)
 | 
						|
        return True
 | 
						|
    except Exception:
 | 
						|
        return False
 | 
						|
    
 | 
						|
def external_namespace(modul):
 | 
						|
    return modul.NAMESPACE
 | 
						|
 | 
						|
def _import_attrs(modul, tag, top):
 | 
						|
    obj = modul.factory(tag)
 | 
						|
    properties = [PyAttribute(key, val[0], top, True, obj.c_namespace, val[2],
 | 
						|
                            val[1]) for key,val in obj.c_attributes.items()]
 | 
						|
    for child in obj.c_child_order:
 | 
						|
        for key, val in obj.c_children.items():
 | 
						|
            (pyn, mul) = val
 | 
						|
            maximum = 1
 | 
						|
            if isinstance(mul, list):
 | 
						|
                mul = mul[0]
 | 
						|
                maximum = "unbounded"
 | 
						|
            if pyn == child:
 | 
						|
                cpy = PyElement(name=mul.c_tag, pyname=pyn, root=top) 
 | 
						|
    #                            internal=False, ns=obj.c_namespace)
 | 
						|
                cpy.max = maximum
 | 
						|
                properties.append(cpy)
 | 
						|
 | 
						|
    return properties
 | 
						|
 | 
						|
# ------------------------------------------------------------------------
 | 
						|
 | 
						|
def _spec(elem):
 | 
						|
    try:
 | 
						|
        name = elem.name
 | 
						|
    except AttributeError:
 | 
						|
        name = "anonymous"
 | 
						|
    txt = "%s" % name
 | 
						|
    try:
 | 
						|
        txt += " ref: %s" % elem.ref
 | 
						|
    except AttributeError:
 | 
						|
        try:
 | 
						|
            txt += " type: %s" % elem.type
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
 | 
						|
    return txt
 | 
						|
        
 | 
						|
# def _klass(elem, _namespace, sup, top):
 | 
						|
#     if elem.name in top.py_elements:
 | 
						|
#         return None
 | 
						|
#     else:
 | 
						|
#         kl = PyType(elem.name, root=top)
 | 
						|
#         top.py_elements[elem.name] = kl
 | 
						|
#         if sup != "SamlBase":
 | 
						|
#             kl.superior.append(sup)
 | 
						|
#         return kl
 | 
						|
        
 | 
						|
def _do_from_string(name):
 | 
						|
    print
 | 
						|
    print "def %s_from_string(xml_string):" % pyify(name)
 | 
						|
    print "%sreturn saml2.create_class_from_xml_string(%s, xml_string)" % (
 | 
						|
                INDENT, name)
 | 
						|
 | 
						|
def _namespace_and_tag(obj, param, top):
 | 
						|
    try:
 | 
						|
        (namespace, tag) = param.split(":")
 | 
						|
    except ValueError:
 | 
						|
        namespace = ""
 | 
						|
        tag = param
 | 
						|
    # except AttributeError:
 | 
						|
    #     namespace = ""
 | 
						|
    #     tag = obj.name
 | 
						|
 | 
						|
    return namespace, tag
 | 
						|
    
 | 
						|
# -----------------------------------------------------------------------------
 | 
						|
 | 
						|
class Simple(object):
 | 
						|
    def __init__(self, elem):
 | 
						|
        self.default = None
 | 
						|
        self.fixed = None
 | 
						|
        self.xmlns_map = []
 | 
						|
        self.name = ""
 | 
						|
        self.type = None
 | 
						|
        self.use = None
 | 
						|
        self.ref = None
 | 
						|
        self.scoped = False
 | 
						|
        self.itemType = None
 | 
						|
        
 | 
						|
        for attribute, value in elem.attrib.iteritems():            
 | 
						|
            self.__setattr__(attribute, value)
 | 
						|
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        argv_copy = sd_copy(argv)
 | 
						|
        rval = self.repr(top, sup, argv_copy, True, parent)
 | 
						|
        if rval:
 | 
						|
            return [rval], []
 | 
						|
        else:
 | 
						|
            return [], []
 | 
						|
 | 
						|
    def repr(self, _top=None, _sup=None, _argv=None, _child=True, _parent=""):
 | 
						|
        return None
 | 
						|
        
 | 
						|
    def elements(self, _top):
 | 
						|
        return []
 | 
						|
 | 
						|
        
 | 
						|
class Any(Simple):
 | 
						|
    
 | 
						|
    def repr(self, _top=None, _sup=None, _argv=None, _child=True, _parent=""):
 | 
						|
        return PyAny()
 | 
						|
        
 | 
						|
class AnyAttribute(Simple):
 | 
						|
 | 
						|
    def repr(self, _top=None, _sup=None, _argv=None, _child=True, _parent=""):
 | 
						|
        return PyAny()
 | 
						|
 | 
						|
class Attribute(Simple):
 | 
						|
    def repr(self, top=None, sup=None, _argv=None, _child=True, _parent=""):
 | 
						|
        # default, fixed, use, type
 | 
						|
                    
 | 
						|
        if DEBUG:
 | 
						|
            print "#ATTR", self.__dict__
 | 
						|
 | 
						|
        external = False
 | 
						|
        name = ""
 | 
						|
        try:
 | 
						|
            (namespace, tag) = _namespace_and_tag(self, self.ref, top)
 | 
						|
            ref = True
 | 
						|
            pyname = tag
 | 
						|
            if namespace in self.xmlns_map:
 | 
						|
                if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                    name = tag
 | 
						|
                else :
 | 
						|
                    external = True
 | 
						|
                    name = "{%s}%s" % (self.xmlns_map[namespace], tag)
 | 
						|
            else:
 | 
						|
                if namespace == "xml":
 | 
						|
                    name = "{%s}%s" % (XML_NAMESPACE, tag)
 | 
						|
        except AttributeError:
 | 
						|
            name = self.name
 | 
						|
            pyname = pyify(name)
 | 
						|
            ref = False
 | 
						|
        except ValueError: # self.ref exists but does not split into two parts
 | 
						|
            ref = True
 | 
						|
            if "" == top.target_namespace:
 | 
						|
                name = self.ref
 | 
						|
                pyname = pyify(name)
 | 
						|
            else: # referering to what
 | 
						|
                raise Exception("Strange reference: %s" % self.ref)
 | 
						|
                    
 | 
						|
        objekt = PyAttribute(name, pyname, external=external, root=top)
 | 
						|
        
 | 
						|
        # Initial declaration
 | 
						|
        if not ref:
 | 
						|
            try:
 | 
						|
                (namespace, klass) = _namespace_and_tag(self, self.type, top)
 | 
						|
                if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                    ctyp = get_type_def(klass, top.parts)
 | 
						|
                    if not ctyp.py_class:
 | 
						|
                        ctyp.repr(top, sup)
 | 
						|
                    objekt.type = ctyp.py_class
 | 
						|
                elif self.xmlns_map[namespace] == XMLSCHEMA:
 | 
						|
                    objekt.type = klass
 | 
						|
                else:
 | 
						|
                    objekt.type = self.type
 | 
						|
            except ValueError:
 | 
						|
                if self.xmlns_map[""] == top.target_namespace:
 | 
						|
                    ctyp = get_type_def(self.type.replace("-","_"), top.parts)
 | 
						|
                    if not ctyp.py_class:
 | 
						|
                        ctyp.repr(top, sup)
 | 
						|
                    objekt.type = ctyp.py_class                    
 | 
						|
                else:
 | 
						|
                    objekt.type = self.type
 | 
						|
            except AttributeError:
 | 
						|
                objekt.type = None
 | 
						|
        try:
 | 
						|
            if self.use == "required":
 | 
						|
                objekt.required = True
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
            
 | 
						|
        # in init
 | 
						|
        try:
 | 
						|
            objekt.default = self.default
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
                
 | 
						|
        # attr def
 | 
						|
        try:
 | 
						|
            objekt.fixed = self.fixed
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
        
 | 
						|
        if DEBUG:
 | 
						|
            print "#--ATTR py_attr:%s" % (objekt,)
 | 
						|
            
 | 
						|
        return objekt
 | 
						|
        
 | 
						|
class Enumeration(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class Union(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class Import(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class Documentation(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class MaxLength(Simple):
 | 
						|
    pass
 | 
						|
 | 
						|
class Length(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class MinInclusive(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class MaxInclusive(Simple):
 | 
						|
    pass
 | 
						|
 | 
						|
class MinExclusive(Simple):
 | 
						|
    pass
 | 
						|
 | 
						|
class MaxExclusive(Simple):
 | 
						|
    pass
 | 
						|
    
 | 
						|
class List(Simple):
 | 
						|
    pass
 | 
						|
 | 
						|
class Include(Simple):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
# -----------------------------------------------------------------------------
 | 
						|
 | 
						|
def sequence(elem):
 | 
						|
    return [evaluate(child.tag, child) for child in elem]
 | 
						|
 | 
						|
def name_or_ref(elem, top):
 | 
						|
    try:
 | 
						|
        (namespace, name) = _namespace_and_tag(elem, elem.ref, top)
 | 
						|
        if namespace and elem.xmlns_map[namespace] == top.target_namespace:
 | 
						|
            return name
 | 
						|
        else:
 | 
						|
            return elem.ref
 | 
						|
    except AttributeError:
 | 
						|
        return elem.name
 | 
						|
 | 
						|
class Complex(object):
 | 
						|
    def __init__(self, elem):
 | 
						|
        self.value_of = ""
 | 
						|
        self.parts = []
 | 
						|
        self._own = []
 | 
						|
        self._inherited = []
 | 
						|
        self._generated = False
 | 
						|
        self.py_class = None
 | 
						|
        self.properties = []
 | 
						|
        # From Elementtree
 | 
						|
        self.ref = None
 | 
						|
        self.type = None
 | 
						|
        self.xmlns_map = []
 | 
						|
        self.maxOccurs = 1
 | 
						|
        self.minOccurs = 1
 | 
						|
        self.base = None
 | 
						|
        self.scoped = False
 | 
						|
        self.abstract = False
 | 
						|
        
 | 
						|
        for attribute, value in elem.attrib.iteritems():
 | 
						|
            self.__setattr__(attribute, value)
 | 
						|
 | 
						|
        try:
 | 
						|
            if elem.text.strip():
 | 
						|
                self.value_of = elem.text.strip()
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
 | 
						|
        self.do_child(elem)
 | 
						|
        
 | 
						|
        try:
 | 
						|
            self.name = self.name.replace("-","_")
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
 | 
						|
    def _extend(self, top, sup, argv=None, parent="", base=""):
 | 
						|
        argv_copy = sd_copy(argv)
 | 
						|
        for part in self.parts:
 | 
						|
            (own, inh) = part.collect(top, sup, argv_copy, parent)
 | 
						|
            if own and base:
 | 
						|
                if len(own) == 1 and isinstance(own[0], PyAttribute):
 | 
						|
                    own[0].base = base
 | 
						|
            self._own.extend(own)
 | 
						|
            self._inherited.extend(inh)
 | 
						|
        
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        if self._own or self._inherited:
 | 
						|
            return self._own, self._inherited
 | 
						|
            
 | 
						|
        if DEBUG:
 | 
						|
            print self.__dict__
 | 
						|
            print "#-- %d parts" % len(self.parts)
 | 
						|
        
 | 
						|
        self._extend(top, sup, argv, parent)
 | 
						|
        
 | 
						|
        return self._own, self._inherited
 | 
						|
        
 | 
						|
    def do_child(self, elem):
 | 
						|
        for child in elem:
 | 
						|
            self.parts.append(evaluate(child.tag, child))
 | 
						|
 | 
						|
    def elements(self, top):
 | 
						|
        res = []
 | 
						|
        # try:
 | 
						|
        #     string = "== %s (%s)" % (self.name,self.__class__)
 | 
						|
        # except AttributeError:
 | 
						|
        #     string = "== (%s)" % (self.__class__,)
 | 
						|
        # print string
 | 
						|
        for part in self.parts:
 | 
						|
            if isinstance(part, Element):
 | 
						|
                res.append(name_or_ref(part, top))
 | 
						|
            else:
 | 
						|
                if isinstance(part, Extension):
 | 
						|
                    res.append(part.base)
 | 
						|
                res.extend(part.elements(top))
 | 
						|
 | 
						|
        return res
 | 
						|
 | 
						|
    def repr(self, _top=None, _sup=None, _argv=None, _child=True, parent=""):
 | 
						|
        return None
 | 
						|
 | 
						|
    def significant_parts(self):
 | 
						|
        res = []
 | 
						|
        for p in self.parts:
 | 
						|
            if isinstance(p, Annotation):
 | 
						|
                continue
 | 
						|
            else:
 | 
						|
                res.append(p)
 | 
						|
                
 | 
						|
        return res
 | 
						|
        
 | 
						|
def min_max(cls, objekt, argv):
 | 
						|
    try:
 | 
						|
        objekt.max = argv["maxOccurs"]
 | 
						|
        if cls.maxOccurs != 1:
 | 
						|
            objekt.max = cls.maxOccurs
 | 
						|
    except (KeyError, TypeError):
 | 
						|
        objekt.max = cls.maxOccurs
 | 
						|
 | 
						|
    try:
 | 
						|
        objekt.min = argv["minOccurs"]
 | 
						|
        if cls.minOccurs != 1:
 | 
						|
            objekt.min = cls.minOccurs
 | 
						|
    except (KeyError, TypeError):
 | 
						|
        objekt.min = cls.minOccurs
 | 
						|
            
 | 
						|
    
 | 
						|
class Element(Complex):
 | 
						|
    def __str__(self):
 | 
						|
        return "%s" % (self.__dict__,)
 | 
						|
 | 
						|
    def klass(self, top):
 | 
						|
        xns = None
 | 
						|
        ctyp = None
 | 
						|
        ref = False
 | 
						|
        try:
 | 
						|
            (namespace, name) = _namespace_and_tag(self, self.ref, top)
 | 
						|
            ref = True
 | 
						|
        except AttributeError:
 | 
						|
            try:
 | 
						|
                (namespace, name) = self.type.split(":")
 | 
						|
            except ValueError:
 | 
						|
                namespace = None
 | 
						|
                name = self.type
 | 
						|
            except AttributeError:
 | 
						|
                namespace = name = None
 | 
						|
 | 
						|
        if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
            ctyp = get_type_def(name, top.parts)
 | 
						|
        else:
 | 
						|
            xns = namespace
 | 
						|
 | 
						|
        return namespace, name, ctyp, xns, ref
 | 
						|
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        """ means this element is part of a larger object, hence a property of 
 | 
						|
        that object """
 | 
						|
        
 | 
						|
        try:
 | 
						|
            argv_copy = sd_copy(argv)
 | 
						|
            return [self.repr(top, sup, argv_copy, parent=parent)], []
 | 
						|
        except AttributeError, exc:
 | 
						|
            print "#!!!!", exc
 | 
						|
            return [], []
 | 
						|
 | 
						|
    def elements(self, top):            
 | 
						|
        (_namespace, name, ctyp, xns, _) = self.klass(top)
 | 
						|
        if ctyp:
 | 
						|
            return ctyp.elements(top)
 | 
						|
        elif xns:
 | 
						|
            return ["%s.%s" % (xns, name)]
 | 
						|
        else:
 | 
						|
            return []
 | 
						|
 | 
						|
    def repr(self, top=None, sup=None, argv=None, child=True, parent=""):
 | 
						|
        #<element ref='xenc:ReferenceList' ...
 | 
						|
        #<element name='Transforms' type='xenc:TransformsType' ...
 | 
						|
        #<element name='CarriedKeyName' type='string' ...
 | 
						|
        #<element name="RecipientKeyInfo" type="ds:KeyInfoType" ...
 | 
						|
        #<element name='ReferenceList'>
 | 
						|
 | 
						|
        if self.py_class:
 | 
						|
            return self.py_class
 | 
						|
            
 | 
						|
        try:
 | 
						|
            myname = self.name
 | 
						|
        except AttributeError:
 | 
						|
            myname = ""
 | 
						|
 | 
						|
        if DEBUG:
 | 
						|
            print "#Element.repr '%s' (child=%s) [%s]" % (myname, 
 | 
						|
                                                            child, 
 | 
						|
                                                            self._generated)
 | 
						|
 | 
						|
        self.py_class = objekt = PyElement(myname, root=top)
 | 
						|
        min_max(self, objekt, argv)
 | 
						|
                
 | 
						|
        try:
 | 
						|
            (namespace, superkl) = _namespace_and_tag(self, self.ref, top)
 | 
						|
            # internal or external reference
 | 
						|
            if not myname:
 | 
						|
                objekt.name = superkl
 | 
						|
                objekt.pyname = pyify(superkl)
 | 
						|
            if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                objekt.ref = superkl 
 | 
						|
            else:
 | 
						|
                objekt.ref = (namespace, superkl)                
 | 
						|
        except AttributeError, exc:
 | 
						|
            if DEBUG:
 | 
						|
                print "#===>", exc
 | 
						|
 | 
						|
            typ = self.type
 | 
						|
 | 
						|
            try:
 | 
						|
                (namespace, klass) = _namespace_and_tag(self, typ, top)
 | 
						|
                if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                    objekt.type = (None, klass)
 | 
						|
                elif self.xmlns_map[namespace] == XMLSCHEMA:
 | 
						|
                    objekt.type = klass
 | 
						|
                    objekt.value_type = {"base": klass}
 | 
						|
                else:
 | 
						|
                    objekt.type = (namespace, klass)
 | 
						|
 | 
						|
            except ValueError:
 | 
						|
                objekt.type = typ
 | 
						|
                objekt.value_type = {"base": typ}
 | 
						|
 | 
						|
            except AttributeError:
 | 
						|
                # neither type nor reference, definitely local
 | 
						|
                if hasattr(self, "parts"):
 | 
						|
                    if len(self.parts) == 1:
 | 
						|
                        if isinstance(self.parts[0], ComplexType) or \
 | 
						|
                            isinstance(self.parts[0], SimpleType):
 | 
						|
                            self.parts[0].name = self.name
 | 
						|
                            objekt.type = self.parts[0].repr(top, sup, 
 | 
						|
                                                            parent=self.name)
 | 
						|
                            objekt.scoped = True
 | 
						|
                    elif len(self.parts) == 2:# One child might be Annotation
 | 
						|
                        if isinstance(self.parts[0], Annotation):
 | 
						|
                            self.parts[1].name = self.name
 | 
						|
                            objekt.type = self.parts[1].repr(top, sup, 
 | 
						|
                                                            parent=self.name)
 | 
						|
                            objekt.scoped = True
 | 
						|
                        elif isinstance(self.parts[1], Annotation):
 | 
						|
                            self.parts[0].name = self.name
 | 
						|
                            objekt.type = self.parts[0].repr(top, sup, 
 | 
						|
                                                            parent=self.name)
 | 
						|
                            objekt.scoped = True
 | 
						|
                else:
 | 
						|
                    if DEBUG:
 | 
						|
                        print "$", self
 | 
						|
                    raise 
 | 
						|
 | 
						|
            if parent:
 | 
						|
                objekt.class_name = "%s_%s" % (
 | 
						|
                                        leading_uppercase(parent),
 | 
						|
                                        objekt.name)
 | 
						|
                objekt.scoped = True
 | 
						|
                
 | 
						|
        return objekt
 | 
						|
 | 
						|
 | 
						|
class SimpleType(Complex):
 | 
						|
    def repr(self, top=None, _sup=None, _argv=None, _child=True, parent=""):
 | 
						|
        if self.py_class:
 | 
						|
            return self.py_class
 | 
						|
            
 | 
						|
        obj = PyType(self.name, root=top)
 | 
						|
        try:
 | 
						|
            if len(self.parts) == 1:
 | 
						|
                part = self.parts[0]
 | 
						|
                if isinstance(part, Restriction):
 | 
						|
                    if part.parts:
 | 
						|
                        if isinstance(part.parts[0], Enumeration):
 | 
						|
                            lista = [p.value for p in part.parts]
 | 
						|
                            obj.value_type = {"base":part.base,
 | 
						|
                                                "enumeration":lista}
 | 
						|
                        elif isinstance(part.parts[0], MaxLength):
 | 
						|
                            obj.value_type = {"base":part.base,
 | 
						|
                                                "maxlen":part.parts[0].value}
 | 
						|
                        elif isinstance(part.parts[0], Length):
 | 
						|
                            obj.value_type = {"base":part.base,
 | 
						|
                                                "len":part.parts[0].value}
 | 
						|
                    else:
 | 
						|
                        obj.value_type = {"base":part.base}
 | 
						|
                elif isinstance(part, List):
 | 
						|
                    if part.itemType:
 | 
						|
                        obj.value_type = {"base":"list", "member":part.itemType}
 | 
						|
        except ValueError:
 | 
						|
            pass
 | 
						|
        
 | 
						|
        self.py_class = obj
 | 
						|
        return obj
 | 
						|
        
 | 
						|
 | 
						|
class Sequence(Complex):
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        argv_copy = sd_copy(argv)
 | 
						|
        for key, val in self.__dict__.items():
 | 
						|
            if key not in ['xmlns_map'] and not key.startswith("_"):
 | 
						|
                argv_copy[key] = val
 | 
						|
    
 | 
						|
        if DEBUG:
 | 
						|
            print "#Sequence: %s" % argv
 | 
						|
        return Complex.collect(self, top, sup, argv_copy, parent)
 | 
						|
 | 
						|
 | 
						|
class SimpleContent(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
class ComplexContent(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
class Key(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
class Redefine(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
 | 
						|
class Extension(Complex):
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        if self._own or self._inherited:
 | 
						|
            return self._own, self._inherited
 | 
						|
        
 | 
						|
        if DEBUG:
 | 
						|
            print "#!!!", self.__dict__
 | 
						|
 | 
						|
        try:
 | 
						|
            base = self.base
 | 
						|
            (namespace, tag) = _namespace_and_tag(self, base, top)
 | 
						|
                    
 | 
						|
            if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                cti = get_type_def(tag, top.parts)
 | 
						|
                if not cti.py_class:
 | 
						|
                    cti.repr(top, sup)
 | 
						|
                #print "#EXT..",ct._collection
 | 
						|
                self._inherited = cti.py_class.properties[0][:]
 | 
						|
                self._inherited.extend(cti.py_class.properties[1])
 | 
						|
            elif self.xmlns_map[namespace] == XMLSCHEMA: 
 | 
						|
                base = tag
 | 
						|
            else:
 | 
						|
                iattr = _import_attrs(top.modul[namespace], tag, top)
 | 
						|
                #print "#EXT..-", ia
 | 
						|
                self._inherited = iattr
 | 
						|
        except (AttributeError, ValueError):
 | 
						|
            base = None
 | 
						|
 | 
						|
        self._extend(top, sup, argv, parent, base)
 | 
						|
 | 
						|
        return self._own, self._inherited
 | 
						|
 | 
						|
class Choice(Complex):
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        argv_copy = sd_copy(argv)
 | 
						|
        for key, val in self.__dict__.items():
 | 
						|
            if key not in ['xmlns_map'] and not key.startswith("_"):
 | 
						|
                argv_copy[key] = val
 | 
						|
 | 
						|
        # A choice means each element may not be part of the choice
 | 
						|
        argv_copy["minOccurs"] = 0
 | 
						|
            
 | 
						|
        if DEBUG:
 | 
						|
            print "#Choice: %s" % argv
 | 
						|
        return Complex.collect(self, top, sup, argv_copy, parent=parent)
 | 
						|
 | 
						|
class Restriction(Complex):
 | 
						|
    pass
 | 
						|
    # if isinstance(self.parts[0], Enumeration):
 | 
						|
    #     values = [enum.value for enum in self.parts]
 | 
						|
 | 
						|
class ComplexType(Complex):
 | 
						|
    def repr(self, top=None, sup=None, _argv=None, _child=True, parent=""):
 | 
						|
        if self.py_class:
 | 
						|
            return self.py_class
 | 
						|
                    
 | 
						|
        # looking for a pattern here
 | 
						|
        significant_parts = self.significant_parts()
 | 
						|
        value_type = ""
 | 
						|
        if len(significant_parts) == 1:
 | 
						|
            if isinstance(significant_parts[0], ComplexContent) or \
 | 
						|
                isinstance(significant_parts[0], SimpleContent):
 | 
						|
                cci = significant_parts[0]
 | 
						|
                if len(cci.parts) == 1:
 | 
						|
                    if isinstance(cci.parts[0], Extension):
 | 
						|
                        ext = cci.parts[0]
 | 
						|
 | 
						|
                        (namespace, name) = _namespace_and_tag(ext, ext.base, 
 | 
						|
                                                                top)
 | 
						|
 | 
						|
                        if ext.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                            new_sup = name
 | 
						|
                            cti = get_type_def(new_sup, top.parts)
 | 
						|
                            if cti and not cti.py_class:
 | 
						|
                                cti.repr(top, sup)
 | 
						|
                        elif ext.xmlns_map[namespace] == XMLSCHEMA:
 | 
						|
                            new_sup = None
 | 
						|
                            value_type = name
 | 
						|
                        else:
 | 
						|
                            new_sup = "%s.%s" % (namespace, name)
 | 
						|
                            
 | 
						|
                        #print "#Superior: %s" % new_sup
 | 
						|
                        if new_sup:
 | 
						|
                            sup = new_sup
 | 
						|
            else:
 | 
						|
                #print "#>>", self.parts[0].__class__
 | 
						|
                pass
 | 
						|
                
 | 
						|
        try:
 | 
						|
            self.py_class = PyType(self.name, superior=sup, 
 | 
						|
                                    namespace=top.target_namespace, root=top)
 | 
						|
        except AttributeError: # No name 
 | 
						|
            self.py_class = PyType("", superior=sup, 
 | 
						|
                                    namespace=top.target_namespace, root=top)
 | 
						|
 | 
						|
        try:
 | 
						|
            self.py_class.abstract = self.abstract
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
        
 | 
						|
        if value_type:
 | 
						|
            self.py_class.value_type = {"base": value_type}
 | 
						|
            
 | 
						|
        try:
 | 
						|
            if not parent:
 | 
						|
                try:
 | 
						|
                    parent = self.name
 | 
						|
                except AttributeError:
 | 
						|
                    parent = ""
 | 
						|
            
 | 
						|
            self.py_class.properties = self.collect(top, sup, parent=parent)
 | 
						|
        except ValueError:
 | 
						|
            pass
 | 
						|
            
 | 
						|
        return self.py_class 
 | 
						|
        
 | 
						|
class Annotation(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
class All(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
class Group(Complex):
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        """ means this element is part of a larger object, hence a property of 
 | 
						|
        that object """
 | 
						|
        
 | 
						|
        try:
 | 
						|
            #objekt = PyGroup("", root=top)
 | 
						|
            (namespace, tag) = _namespace_and_tag(self, self.ref, top)
 | 
						|
    
 | 
						|
            try:
 | 
						|
                if self.xmlns_map[namespace] == top.target_namespace:
 | 
						|
                    cti = get_type_def(tag, top.parts)
 | 
						|
                    try:
 | 
						|
                        return cti.py_class.properties
 | 
						|
                    except ValueError:
 | 
						|
                        return cti.collect(top, sup) 
 | 
						|
                else:
 | 
						|
                    raise Exception(
 | 
						|
                        "Reference to group in other XSD file, not supported")
 | 
						|
            except KeyError:
 | 
						|
                raise Exception("Missing namespace definition")            
 | 
						|
        except AttributeError, exc:
 | 
						|
            print "#!!!!", exc
 | 
						|
            return [], []
 | 
						|
 | 
						|
    def repr(self, top=None, sup=None, argv=None, _child=True, parent=""):
 | 
						|
        if self.py_class:
 | 
						|
            return self.py_class
 | 
						|
 | 
						|
        self.py_class = objekt = PyGroup(self.name, root=top)
 | 
						|
 | 
						|
        min_max(self, objekt, argv)
 | 
						|
        
 | 
						|
        try:
 | 
						|
            self._extend(top, sup, argv)
 | 
						|
            objekt.properties = (self._own, self._inherited)
 | 
						|
        except ValueError:
 | 
						|
            pass
 | 
						|
            
 | 
						|
        return objekt
 | 
						|
 | 
						|
class Unique(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
class Selector(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
class Field(Complex):
 | 
						|
    pass
 | 
						|
 | 
						|
class AttributeGroup(Complex):
 | 
						|
    def collect(self, top, sup, argv=None, parent=""):
 | 
						|
        try:
 | 
						|
            (_namespace, typ) = _namespace_and_tag(self, self.ref, top)
 | 
						|
            # TODO: use definitions in other XSD
 | 
						|
            cti = get_type_def(typ, top.parts)
 | 
						|
            return cti.collect(top, sup)
 | 
						|
        except AttributeError:
 | 
						|
            if self._own or self._inherited:
 | 
						|
                return self._own, self._inherited
 | 
						|
            
 | 
						|
            argv_copy = sd_copy(argv)
 | 
						|
            
 | 
						|
            for prop in self.parts:
 | 
						|
                if isinstance(prop, Attribute):
 | 
						|
                    self._own.append(prop.repr(top, sup, argv_copy, parent))
 | 
						|
 | 
						|
            return self._own, self._inherited
 | 
						|
 | 
						|
    def repr(self, top=None, sup=None, _argv=None, _child=True, parent=""):
 | 
						|
        if self.py_class:
 | 
						|
            return self.py_class
 | 
						|
            
 | 
						|
        self.py_class = PyAttributeGroup(self.name, root=top)
 | 
						|
 | 
						|
        try:
 | 
						|
            self.py_class.properties = self.collect(top, sup)
 | 
						|
        except ValueError:
 | 
						|
            pass
 | 
						|
            
 | 
						|
        return self.py_class 
 | 
						|
 | 
						|
def pyify_0(name):
 | 
						|
    res = ""
 | 
						|
    match = re.match(
 | 
						|
            r"^(([A-Z])[a-z]+)(([A-Z])[a-z]+)?(([A-Z])[a-z]+)?(([A-Z])[a-z]+)?",
 | 
						|
            name)
 | 
						|
    res += match.group(1).lower()
 | 
						|
    for num in range(3, len(match.groups()), 2):
 | 
						|
        try:
 | 
						|
            res += "_"+match.group(num+1).lower()+match.group(num)[1:]
 | 
						|
        except AttributeError:
 | 
						|
            break
 | 
						|
    
 | 
						|
    res = res.replace("-","_")
 | 
						|
    if res in ["class"]:
 | 
						|
        res += "_"
 | 
						|
    return res
 | 
						|
 | 
						|
 | 
						|
def pyify(name):
 | 
						|
    # AssertionIDRef
 | 
						|
    res = []
 | 
						|
    
 | 
						|
    upc = []
 | 
						|
    pre = ""
 | 
						|
    for char in name:
 | 
						|
        if "A" <= char <= "Z":
 | 
						|
            upc.append(char)
 | 
						|
        elif char == "-":
 | 
						|
            upc.append("_")
 | 
						|
        else:
 | 
						|
            if upc:
 | 
						|
                if len(upc) == 1:
 | 
						|
                    res.append(pre+upc[0].lower())
 | 
						|
                else:
 | 
						|
                    if pre:
 | 
						|
                        res.append(pre)
 | 
						|
                    for uch in upc[:-1]:
 | 
						|
                        res.append(uch.lower())
 | 
						|
                    res.append("_"+upc[-1].lower())
 | 
						|
                        
 | 
						|
                upc = []
 | 
						|
            res.append(char)
 | 
						|
            pre = "_"
 | 
						|
    if upc:
 | 
						|
        if len(upc) == len(name):
 | 
						|
            return name.lower()
 | 
						|
        else:
 | 
						|
            res.append("_"+("".join(upc).lower()))
 | 
						|
        
 | 
						|
    return "".join(res)
 | 
						|
 | 
						|
 | 
						|
def get_type_def( typ, defs):
 | 
						|
    for cdef in defs:
 | 
						|
        try:
 | 
						|
            if cdef.name == typ:
 | 
						|
                return cdef
 | 
						|
        except AttributeError:
 | 
						|
            pass
 | 
						|
    return None
 | 
						|
    
 | 
						|
 | 
						|
def sort_elements(els):
 | 
						|
    res = []
 | 
						|
    
 | 
						|
    diff = False
 | 
						|
    for key, val in els.items():
 | 
						|
        if not val:
 | 
						|
            res.append(key)
 | 
						|
            del els[key]
 | 
						|
            diff = True
 | 
						|
    
 | 
						|
    res.sort()
 | 
						|
    while diff:
 | 
						|
        diff = False
 | 
						|
        for key, val in els.items():
 | 
						|
            pres = [v for v in val if v not in res and ':' not in v]
 | 
						|
            els[key] = pres
 | 
						|
            if pres != val:
 | 
						|
                diff = True
 | 
						|
 | 
						|
        #print els
 | 
						|
        partres = []
 | 
						|
        for key, val in els.items():
 | 
						|
            if not val:
 | 
						|
                partres.append(key)
 | 
						|
                del els[key]
 | 
						|
                diff = True
 | 
						|
        partres.sort()
 | 
						|
        res.extend(partres)
 | 
						|
        
 | 
						|
    return res, els
 | 
						|
 | 
						|
 | 
						|
def output(elem, target_namespace, eldict, ignore=None):
 | 
						|
    done = 0
 | 
						|
 | 
						|
    if ignore is None:
 | 
						|
        ignore = []
 | 
						|
        
 | 
						|
    try:
 | 
						|
        (preps, text) = elem.text(target_namespace, eldict, False, ignore)
 | 
						|
    except TypeError:
 | 
						|
        return done
 | 
						|
    except MissingPrerequisite:
 | 
						|
        return done
 | 
						|
    
 | 
						|
    for prep in preps:
 | 
						|
        if prep:
 | 
						|
            done = 1
 | 
						|
            if isinstance(prep, basestring):
 | 
						|
                print prep
 | 
						|
            else:
 | 
						|
                for item in prep:
 | 
						|
                    print item
 | 
						|
                    print
 | 
						|
            print 
 | 
						|
 | 
						|
    if text:
 | 
						|
        done = 1
 | 
						|
        elem.done = True
 | 
						|
        print text
 | 
						|
        print
 | 
						|
    
 | 
						|
    return done
 | 
						|
    
 | 
						|
 | 
						|
def intro():
 | 
						|
    print """#!/usr/bin/env python
 | 
						|
 | 
						|
#
 | 
						|
# Generated %s by parse_xsd.py version %s.
 | 
						|
#
 | 
						|
 | 
						|
import saml2
 | 
						|
from saml2 import SamlBase
 | 
						|
""" % (time.ctime(), __version__)
 | 
						|
 | 
						|
#NAMESPACE = 'http://www.w3.org/2000/09/xmldsig#'
 | 
						|
    
 | 
						|
 | 
						|
def block_items(objekt, block, eldict):
 | 
						|
    if objekt not in block:
 | 
						|
        if isinstance(objekt.type, PyType):
 | 
						|
            if objekt.type not in block:
 | 
						|
                block.append(objekt.type)
 | 
						|
        block.append(objekt)
 | 
						|
        if isinstance(objekt, PyType):
 | 
						|
            others = [p for p in eldict.values() if isinstance(p, 
 | 
						|
                                    PyElement) and p.type[1] == objekt.name]
 | 
						|
            for item in others:
 | 
						|
                if item not in block:
 | 
						|
                    block.append(item)
 | 
						|
    return block
 | 
						|
 | 
						|
    
 | 
						|
def find_parent(elm, eldict):
 | 
						|
    if isinstance(elm, PyElement):
 | 
						|
        if elm.type:
 | 
						|
            sup = eldict[elm.type[1]]
 | 
						|
            return find_parent(sup, eldict)
 | 
						|
        elif elm.ref:
 | 
						|
            sup = eldict[elm.ref]
 | 
						|
            if sup.name == elm.name:
 | 
						|
                return elm
 | 
						|
            return find_parent(sup, eldict)
 | 
						|
    else:
 | 
						|
        if elm.superior:
 | 
						|
            sup = eldict[elm.superior[0]]
 | 
						|
            if sup.done:
 | 
						|
                return elm
 | 
						|
            return find_parent(sup, eldict)
 | 
						|
    
 | 
						|
    return elm
 | 
						|
    
 | 
						|
 | 
						|
class Schema(Complex):
 | 
						|
 | 
						|
    def __init__(self, elem, impo, add, modul, defs):
 | 
						|
        Complex.__init__(self, elem)
 | 
						|
        self.impo = impo
 | 
						|
        self.add = add
 | 
						|
        self.modul = modul
 | 
						|
        self.py_elements = {}
 | 
						|
        self.py_attributes = {}
 | 
						|
        self.elems = []
 | 
						|
        self.attrgrp = []
 | 
						|
        self.defs = []
 | 
						|
        try:
 | 
						|
            self.target_namespace = self.targetNamespace
 | 
						|
        except AttributeError:
 | 
						|
            self.target_namespace = ""
 | 
						|
        for def_file in defs:
 | 
						|
            self.defs.append(open(def_file).read())
 | 
						|
 | 
						|
    def _mk_list(self, objekt, alla, eldict):
 | 
						|
        tup = []
 | 
						|
        for prop in alla:
 | 
						|
            (mod, cname) = _mod_cname(prop, eldict)
 | 
						|
 | 
						|
            if prop.max == "unbounded":
 | 
						|
                lista = True
 | 
						|
            else:
 | 
						|
                lista = False
 | 
						|
 | 
						|
            spec = objekt.child_spec(self.target_namespace, 
 | 
						|
                                        prop, mod, cname, 
 | 
						|
                                        lista)
 | 
						|
            lines = ["%s.%s" % (objekt.class_name, spec)]
 | 
						|
            tup.append((prop, lines, spec))
 | 
						|
        
 | 
						|
        return tup
 | 
						|
        
 | 
						|
    def adjust(self, eldict, block):
 | 
						|
        udict = {}
 | 
						|
        for elem in self.elems:
 | 
						|
            if isinstance(elem, PyAttribute) or isinstance(elem, PyGroup):
 | 
						|
                elem.done = True
 | 
						|
                continue
 | 
						|
            if elem in block:
 | 
						|
                continue
 | 
						|
            if not elem.done:
 | 
						|
                udict[elem] = elem.undefined(eldict)
 | 
						|
 | 
						|
        keys = [k.name for k in udict.keys()]
 | 
						|
        print "#", keys
 | 
						|
        res = (None, [])
 | 
						|
        if not udict:
 | 
						|
            return res
 | 
						|
        level = 1
 | 
						|
        rblocked = [p.name for p in block]
 | 
						|
        while True:
 | 
						|
            non_child = 0
 | 
						|
            for objekt, (sup, elems) in udict.items():
 | 
						|
                if sup:
 | 
						|
                    continue
 | 
						|
                else:
 | 
						|
                    non_child += 1
 | 
						|
                    signif = []
 | 
						|
                    other = []
 | 
						|
                    for elem in elems:
 | 
						|
                        if elem.name in keys:
 | 
						|
                            signif.append(elem)
 | 
						|
                        elif elem.ref in rblocked:
 | 
						|
                            other.append(elem)
 | 
						|
                    if len(signif) <= level:
 | 
						|
                        alla = signif
 | 
						|
                        alla.extend(other)
 | 
						|
                        tup = self._mk_list(objekt, alla, eldict)
 | 
						|
                        res = (objekt, tup)
 | 
						|
                        break
 | 
						|
            if res[0]:
 | 
						|
                ref = res[0].name
 | 
						|
                tups = res[1]
 | 
						|
                for objekt, (sups, elems) in udict.items():
 | 
						|
                    if sups:
 | 
						|
                        for sup in sups:
 | 
						|
                            if sup.name == ref:
 | 
						|
                                for tup in tups:
 | 
						|
                                    tup[1].append("%s.%s" % (objekt.class_name,
 | 
						|
                                                            tup[2]))
 | 
						|
                                break
 | 
						|
                    else:
 | 
						|
                        pass
 | 
						|
            elif not non_child or level > 10:
 | 
						|
                elm = udict.keys()[0]
 | 
						|
                parent = find_parent(elm, eldict)
 | 
						|
                signif = []
 | 
						|
                other = []
 | 
						|
                tot = parent.properties[0]
 | 
						|
                tot.extend(parent.properties[1])
 | 
						|
                alla = []
 | 
						|
                for elem in tot:
 | 
						|
                    if isinstance(elem, PyAttribute):
 | 
						|
                        continue
 | 
						|
                    else:
 | 
						|
                        alla.append(elem)
 | 
						|
                tup = self._mk_list(parent, alla, eldict)
 | 
						|
                res = (parent, tup)
 | 
						|
                
 | 
						|
            if res[0]:
 | 
						|
                break
 | 
						|
            else:
 | 
						|
                level += 1
 | 
						|
        return res
 | 
						|
 | 
						|
    def _do(self, eldict):
 | 
						|
        not_done = 1
 | 
						|
        undone = 0
 | 
						|
        while not_done:
 | 
						|
            not_done = 0
 | 
						|
            undone = 0
 | 
						|
            for elem in self.elems:
 | 
						|
                if isinstance(elem, PyGroup) or elem.done:
 | 
						|
                    continue
 | 
						|
                undone += 1
 | 
						|
                not_done += output(elem, self.target_namespace, eldict)
 | 
						|
        return undone
 | 
						|
        
 | 
						|
    def _element_from_string(self):
 | 
						|
        print "ELEMENT_FROM_STRING = {"
 | 
						|
        for elem in self.elems:
 | 
						|
            if isinstance(elem, PyAttribute) or isinstance(elem, PyGroup):
 | 
						|
                continue
 | 
						|
            if elem.abstract:
 | 
						|
                continue
 | 
						|
            print "%s%s.c_tag: %s_from_string," % (INDENT, elem.class_name, 
 | 
						|
                                                    pyify(elem.class_name))
 | 
						|
        print "}"
 | 
						|
        print
 | 
						|
        
 | 
						|
    def _element_by_tag(self):
 | 
						|
        print "ELEMENT_BY_TAG = {"
 | 
						|
        listed = []
 | 
						|
        for elem in self.elems:
 | 
						|
            if isinstance(elem, PyAttribute) or isinstance(elem, PyGroup):
 | 
						|
                continue
 | 
						|
            if elem.abstract:
 | 
						|
                continue
 | 
						|
            lcen = elem.name
 | 
						|
            print "%s'%s': %s," % (INDENT, lcen, elem.class_name)
 | 
						|
            listed.append(lcen)
 | 
						|
        for elem in self.elems:
 | 
						|
            if isinstance(elem, PyAttribute) or isinstance(elem, PyGroup):
 | 
						|
                continue
 | 
						|
            lcen = elem.name
 | 
						|
            if elem.abstract and lcen not in listed:
 | 
						|
                print "%s'%s': %s," % (INDENT, lcen, elem.class_name)
 | 
						|
                listed.append(lcen)
 | 
						|
        print "}"
 | 
						|
        print
 | 
						|
        
 | 
						|
    def out(self):
 | 
						|
        for part in self.parts:
 | 
						|
            if isinstance(part, Import):
 | 
						|
                continue
 | 
						|
            if part is None:
 | 
						|
                continue
 | 
						|
                
 | 
						|
            elem = part.repr(self, "", {}, False)
 | 
						|
            if elem:
 | 
						|
                if isinstance(elem, PyAttributeGroup):
 | 
						|
                    self.attrgrp.append(elem)
 | 
						|
                else:
 | 
						|
                    self.elems.append(elem)
 | 
						|
        
 | 
						|
        eldict = {}
 | 
						|
        for elem in self.elems:
 | 
						|
            eldict[elem.name] = elem
 | 
						|
 | 
						|
        #print eldict.keys()
 | 
						|
        
 | 
						|
        intro()
 | 
						|
        for modul in self.add:
 | 
						|
            print "from %s import *" % modul
 | 
						|
        for _namespace, (mod, namn) in self.impo.items():
 | 
						|
            if namn:
 | 
						|
                print "import %s as %s" % (mod, namn)
 | 
						|
        print        
 | 
						|
        print "NAMESPACE = '%s'" % self.target_namespace
 | 
						|
        print
 | 
						|
 | 
						|
        for defs in self.defs:
 | 
						|
            print defs
 | 
						|
            print
 | 
						|
        
 | 
						|
        exceptions = []
 | 
						|
        block = []
 | 
						|
        while self._do(eldict):
 | 
						|
            print "#.................."
 | 
						|
            (objekt, tups) = self.adjust(eldict, block)
 | 
						|
            if not objekt:
 | 
						|
                break
 | 
						|
            ignore = [p.name for (p, _l, _s) in tups]
 | 
						|
            done = output(objekt, self.target_namespace, eldict, ignore)
 | 
						|
            if done:
 | 
						|
                for (prop, lines, _) in tups:
 | 
						|
                    exceptions.extend(lines)
 | 
						|
                block = []
 | 
						|
            else:
 | 
						|
                block = block_items(objekt, block, eldict)
 | 
						|
 | 
						|
        if exceptions:
 | 
						|
            print "#", 70*'+'
 | 
						|
            for line in exceptions:
 | 
						|
                print line
 | 
						|
            print "#", 70*'+'
 | 
						|
            print
 | 
						|
        
 | 
						|
        for attrgrp in self.attrgrp:
 | 
						|
            print "AG_%s = [" % attrgrp.name
 | 
						|
            for prop in attrgrp.properties[0]:
 | 
						|
                if isinstance(prop.type, PyObj):
 | 
						|
                    print "%s('%s', %s_, %s)," % (INDENT, prop.name, 
 | 
						|
                                                prop.type.name, prop.required)
 | 
						|
                else:
 | 
						|
                    print "%s('%s', '%s', %s)," % (INDENT, prop.name, 
 | 
						|
                                                    prop.type, prop.required)
 | 
						|
            print "]"
 | 
						|
            print
 | 
						|
           
 | 
						|
        self._element_from_string() 
 | 
						|
        self._element_by_tag()
 | 
						|
        print
 | 
						|
        print "def factory(tag, **kwargs):"
 | 
						|
        print "    return ELEMENT_BY_TAG[tag](**kwargs)"
 | 
						|
        print
 | 
						|
        
 | 
						|
        
 | 
						|
# -----------------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
NAMESPACE_BASE = ["http://www.w3.org/2001/XMLSchema",
 | 
						|
    "http://www.w3.org/2000/10/XMLSchema"]
 | 
						|
 | 
						|
_MAP = {    
 | 
						|
    "element": Element,
 | 
						|
    "complexType": ComplexType,
 | 
						|
    "sequence": Sequence,
 | 
						|
    "any": Any,
 | 
						|
    "all": All,
 | 
						|
    "anyAttribute": AnyAttribute,
 | 
						|
    "simpleContent": SimpleContent,
 | 
						|
    "extension": Extension,
 | 
						|
    "union": Union,
 | 
						|
    "restriction": Restriction,
 | 
						|
    "enumeration": Enumeration,
 | 
						|
    "import": Import,
 | 
						|
    "annotation": Annotation,
 | 
						|
    "attributeGroup":AttributeGroup,
 | 
						|
    "attribute":Attribute,
 | 
						|
    "choice": Choice,
 | 
						|
    "complexContent": ComplexContent,
 | 
						|
    "documentation": Documentation,
 | 
						|
    "simpleType": SimpleType,
 | 
						|
    "maxLength": MaxLength,
 | 
						|
    "list": List,
 | 
						|
    "unique": Unique,
 | 
						|
    "group": Group,
 | 
						|
    "selector": Selector,
 | 
						|
    "field": Field,
 | 
						|
    "key": Key,
 | 
						|
    "include": Include,
 | 
						|
    "redefine": Redefine
 | 
						|
    }
 | 
						|
    
 | 
						|
ELEMENTFUNCTION = {}
 | 
						|
 | 
						|
for nsp in NAMESPACE_BASE:
 | 
						|
    for nskey, func in _MAP.items():
 | 
						|
        ELEMENTFUNCTION["{%s}%s" % (nsp, nskey)] = func
 | 
						|
 | 
						|
    
 | 
						|
def evaluate(typ, elem):
 | 
						|
    try:
 | 
						|
        return ELEMENTFUNCTION[typ](elem)
 | 
						|
    except KeyError:
 | 
						|
        print "Unknown type", typ
 | 
						|
        
 | 
						|
    
 | 
						|
NS_MAP = "xmlns_map"
 | 
						|
 | 
						|
def parse_nsmap(fil):
 | 
						|
    events = "start", "start-ns", "end-ns"
 | 
						|
 | 
						|
    root = None
 | 
						|
    ns_map = []
 | 
						|
 | 
						|
    for event, elem in ElementTree.iterparse(fil, events):
 | 
						|
        if event == "start-ns":
 | 
						|
            ns_map.append(elem)
 | 
						|
        elif event == "end-ns":
 | 
						|
            ns_map.pop()
 | 
						|
        elif event == "start":
 | 
						|
            if root is None:
 | 
						|
                root = elem
 | 
						|
            elem.set(NS_MAP, dict(ns_map))
 | 
						|
 | 
						|
    return ElementTree.ElementTree(root)
 | 
						|
 | 
						|
def usage():
 | 
						|
    print "Usage: parse_xsd [-i <module:as>] xsd.file > module.py"
 | 
						|
    
 | 
						|
def recursive_find_module(name, path=None):
 | 
						|
    parts = name.split(".")
 | 
						|
 | 
						|
    mod_a = None
 | 
						|
    for part in parts:
 | 
						|
        #print "$$", part, path
 | 
						|
        try:
 | 
						|
            (fil, pathname, desc) = imp.find_module(part, path)
 | 
						|
        except ImportError:
 | 
						|
            raise 
 | 
						|
 | 
						|
        mod_a = imp.load_module(name, fil, pathname, desc)
 | 
						|
        sys.modules[name] = mod_a
 | 
						|
        path = mod_a.__path__
 | 
						|
 | 
						|
    return mod_a
 | 
						|
 | 
						|
def get_mod(name, path=None):
 | 
						|
    try:
 | 
						|
        mod_a = sys.modules[name]
 | 
						|
        if not isinstance(mod_a, types.ModuleType):
 | 
						|
            raise KeyError
 | 
						|
    except KeyError:
 | 
						|
        try:
 | 
						|
            (fil, pathname, desc) = imp.find_module(name, path)
 | 
						|
            mod_a = imp.load_module(name, fil, pathname, desc)
 | 
						|
        except ImportError:
 | 
						|
            if "." in name:
 | 
						|
                mod_a = recursive_find_module(name, path)
 | 
						|
            else:
 | 
						|
                raise
 | 
						|
        sys.modules[name] = mod_a
 | 
						|
    return mod_a
 | 
						|
 | 
						|
 | 
						|
def recursive_add_xmlns_map(_sch, base):
 | 
						|
    for _part in _sch.parts:
 | 
						|
        _part.xmlns_map.update(base.xmlns_map)
 | 
						|
        if isinstance(_part, Complex):
 | 
						|
            recursive_add_xmlns_map(_part, base)
 | 
						|
 | 
						|
def find_and_replace(base, mods):
 | 
						|
    base.xmlns_map = mods.xmlns_map
 | 
						|
    recursive_add_xmlns_map(base, mods)
 | 
						|
    rm = []
 | 
						|
    for part in mods.parts:
 | 
						|
        try:
 | 
						|
            _name = part.name
 | 
						|
        except AttributeError:
 | 
						|
            continue
 | 
						|
        for _part in base.parts:
 | 
						|
            try:
 | 
						|
                if _name == _part.name:
 | 
						|
                    rm.append(_part)
 | 
						|
            except AttributeError:
 | 
						|
                continue
 | 
						|
    for part in rm:
 | 
						|
        base.parts.remove(part)
 | 
						|
    base.parts.extend(mods.parts)
 | 
						|
    return base
 | 
						|
 | 
						|
def read_schema(doc, add, defs, impo, modul, ignore, sdir):
 | 
						|
    for path in sdir:
 | 
						|
        fil = "%s%s" % (path, doc)
 | 
						|
        try:
 | 
						|
            fp = open(fil)
 | 
						|
            fp.close()
 | 
						|
            break
 | 
						|
        except IOError as e:
 | 
						|
            if e.errno == errno.EACCES:
 | 
						|
                continue
 | 
						|
    else:
 | 
						|
        raise Exception("Could not find schema file")
 | 
						|
 | 
						|
    tree = parse_nsmap(fil)
 | 
						|
 | 
						|
    known = NAMESPACE_BASE[:]
 | 
						|
    known.append(XML_NAMESPACE)
 | 
						|
    for key, namespace in tree._root.attrib["xmlns_map"].items():
 | 
						|
        if namespace in known:
 | 
						|
            continue
 | 
						|
        else:
 | 
						|
            try:
 | 
						|
                modul[key] = modul[namespace]
 | 
						|
                impo[namespace][1] = key
 | 
						|
            except KeyError:
 | 
						|
                if namespace == tree._root.attrib["targetNamespace"]:
 | 
						|
                    continue
 | 
						|
                elif namespace in ignore:
 | 
						|
                    continue
 | 
						|
                else:
 | 
						|
                    raise Exception("Undefined namespace: %s" % namespace)
 | 
						|
 | 
						|
    _schema =  Schema(tree._root, impo, add, modul, defs)
 | 
						|
    _included_parts = []
 | 
						|
    _remove_parts = []
 | 
						|
    _replace = []
 | 
						|
    for part in _schema.parts:
 | 
						|
        if isinstance(part, Include):
 | 
						|
            _sch = read_schema(part.schemaLocation, add, defs, impo, modul,
 | 
						|
                               ignore, sdir)
 | 
						|
            # Add namespace information
 | 
						|
            recursive_add_xmlns_map(_sch, _schema)
 | 
						|
            _included_parts.extend(_sch.parts)
 | 
						|
            _remove_parts.append(part)
 | 
						|
        elif isinstance(part, Redefine):
 | 
						|
            # This is the schema that is going to be redefined
 | 
						|
            _redef = read_schema(part.schemaLocation, add, defs, impo, modul,
 | 
						|
                                 ignore, sdir)
 | 
						|
            # so find and replace
 | 
						|
            # Use the schema to be redefined as starting point
 | 
						|
            _replacement = find_and_replace(_redef, part)
 | 
						|
            _replace.append((part, _replacement.parts))
 | 
						|
 | 
						|
    for part in _remove_parts:
 | 
						|
        _schema.parts.remove(part)
 | 
						|
    _schema.parts.extend(_included_parts)
 | 
						|
    if _replace:
 | 
						|
        for vad, med in _replace:
 | 
						|
            _schema.parts.remove(vad)
 | 
						|
            _schema.parts.extend(med)
 | 
						|
    return _schema
 | 
						|
 | 
						|
def main(argv):
 | 
						|
    try:
 | 
						|
        opts, args = getopt.getopt(argv, "a:d:hi:I:s:",
 | 
						|
                                    ["add=", "help", "import=", "defs="])
 | 
						|
    except getopt.GetoptError, err:
 | 
						|
        # print help information and exit:
 | 
						|
        print str(err) # will print something like "option -a not recognized"
 | 
						|
        usage()
 | 
						|
        sys.exit(2)
 | 
						|
 | 
						|
    add = []
 | 
						|
    defs = []
 | 
						|
    impo = {}
 | 
						|
    modul = {}
 | 
						|
    ignore = []
 | 
						|
    sdir = ["./"]
 | 
						|
 | 
						|
    for opt, arg in opts:
 | 
						|
        if opt in ("-a", "--add"):
 | 
						|
            add.append(arg)
 | 
						|
        elif opt in ("-d", "--defs"):
 | 
						|
            defs.append(arg)
 | 
						|
        elif opt in ("-h", "--help"):
 | 
						|
            usage()
 | 
						|
            sys.exit()
 | 
						|
        elif opt in ("-s", "--schemadir"):
 | 
						|
            sdir.append(arg)
 | 
						|
        elif opt in ("-i", "--import"):
 | 
						|
            mod = get_mod(arg, ['.'])
 | 
						|
            modul[mod.NAMESPACE] = mod
 | 
						|
            impo[mod.NAMESPACE] = [arg, None]
 | 
						|
        elif opt in ("-I", "--ignore"):
 | 
						|
            ignore.append(arg)
 | 
						|
        else:
 | 
						|
            assert False, "unhandled option"
 | 
						|
 | 
						|
    if not args:
 | 
						|
        print "No XSD-file specified"
 | 
						|
        usage()
 | 
						|
        sys.exit(2)
 | 
						|
 | 
						|
    schema = read_schema(args[0], add, defs, impo, modul, ignore, sdir)
 | 
						|
    #print schema.__dict__
 | 
						|
    schema.out()
 | 
						|
 | 
						|
if __name__ == "__main__":    
 | 
						|
    main(sys.argv[1:])
 |