|
From: <bov...@us...> - 2006-10-19 22:31:20
|
Revision: 1270
http://svn.sourceforge.net/pywebsvcs/?rev=1270&view=rev
Author: boverhof
Date: 2006-10-19 15:31:07 -0700 (Thu, 19 Oct 2006)
Log Message:
-----------
M test/test_t8.py
M ZSI/__init__.py
A ZSI/schema.py
M ZSI/generate/containers.py
M ZSI/TC.py
M ZSI/TCcompound.py
M ZSI/writer.py
M ZSI/address.py
-- Moved all schema instance stuff into a new module "schema",
Modified Paths:
--------------
trunk/zsi/ZSI/TC.py
trunk/zsi/ZSI/TCcompound.py
trunk/zsi/ZSI/__init__.py
trunk/zsi/ZSI/address.py
trunk/zsi/ZSI/generate/containers.py
trunk/zsi/ZSI/writer.py
trunk/zsi/test/test_t8.py
Added Paths:
-----------
trunk/zsi/ZSI/schema.py
Modified: trunk/zsi/ZSI/TC.py
===================================================================
--- trunk/zsi/ZSI/TC.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/ZSI/TC.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -10,7 +10,7 @@
_find_xmlns_prefix, _get_element_nsuri_name, _get_idstr, \
_Node, EvaluateException, \
_valid_encoding, ParseException
-
+
from ZSI.wstools.Namespaces import SCHEMA, SOAP
from ZSI.wstools.Utility import SplitQName
from ZSI.wstools.c14n import Canonicalize
@@ -22,13 +22,14 @@
from urllib import unquote as urldecode, quote as urlencode
from binascii import unhexlify as hexdecode, hexlify as hexencode
-UNBOUNDED = 'unbounded'
_is_xsd_or_soap_ns = lambda ns: ns in [
SCHEMA.XSD3, SOAP.ENC, SCHEMA.XSD1, SCHEMA.XSD2, ]
_find_nil = lambda E: _find_xsi_attr(E, "null") or _find_xsi_attr(E, "nil")
def _get_xsitype(pyclass):
+ '''returns the xsi:type as a tuple, coupled with ZSI.schema
+ '''
if hasattr(pyclass,'type') and type(pyclass.type) in _seqtypes:
return pyclass.type
elif hasattr(pyclass,'type') and hasattr(pyclass, 'schema'):
@@ -36,168 +37,12 @@
return (None,None)
-def _get_type_definition(namespaceURI, name, **kw):
- return SchemaInstanceType.getTypeDefinition(namespaceURI, name, **kw)
-def _get_global_element_declaration(namespaceURI, name, **kw):
- return SchemaInstanceType.getElementDeclaration(namespaceURI, name, **kw)
+# value returned when xsi:nil="true"
+Nilled = None
+UNBOUNDED = 'unbounded'
-def _get_substitute_element(elt, what):
- raise NotImplementedError, 'Not implemented'
-def _has_type_definition(namespaceURI, name):
- return SchemaInstanceType.getTypeDefinition(namespaceURI, name) is not None
-
-
-#
-# functions for retrieving schema items from
-# the global schema instance.
-#
-GED = _get_global_element_declaration
-GTD = _get_type_definition
-
-
-class SchemaInstanceType(type):
- '''Register all types/elements, when hit already defined
- class dont create a new one just give back reference. Thus
- import order determines which class is loaded.
-
- class variables:
- types -- dict of typecode classes definitions
- representing global type definitions.
- elements -- dict of typecode classes representing
- global element declarations.
- element_typecode_cache -- dict of typecode instances
- representing global element declarations.
- '''
- types = {}
- elements = {}
- element_typecode_cache = {}
-
- def __new__(cls,classname,bases,classdict):
- '''If classdict has literal and schema register it as a
- element declaration, else if has type and schema register
- it as a type definition.
- '''
- if classname in ['ElementDeclaration', 'TypeDefinition']:
- return type.__new__(cls,classname,bases,classdict)
-
- if ElementDeclaration in bases:
- if classdict.has_key('schema') is False or classdict.has_key('literal') is False:
- raise AttributeError, 'ElementDeclaration must define schema and literal attributes'
-
- key = (classdict['schema'],classdict['literal'])
- if SchemaInstanceType.elements.has_key(key) is False:
- SchemaInstanceType.elements[key] = type.__new__(cls,classname,bases,classdict)
- return SchemaInstanceType.elements[key]
-
- if TypeDefinition in bases:
- if classdict.has_key('type') is None:
- raise AttributeError, 'TypeDefinition must define type attribute'
-
- key = classdict['type']
- if SchemaInstanceType.types.has_key(key) is False:
- SchemaInstanceType.types[key] = type.__new__(cls,classname,bases,classdict)
- return SchemaInstanceType.types[key]
-
- raise TypeError, 'SchemaInstanceType must be an ElementDeclaration or TypeDefinition '
-
- def getTypeDefinition(cls, namespaceURI, name, lazy=False):
- '''Grab a type definition, returns a typecode class definition
- because the facets (name, minOccurs, maxOccurs) must be provided.
-
- Parameters:
- namespaceURI --
- name --
- '''
- klass = cls.types.get((namespaceURI, name), None)
- if lazy and klass is not None:
- return _Mirage(klass)
- return klass
- getTypeDefinition = classmethod(getTypeDefinition)
-
- def getElementDeclaration(cls, namespaceURI, name, isref=False, lazy=False):
- '''Grab an element declaration, returns a typecode instance
- representation or a typecode class definition. An element
- reference has its own facets, and is local so it will not be
- cached.
-
- Parameters:
- namespaceURI --
- name --
- isref -- if element reference, return class definition.
- '''
- key = (namespaceURI, name)
- if isref:
- klass = cls.elements.get(key,None)
- if klass is not None and lazy is True:
- return _Mirage(klass)
- return klass
-
- typecode = cls.element_typecode_cache.get(key, None)
- if typecode is None:
- tcls = cls.elements.get(key,None)
- if tcls is not None:
- typecode = cls.element_typecode_cache[key] = tcls()
- typecode.typed = False
-
- return typecode
- getElementDeclaration = classmethod(getElementDeclaration)
-
-
-class ElementDeclaration:
- '''Typecodes subclass to represent a Global Element Declaration by
- setting class variables schema and literal.
-
- schema = namespaceURI
- literal = NCName
- '''
- __metaclass__ = SchemaInstanceType
-
-
-class TypeDefinition:
- '''Typecodes subclass to represent a Global Type Definition by
- setting class variable type.
-
- type = (namespaceURI, NCName)
- '''
- __metaclass__ = SchemaInstanceType
-
- def getSubstituteType(self, elt, ps):
- '''if xsi:type does not match the instance type attr,
- check to see if it is a derived type substitution.
-
- DONT Return the element's type.
-
- Parameters:
- elt -- the DOM element being parsed
- ps -- the ParsedSoap object.
- '''
- pyclass = SchemaInstanceType.getTypeDefinition(*self.type)
- if pyclass is None:
- raise EvaluateException(
- 'No Type registed for xsi:type=(%s, %s)' %
- (self.type[0], self.type[1]), ps.Backtrace(elt))
-
- typeName = _find_type(elt)
- prefix,typeName = SplitQName(typeName)
- uri = ps.GetElementNSdict(elt).get(prefix)
- subclass = SchemaInstanceType.getTypeDefinition(uri, typeName)
- if subclass is None:
- raise EvaluateException(
- 'No registered xsi:type=(%s, %s), substitute for xsi:type=(%s, %s)' %
- (uri, typeName, self.type[0], self.type[1]), ps.Backtrace(elt))
-
- if not issubclass(subclass, pyclass) and subclass(None) and not issubclass(subclass, pyclass):
- raise TypeError(
- 'Substitute Type (%s, %s) is not derived from %s' %
- (self.type[0], self.type[1], pyclass), ps.Backtrace(elt))
-
- return subclass((self.nspname, self.pname))
-
-
-Nilled = None
-
class TypeCode:
'''The parent class for all parseable SOAP types.
Class data:
@@ -1482,14 +1327,6 @@
return
# Namespace if element AnyType was namespaced.
-# if self.nspname != what.nspname:
-# what.nspname = self.nspname
-#
-# if self.pname != what.pname:
-# raise EvaluateException, \
-# 'element name of typecode(%s) must match element name of AnyType(%s)' \
-# %(what.pname,self.pname)
-
what.serialize(elt, sw, pyobj,
name=(self.nspname or what.nspname, self.pname or what.pname), **kw)
@@ -1503,7 +1340,7 @@
#locate xsi:type
prefix, typeName = SplitQName(_find_type(elt))
namespaceURI = _resolve_prefix(elt, prefix)
- pyclass = _get_type_definition(namespaceURI, typeName)
+ pyclass = GTD(namespaceURI, typeName)
if not pyclass:
if _is_xsd_or_soap_ns(namespaceURI):
pyclass = _AnyStrict
@@ -1577,14 +1414,14 @@
'''
skip = self.processContents == 'skip'
nspname,pname = _get_element_nsuri_name(elt)
- what = _get_global_element_declaration(nspname, pname)
+ what = GED(nspname, pname)
if not skip and what is not None:
pyobj = what.parse(elt, ps)
try:
pyobj.typecode = what
except AttributeError, ex:
# Assume this means builtin type.
- pyobj = _GetPyobjWrapper.Wrap(pyobj, what)
+ pyobj = WrapImmutable(pyobj, what)
return pyobj
# Allow use of "<any>" element declarations w/ local
@@ -1594,14 +1431,14 @@
namespaceURI = _resolve_prefix(elt, prefix or 'xmlns')
# First look thru user defined namespaces, if don't find
# look for 'primitives'.
- pyclass = _get_type_definition(namespaceURI, typeName) or Any
+ pyclass = GTD(namespaceURI, typeName) or Any
what = pyclass(pname=(nspname,pname))
pyobj = what.parse(elt, ps)
try:
pyobj.typecode = what
except AttributeError, ex:
# Assume this means builtin type.
- pyobj = Wrap(pyobj, what)
+ pyobj = WrapImmutable(pyobj, what)
what.typed = True
return pyobj
@@ -1619,7 +1456,7 @@
self.logger.error("Give up, parse (%s,%s) as a String",
what.nspname, what.pname)
what = String(pname=(nspname,pname), typed=False)
- pyobj = Wrap(what.parse(elt, ps), what)
+ pyobj = WrapImmutable(what.parse(elt, ps), what)
return pyobj
@@ -1643,7 +1480,7 @@
if self.__class__.memberTypes is None:
raise EvaluateException, 'uninitialized class variable memberTypes [(namespace,name),]'
for nsuri,name in self.__class__.memberTypes:
- tcclass = _get_type_definition(nsuri,name)
+ tcclass = GTD(nsuri,name)
if tcclass is None:
tc = Any.parsemap.get((nsuri,name))
typecode = tc.__class__(pname=(self.nspname,self.pname))
@@ -1734,7 +1571,7 @@
if type(self.itemTypeCode) in _seqtypes:
namespaceURI,name = self.itemTypeCode
try:
- itemTypeCode = _get_type_definition(*self.itemType)(None)
+ itemTypeCode = GTD(*self.itemType)(None)
except:
if _is_xsd_or_soap_ns(namespaceURI) is False:
raise
@@ -1926,150 +1763,6 @@
return self.checktype(elt, ps)
-class _Mirage:
- '''Used with SchemaInstanceType for lazy evaluation, eval during serialize or
- parse as needed. Mirage is callable, TypeCodes are not. When called it returns the
- typecode. Tightly coupled with generated code.
-
- NOTE: **Must Use ClassType** for intended MRO of __call__ since setting it in
- an instance attribute rather than a class attribute (will not work for object).
- '''
- def __init__(self, klass):
- self.klass = klass
- self.__reveal = False
- self.__cache = None
- if issubclass(klass, ElementDeclaration):
- self.__call__ = self._hide_element
-
- def __str__(self):
- msg = "<Mirage id=%s, Local Element %s>"
- if issubclass(self.klass, ElementDeclaration):
- msg = "<Mirage id=%s, GED %s>"
- return msg %(id(self), self.klass)
-
- def _hide_type(self, pname, aname, minOccurs=0, maxOccurs=1, nillable=False,
- **kw):
- self.__call__ = self._reveal_type
- self.__reveal = True
-
- # store all attributes, make some visable for pyclass_type
- self.__kw = kw
- self.minOccurs,self.maxOccurs,self.nillable = minOccurs,maxOccurs,nillable
- self.nspname,self.pname,self.aname = None,pname,aname
- if type(self.pname) in (tuple,list):
- self.nspname,self.pname = pname
-
- return self
-
- def _hide_element(self, minOccurs=0, maxOccurs=1, nillable=False, **kw):
- self.__call__ = self._reveal_element
- self.__reveal = True
-
- # store all attributes, make some visable for pyclass_type
- self.__kw = kw
- self.nspname = self.klass.schema
- self.pname = self.klass.literal
- #TODO: Fix hack
- #self.aname = '_%s' %self.pname
- self.minOccurs,self.maxOccurs,self.nillable = minOccurs,maxOccurs,nillable
-
- return self
-
- def _reveal_type(self):
- if self.__cache is None:
- self.__cache = self.klass(pname=self.pname,
- aname=self.aname, minOccurs=self.minOccurs,
- maxOccurs=self.maxOccurs, nillable=self.nillable,
- **self.__kw)
- return self.__cache
-
- def _reveal_element(self):
- if self.__cache is None:
- self.__cache = self.klass(minOccurs=self.minOccurs,
- maxOccurs=self.maxOccurs, nillable=self.nillable,
- **self.__kw)
- return self.__cache
-
- __call__ = _hide_type
-
-
-class _GetPyobjWrapper:
- '''Get a python object that wraps data and typecode. Used by
- <any> parse routine, so that typecode information discovered
- during parsing is retained in the pyobj representation
- and thus can be serialized.
- '''
- types_dict = {}
-
- def RegisterBuiltin(cls, arg):
- '''register a builtin, create a new wrapper.
- '''
- if arg in cls.types_dict:
- raise RuntimeError, '%s already registered' %arg
- class _Wrapper(arg):
- 'Wrapper for builtin %s\n%s' %(arg, cls.__doc__)
- _Wrapper.__name__ = '_%sWrapper' %arg
- cls.types_dict[arg] = _Wrapper
- RegisterBuiltin = classmethod(RegisterBuiltin)
-
- def RegisterAnyElement(cls):
- '''clobber all existing entries in Any serialmap,
- replace with Wrapper classes.
- '''
- for k,v in cls.types_dict.items():
- what = Any.serialmap.get(k)
- if what is None: continue
- if v in what.__class__.seriallist: continue
- what.__class__.seriallist.append(v)
- RegisterType(what.__class__, clobber=1)
- RegisterAnyElement = classmethod(RegisterAnyElement)
-
- def Wrap(cls, pyobj, what):
- '''return a wrapper for pyobj, with typecode attribute set.
- Parameters:
- pyobj -- instance of builtin type (immutable)
- what -- typecode describing the data
- '''
- d = cls.types_dict
- if type(pyobj) is bool:
- pyclass = d[int]
- elif d.has_key(type(pyobj)) is True:
- pyclass = d[type(pyobj)]
- else:
- raise TypeError,\
- 'Expecting a built-in type in %s (got %s).' %(
- d.keys(),type(pyobj))
-
- newobj = pyclass(pyobj)
- newobj.typecode = what
- return newobj
- Wrap = classmethod(Wrap)
-
-
-def Wrap(pyobj, what):
- '''Wrap immutable instance so a typecode can be
- set, making it self-describing ie. serializable.
- '''
- return _GetPyobjWrapper.Wrap(pyobj, what)
-
-
-def RegisterBuiltin(arg):
- '''Add a builtin to be registered, and register it
- with the Any typecode.
- '''
- _GetPyobjWrapper.RegisterBuiltin(arg)
- _GetPyobjWrapper.RegisterAnyElement()
-
-
-def RegisterAnyElement():
- '''register all Wrapper classes with the Any typecode.
- This allows instances returned by Any to be self-describing.
- ie. serializable. AnyElement falls back on Any to parse
- anything it doesn't understand.
- '''
- return _GetPyobjWrapper.RegisterAnyElement()
-
-
def RegisterType(C, clobber=0, *args, **keywords):
instance = apply(C, args, keywords)
for t in C.__dict__.get('parselist', []):
@@ -2097,19 +1790,18 @@
Any.serialmap[key] = instance
-# Load up Wrappers for builtin types
-for i in [int,float,str,tuple,list,unicode]:
- _GetPyobjWrapper.RegisterBuiltin(i)
-
-
from TCnumbers import *
from TCtimes import *
+from schema import GTD, GED, WrapImmutable
from TCcompound import *
from TCapache import *
-
+# aliases backwards compatiblity
+_get_type_definition, _get_global_element_declaration, Wrap = GTD, GED, WrapImmutable
+
f = lambda x: type(x) == types.ClassType and issubclass(x, TypeCode) and getattr(x, 'type', None) is not None
TYPES = filter(f, map(lambda y:eval(y),dir()))
+
if __name__ == '__main__': print _copyright
Modified: trunk/zsi/ZSI/TCcompound.py
===================================================================
--- trunk/zsi/ZSI/TCcompound.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/ZSI/TCcompound.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -7,10 +7,14 @@
_inttypes, _stringtypes, _seqtypes, _find_arraytype, _find_href, \
_find_type, _find_xmlns_prefix, _get_idstr, EvaluateException, \
ParseException
-from ZSI.TC import _get_element_nsuri_name, \
- _get_substitute_element, _get_type_definition, _get_xsitype, \
- TypeCode, Any, AnyElement, AnyType, ElementDeclaration, TypeDefinition, \
- Nilled
+
+from TC import _get_element_nsuri_name, \
+ _get_xsitype, TypeCode, Any, AnyElement, AnyType, \
+ Nilled, UNBOUNDED
+
+from schema import ElementDeclaration, TypeDefinition, \
+ _get_substitute_element, _get_type_definition
+
from ZSI.wstools.Namespaces import SCHEMA, SOAP
from ZSI.wstools.Utility import SplitQName
from ZSI.wstools.logging import getLogger as _GetLogger
@@ -236,7 +240,7 @@
v[any.aname] = []
for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
value = any.parse(c_elt, ps)
- if any.maxOccurs == 'unbounded' or any.maxOccurs > 1:
+ if any.maxOccurs == UNBOUNDED or any.maxOccurs > 1:
v[any.aname].append(value)
else:
v[any.aname] = value
@@ -246,7 +250,7 @@
# No such thing as nillable <any>
if any.maxOccurs == 1 and occurs == 0:
v[any.aname] = None
- elif occurs < any.minOccurs or (any.maxOccurs!='unbounded' and any.maxOccurs<occurs):
+ elif occurs < any.minOccurs or (any.maxOccurs!=UNBOUNDED and any.maxOccurs<occurs):
raise EvaluateException('occurances of <any> elements(#%d) bound by (%d,%s)' %(
occurs, any.minOccurs,str(any.maxOccurs)), ps.Backtrace(elt))
@@ -667,5 +671,4 @@
position += 1
-
if __name__ == '__main__': print _copyright
Modified: trunk/zsi/ZSI/__init__.py
===================================================================
--- trunk/zsi/ZSI/__init__.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/ZSI/__init__.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -412,11 +412,22 @@
TC.RegisterType(TC.gDay, minOccurs=0, nillable=False)
TC.RegisterType(TC.gTime, minOccurs=0, nillable=False)
TC.RegisterType(TC.Apache.Map, minOccurs=0, nillable=False)
-TC.RegisterAnyElement()
-try:
- from ServiceProxy import *
-except:
- pass
+##
+## Register Wrappers for builtin types.
+## TC.AnyElement wraps builtins so element name information can be saved
+##
+import schema
+for i in [int,float,str,tuple,list,unicode]:
+ schema._GetPyobjWrapper.RegisterBuiltin(i)
+## Load up Wrappers for builtin types
+schema.RegisterAnyElement()
+
+
+#try:
+# from ServiceProxy import *
+#except:
+# pass
+
if __name__ == '__main__': print _copyright
Modified: trunk/zsi/ZSI/address.py
===================================================================
--- trunk/zsi/ZSI/address.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/ZSI/address.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -5,8 +5,8 @@
import time, urlparse, socket
from ZSI import _seqtypes, EvaluateException, WSActionException
-from ZSI.TC import _get_global_element_declaration as GED, _get_type_definition as GTD, \
- _has_type_definition, AnyElement, AnyType, TypeCode
+from TC import AnyElement, AnyType, TypeCode
+from schema import GED, GTD, _has_type_definition
from ZSI.TCcompound import ComplexType
from ZSI.wstools.Namespaces import WSA_LIST
Modified: trunk/zsi/ZSI/generate/containers.py
===================================================================
--- trunk/zsi/ZSI/generate/containers.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/ZSI/generate/containers.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -1047,8 +1047,7 @@
imports = [
'import ZSI',
'import ZSI.TCcompound',
- 'from ZSI.TC import ElementDeclaration,TypeDefinition',
- 'from ZSI.TC import _get_type_definition as GTD, _get_global_element_declaration as GED',
+ 'from ZSI.schema import LocalElementDeclaration, ElementDeclaration, TypeDefinition, GTD, GED',
]
logger = _GetLogger("TypesHeaderContainer")
Added: trunk/zsi/ZSI/schema.py
===================================================================
--- trunk/zsi/ZSI/schema.py (rev 0)
+++ trunk/zsi/ZSI/schema.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -0,0 +1,327 @@
+#! /usr/bin/env python
+# $Header$
+'''XML Schema support
+'''
+
+from ZSI import _copyright, _seqtypes, _find_type, EvaluateException
+from ZSI.wstools.Namespaces import SCHEMA, SOAP
+from ZSI.wstools.Utility import SplitQName
+
+
+def _get_type_definition(namespaceURI, name, **kw):
+ return SchemaInstanceType.getTypeDefinition(namespaceURI, name, **kw)
+
+def _get_global_element_declaration(namespaceURI, name, **kw):
+ return SchemaInstanceType.getElementDeclaration(namespaceURI, name, **kw)
+
+def _get_substitute_element(elt, what):
+ raise NotImplementedError, 'Not implemented'
+
+def _has_type_definition(namespaceURI, name):
+ return SchemaInstanceType.getTypeDefinition(namespaceURI, name) is not None
+
+
+#
+# functions for retrieving schema items from
+# the global schema instance.
+#
+GED = _get_global_element_declaration
+GTD = _get_type_definition
+
+
+def WrapImmutable(pyobj, what):
+ '''Wrap immutable instance so a typecode can be
+ set, making it self-describing ie. serializable.
+ '''
+ return _GetPyobjWrapper.WrapImmutable(pyobj, what)
+
+def RegisterBuiltin(arg):
+ '''Add a builtin to be registered, and register it
+ with the Any typecode.
+ '''
+ _GetPyobjWrapper.RegisterBuiltin(arg)
+ _GetPyobjWrapper.RegisterAnyElement()
+
+def RegisterAnyElement():
+ '''register all Wrapper classes with the Any typecode.
+ This allows instances returned by Any to be self-describing.
+ ie. serializable. AnyElement falls back on Any to parse
+ anything it doesn't understand.
+ '''
+ return _GetPyobjWrapper.RegisterAnyElement()
+
+
+class SchemaInstanceType(type):
+ '''Register all types/elements, when hit already defined
+ class dont create a new one just give back reference. Thus
+ import order determines which class is loaded.
+
+ class variables:
+ types -- dict of typecode classes definitions
+ representing global type definitions.
+ elements -- dict of typecode classes representing
+ global element declarations.
+ element_typecode_cache -- dict of typecode instances
+ representing global element declarations.
+ '''
+ types = {}
+ elements = {}
+ element_typecode_cache = {}
+
+ def __new__(cls,classname,bases,classdict):
+ '''If classdict has literal and schema register it as a
+ element declaration, else if has type and schema register
+ it as a type definition.
+ '''
+ if classname in ['ElementDeclaration', 'TypeDefinition', 'LocalElementDeclaration',]:
+ return type.__new__(cls,classname,bases,classdict)
+
+ if ElementDeclaration in bases:
+ if classdict.has_key('schema') is False or classdict.has_key('literal') is False:
+ raise AttributeError, 'ElementDeclaration must define schema and literal attributes'
+
+ key = (classdict['schema'],classdict['literal'])
+ if SchemaInstanceType.elements.has_key(key) is False:
+ SchemaInstanceType.elements[key] = type.__new__(cls,classname,bases,classdict)
+ return SchemaInstanceType.elements[key]
+
+ if TypeDefinition in bases:
+ if classdict.has_key('type') is None:
+ raise AttributeError, 'TypeDefinition must define type attribute'
+
+ key = classdict['type']
+ if SchemaInstanceType.types.has_key(key) is False:
+ SchemaInstanceType.types[key] = type.__new__(cls,classname,bases,classdict)
+ return SchemaInstanceType.types[key]
+
+ if LocalElementDeclaration in bases:
+ return type.__new__(cls,classname,bases,classdict)
+
+ raise TypeError, 'SchemaInstanceType must be an ElementDeclaration or TypeDefinition '
+
+ def getTypeDefinition(cls, namespaceURI, name, lazy=False):
+ '''Grab a type definition, returns a typecode class definition
+ because the facets (name, minOccurs, maxOccurs) must be provided.
+
+ Parameters:
+ namespaceURI --
+ name --
+ '''
+ klass = cls.types.get((namespaceURI, name), None)
+ if lazy and klass is not None:
+ return _Mirage(klass)
+ return klass
+ getTypeDefinition = classmethod(getTypeDefinition)
+
+ def getElementDeclaration(cls, namespaceURI, name, isref=False, lazy=False):
+ '''Grab an element declaration, returns a typecode instance
+ representation or a typecode class definition. An element
+ reference has its own facets, and is local so it will not be
+ cached.
+
+ Parameters:
+ namespaceURI --
+ name --
+ isref -- if element reference, return class definition.
+ '''
+ key = (namespaceURI, name)
+ if isref:
+ klass = cls.elements.get(key,None)
+ if klass is not None and lazy is True:
+ return _Mirage(klass)
+ return klass
+
+ typecode = cls.element_typecode_cache.get(key, None)
+ if typecode is None:
+ tcls = cls.elements.get(key,None)
+ if tcls is not None:
+ typecode = cls.element_typecode_cache[key] = tcls()
+ typecode.typed = False
+
+ return typecode
+ getElementDeclaration = classmethod(getElementDeclaration)
+
+
+class ElementDeclaration:
+ '''Typecodes subclass to represent a Global Element Declaration by
+ setting class variables schema and literal.
+
+ schema = namespaceURI
+ literal = NCName
+ '''
+ __metaclass__ = SchemaInstanceType
+
+
+class LocalElementDeclaration:
+ '''Typecodes subclass to represent a Local Element Declaration.
+ '''
+ __metaclass__ = SchemaInstanceType
+
+
+class TypeDefinition:
+ '''Typecodes subclass to represent a Global Type Definition by
+ setting class variable type.
+
+ type = (namespaceURI, NCName)
+ '''
+ __metaclass__ = SchemaInstanceType
+
+ def getSubstituteType(self, elt, ps):
+ '''if xsi:type does not match the instance type attr,
+ check to see if it is a derived type substitution.
+
+ DONT Return the element's type.
+
+ Parameters:
+ elt -- the DOM element being parsed
+ ps -- the ParsedSoap object.
+ '''
+ pyclass = SchemaInstanceType.getTypeDefinition(*self.type)
+ if pyclass is None:
+ raise EvaluateException(
+ 'No Type registed for xsi:type=(%s, %s)' %
+ (self.type[0], self.type[1]), ps.Backtrace(elt))
+
+ typeName = _find_type(elt)
+ prefix,typeName = SplitQName(typeName)
+ uri = ps.GetElementNSdict(elt).get(prefix)
+ subclass = SchemaInstanceType.getTypeDefinition(uri, typeName)
+ if subclass is None:
+ raise EvaluateException(
+ 'No registered xsi:type=(%s, %s), substitute for xsi:type=(%s, %s)' %
+ (uri, typeName, self.type[0], self.type[1]), ps.Backtrace(elt))
+
+ if not issubclass(subclass, pyclass) and subclass(None) and not issubclass(subclass, pyclass):
+ raise TypeError(
+ 'Substitute Type (%s, %s) is not derived from %s' %
+ (self.type[0], self.type[1], pyclass), ps.Backtrace(elt))
+
+ return subclass((self.nspname, self.pname))
+
+
+
+class _Mirage:
+ '''Used with SchemaInstanceType for lazy evaluation, eval during serialize or
+ parse as needed. Mirage is callable, TypeCodes are not. When called it returns the
+ typecode. Tightly coupled with generated code.
+
+ NOTE: **Must Use ClassType** for intended MRO of __call__ since setting it in
+ an instance attribute rather than a class attribute (will not work for object).
+ '''
+ def __init__(self, klass):
+ self.klass = klass
+ self.__reveal = False
+ self.__cache = None
+ if issubclass(klass, ElementDeclaration):
+ self.__call__ = self._hide_element
+
+ def __str__(self):
+ msg = "<Mirage id=%s, Local Element %s>"
+ if issubclass(self.klass, ElementDeclaration):
+ msg = "<Mirage id=%s, GED %s>"
+ return msg %(id(self), self.klass)
+
+ def _hide_type(self, pname, aname, minOccurs=0, maxOccurs=1, nillable=False,
+ **kw):
+ self.__call__ = self._reveal_type
+ self.__reveal = True
+
+ # store all attributes, make some visable for pyclass_type
+ self.__kw = kw
+ self.minOccurs,self.maxOccurs,self.nillable = minOccurs,maxOccurs,nillable
+ self.nspname,self.pname,self.aname = None,pname,aname
+ if type(self.pname) in (tuple,list):
+ self.nspname,self.pname = pname
+
+ return self
+
+ def _hide_element(self, minOccurs=0, maxOccurs=1, nillable=False, **kw):
+ self.__call__ = self._reveal_element
+ self.__reveal = True
+
+ # store all attributes, make some visable for pyclass_type
+ self.__kw = kw
+ self.nspname = self.klass.schema
+ self.pname = self.klass.literal
+ #TODO: Fix hack
+ #self.aname = '_%s' %self.pname
+ self.minOccurs,self.maxOccurs,self.nillable = minOccurs,maxOccurs,nillable
+
+ return self
+
+ def _reveal_type(self):
+ if self.__cache is None:
+ self.__cache = self.klass(pname=self.pname,
+ aname=self.aname, minOccurs=self.minOccurs,
+ maxOccurs=self.maxOccurs, nillable=self.nillable,
+ **self.__kw)
+ return self.__cache
+
+ def _reveal_element(self):
+ if self.__cache is None:
+ self.__cache = self.klass(minOccurs=self.minOccurs,
+ maxOccurs=self.maxOccurs, nillable=self.nillable,
+ **self.__kw)
+ return self.__cache
+
+ __call__ = _hide_type
+
+
+class _GetPyobjWrapper:
+ '''Get a python object that wraps data and typecode. Used by
+ <any> parse routine, so that typecode information discovered
+ during parsing is retained in the pyobj representation
+ and thus can be serialized.
+ '''
+ types_dict = {}
+
+ def RegisterBuiltin(cls, arg):
+ '''register a builtin, create a new wrapper.
+ '''
+ if arg in cls.types_dict:
+ raise RuntimeError, '%s already registered' %arg
+ class _Wrapper(arg):
+ 'Wrapper for builtin %s\n%s' %(arg, cls.__doc__)
+ _Wrapper.__name__ = '_%sWrapper' %arg.__name__
+ cls.types_dict[arg] = _Wrapper
+ RegisterBuiltin = classmethod(RegisterBuiltin)
+
+ def RegisterAnyElement(cls):
+ '''If find registered TypeCode instance, add Wrapper class
+ to TypeCode class serialmap and Re-RegisterType. Provides
+ Any serialzation of any instances of the Wrapper.
+ '''
+ for k,v in cls.types_dict.items():
+ what = Any.serialmap.get(k)
+ if what is None: continue
+ if v in what.__class__.seriallist: continue
+ what.__class__.seriallist.append(v)
+ RegisterType(what.__class__, clobber=1, **what.__dict__)
+ RegisterAnyElement = classmethod(RegisterAnyElement)
+
+ def WrapImmutable(cls, pyobj, what):
+ '''return a wrapper for pyobj, with typecode attribute set.
+ Parameters:
+ pyobj -- instance of builtin type (immutable)
+ what -- typecode describing the data
+ '''
+ d = cls.types_dict
+ if type(pyobj) is bool:
+ pyclass = d[int]
+ elif d.has_key(type(pyobj)) is True:
+ pyclass = d[type(pyobj)]
+ else:
+ raise TypeError,\
+ 'Expecting a built-in type in %s (got %s).' %(
+ d.keys(),type(pyobj))
+
+ newobj = pyclass(pyobj)
+ newobj.typecode = what
+ return newobj
+ WrapImmutable = classmethod(WrapImmutable)
+
+
+from TC import Any, RegisterType
+
+if __name__ == '__main__': print _copyright
+
Modified: trunk/zsi/ZSI/writer.py
===================================================================
--- trunk/zsi/ZSI/writer.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/ZSI/writer.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -5,7 +5,6 @@
from ZSI import _copyright, _get_idstr, ZSI_SCHEMA_URI
from ZSI import _backtrace, _stringtypes, _seqtypes
-from ZSI.TC import AnyElement, TypeCode
from ZSI.wstools.Utility import MessageInterface, ElementProxy
from ZSI.wstools.Namespaces import XMLNS, SOAP, SCHEMA
from ZSI.wstools.c14n import Canonicalize
Modified: trunk/zsi/test/test_t8.py
===================================================================
--- trunk/zsi/test/test_t8.py 2006-10-18 22:55:32 UTC (rev 1269)
+++ trunk/zsi/test/test_t8.py 2006-10-19 22:31:07 UTC (rev 1270)
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-import unittest, sys
-from ZSI import *
+import unittest, sys, types, time
+from ZSI import TC, SoapWriter, ParsedSoap, EvaluateException
from ZSI.wstools.Namespaces import SCHEMA, SOAP
NSDICT = {'tns':'xmlns:tns="urn:a"',
@@ -39,7 +39,7 @@
sw.serialize(None, typecode=tc, typed=True)
soap = str(sw)
ps = ParsedSoap(soap)
- parsed = ps.Parse(Any())
+ parsed = ps.Parse(TC.Any())
self.assertEqual(None, parsed)
def check_parse_empty_string(self):
@@ -50,7 +50,7 @@
sw.serialize("", typecode=tc, typed=True)
soap = str(sw)
ps = ParsedSoap(soap)
- parsed = ps.Parse(Any())
+ parsed = ps.Parse(TC.Any())
self.assertEqual("", parsed)
def check_builtins(self):
@@ -59,10 +59,10 @@
orig = [myInt,myLong,myStr,myDate,myFloat]
sw = SoapWriter()
- sw.serialize(orig, typecode=Any(pname="builtins", aslist=True))
+ sw.serialize(orig, typecode=TC.Any(pname="builtins", aslist=True))
ps = ParsedSoap(str(sw))
- parsed = ps.Parse(Any())
+ parsed = ps.Parse(TC.Any())
self.assertEqual(len(orig), len(parsed))
self.assertEqual(myInt, parsed[0])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|