source: trunk/packages/xen-3.1/xen-3.1/tools/python/xen/xend/Args.py @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 5.2 KB
Line 
1#============================================================================
2# This library is free software; you can redistribute it and/or
3# modify it under the terms of version 2.1 of the GNU Lesser General Public
4# License as published by the Free Software Foundation.
5#
6# This library is distributed in the hope that it will be useful,
7# but WITHOUT ANY WARRANTY; without even the implied warranty of
8# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9# Lesser General Public License for more details.
10#
11# You should have received a copy of the GNU Lesser General Public
12# License along with this library; if not, write to the Free Software
13# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14#============================================================================
15# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16#============================================================================
17
18import types
19import StringIO
20
21from xen.xend import sxp
22
23class ArgError(StandardError):
24    pass
25
26class Args:
27    """Argument encoding support for HTTP.
28    """
29   
30    def __init__(self, paramspec, keyspec):
31        self.arg_ord = []
32        self.arg_dict = {}
33        self.key_ord = []
34        self.key_dict = {}
35        for (name, typ) in paramspec:
36                self.arg_ord.append(name)
37                self.arg_dict[name] = typ
38        for (name, typ) in keyspec:
39                self.key_ord.append(name)
40                self.key_dict[name] = typ
41
42    def get_args(self, d, xargs=None):
43        args = {}
44        keys = {}
45        params = []
46        if xargs:
47            self.split_args(xargs, args, keys)
48        self.split_args(d, args, keys)
49        for a in self.arg_ord:
50            if a in args:
51                params.append(args[a])
52            else:
53                raise ArgError('Missing parameter: %s' % a)
54        return (params, keys)
55
56    def split_args(self, d, args, keys):
57        for (k, v) in d.items():
58            if k in self.arg_dict:
59                typ = self.arg_dict[k]
60                val = self.coerce(typ, v)
61                args[k] = val
62            elif k in self.key_dict:
63                typ = self.key_dict[k]
64                val = self.coerce(typ, v)
65                keys[k] = val
66            else:
67                raise ArgError('Invalid parameter: %s' % k)
68
69    def get_form_args(self, f, xargs=None):
70        d = {}
71        for (k, v) in f.items():
72            if ((k not in self.arg_dict) and
73                (k not in self.key_dict)):
74                continue
75            if isinstance(v, types.ListType):
76                n = len(v)
77                if n == 0:
78                    continue
79                elif n == 1:
80                    val = v[0]
81                else:
82                    raise ArgError('Too many values for %s' % k)
83            else:
84                val = v
85            d[k] = val
86        return self.get_args(d, xargs=xargs)
87
88    def coerce(self, typ, v):
89        try:
90            if typ == 'int':
91                val = int(v)
92            elif typ == 'long':
93                val = long(v)
94            elif typ == 'str':
95                val = str(v)
96            elif typ == 'sxpr':
97                val = self.sxpr(v)
98            elif typ == 'bool':
99                val = self.bool(v)
100            else:
101                raise ArgError('invalid type:' + str(typ))
102            return val
103        except ArgError:
104            raise
105        except StandardError, ex:
106            raise ArgError(str(ex))
107
108    def bool(self, v):
109        return (v.lower() in ['on', 'yes', '1', 'true'])
110
111    def sxpr(self, v):
112        if isinstance(v, types.ListType):
113            val = v
114        elif isinstance(v, types.FileType) or hasattr(v, 'readline'):
115            val = self.sxpr_file(v)
116        elif isinstance(v, types.StringType):
117            val = self.sxpr_file(StringIO.StringIO(v))
118        else:
119            val = str(v)
120        return val
121
122    def sxpr_file(self, fin):
123        try:
124            vals = sxp.parse(fin)
125        except:
126            raise ArgError('Coercion to sxpr failed')
127        if len(vals) == 1:
128            return vals[0]
129        else:
130            raise ArgError('Too many sxprs')
131
132    def call_with_args(self, fn, args, xargs=None):
133        (params, keys) = self.get_args(args, xargs=xargs)
134        return fn(*params, **keys)
135
136    def call_with_form_args(self, fn, fargs, xargs=None):
137        (params, keys) = self.get_form_args(fargs, xargs=xargs)
138        return fn(*params, **keys)
139
140class ArgFn(Args):
141    """Represent a remote HTTP operation as a function.
142    Used on the client.
143    """
144
145    def __init__(self, fn, paramspec, keyspec = None):
146        if keyspec == None:
147            keyspec = {}
148        Args.__init__(self, paramspec, keyspec)
149        self.fn = fn
150
151    def __call__(self, fargs, xargs=None):
152        return self.call_with_args(self.fn, fargs, xargs=xargs)
153   
154class FormFn(Args):
155    """Represent an operation as a function over a form.
156    Used in the HTTP server.
157    """
158
159    def __init__(self, fn, paramspec, keyspec = None):
160        if keyspec == None:
161            keyspec = {}
162        Args.__init__(self, paramspec, keyspec)
163        self.fn = fn
164
165    def __call__(self, fargs, xargs=None):
166        return self.call_with_form_args(self.fn, fargs, xargs=xargs)
Note: See TracBrowser for help on using the repository browser.