poly.py :  » Web-Services » ZSI » ZSI-2.0 » samples » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Services » ZSI 
ZSI » ZSI 2.0 » samples » poly.py
#! /usr/bin/env python

from ZSI import *

"""Polymorphic containers using TC.Choice

Based on code and text from Dan Gunter <dkgunter@lbl.gov>.

The TC.Choice typecode can be used to create a polymorphic type for
a specified set of object types.  Here's how:
    1.  Define all your data classes (D1, D2, ...). If they derive from
        a common base class (Base), some feel you get "cleaner" code.
    2.  Create a typecode class (TC_D1, TC_D2, ...) for each data class.
    3.  Create a "base" typecode that uses TC.Choice to do the actual
        parsing and serializing.  Two versions are shown, below.
Then you can instantiate, e.g., an Array that can handle multiple
datatypes with: 
    TC.Array("base-class-name", TC_Base(), "MyArray") 
"""

class Base: pass
class D1(Base): pass
class D2(Base): pass

class TC_D1(TC.TypeCode): pass
class TC_D2(TC.TypeCode): pass
D1.typecode = TC_D1()
D2.typecode = TC_D2()

# A simple version of TC_Base that is "hardwired" with the types of
# objects it can handle.  We defer setting the choice attribute because
# with nested containers you could get too much recursion.
class TC_Base(TC.TypeCode):
    def parse(self, elt, ps):
        return self.choice.parse(elt, ps)[1]

    def serialize(self, sw, pyobj, **kw):
        if not isinstance(pyobj, Base):
            raise TypeError(str(pyobj.__class__) + " not in type hierarchy")
        if isinstance(pyobj, D1):
            self.choice.serialize(sw, ('D1', pyobj), **kw)
        elif isinstance(pyobj, D2):
            self.choice.serialize(sw, ('D2', pyobj), **kw)
        else:
            raise TypeError(str(pyobj.__class__) + " unknown type")
        return

    def __getattr__(self, attr):
        if attr == 'choice':
            choice = TC.Choice((D1.typecode, D2.typecode), 'Item')
            self.__dict__['choice'] = choice
            return choice
        raise AttributeError(attr)

## Another version that takes a dictionary that maps element names to
## the python class.

class TC_Polymorphic(TC.TypeCode):
    def __init__(self, name2class, pname=None, **kw):
        TC.TypeCode.__init__(self, pname, **kw)
        self.name2class = name2class

    def parse(self, elt, ps):
        return self.choice.parse(elt, ps)[1]

    def serialize(self, sw, pyobj, **kw):
        self.choice.serialize(sw,
            (self.class2name[pyobj.__class__], pyobj), **kw)

    def __getattr__(self, attr):
        if attr == 'choice':
            choice = TC.Choice(
                [getattr(v, 'typecode') for k,v in self.name2class.items()],
                'Item')
            self.__dict__['choice'] = choice
            return choice
        if attr == 'class2name':
            class2name = {}
            for k,v in self.name2class.items(): class2name[v] = k
            self.__dict__['class2name'] = class2name
            return class2name
        raise AttributeError(attr)

class P1: pass
class P2: pass
P1.typecode = TC.String('s')
P2.typecode = TC.Integer('i')
myTC = TC.Array("Base", TC_Polymorphic({'i': P2, 's': P1}))

test = '''<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body xmlns='test-uri'>
        <array SOAP-ENC:arrayType="Base">
            <i>34</i>
            <s>hello</s>
            <s>34</s>
            <i>12</i>
            <s>goodbye</s>
        </array>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>'''

ps = ParsedSoap(test)
a = myTC.parse(ps.body_root, ps)
print a

if 0:
    # XXX.  Does not work. :(
    b = [ P1(), P1(), P2(), P1() ]
    b[0].s = 'string'
    b[1].s = '34'
    b[2].i = 34
    b[3].s = 'adios'

    import sys
    sw = SoapWriter(sys.stdout)
    myTC.serialize(sw, b)
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.