KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > core > ArgParser


1 package org.python.core;
2
3 /**
4  * A utility class for handling mixed positional and keyword arguments.
5  *
6  * A typical usage:
7  * <pre>
8  * public MatchObject search(PyObject[] args, String[] kws) {
9  * ArgParser ap = new ArgParser("search", args, kws,
10  * "pattern", "pos", "endpos");
11  * String string = ap.getString(0);
12  * int start = ap.getInt(1, 0);
13  * int end = ap.getInt(2, string.length());
14  * ...
15  * </pre>
16  */

17
18 public class ArgParser {
19     // The name of the function. Used in exception messages
20
private String JavaDoc funcname;
21
22     // The actual argument values.
23
private PyObject[] args;
24
25     // The list of actual keyword names.
26
private String JavaDoc[] kws;
27
28     // The list of allowed and expected keyword names.
29
private String JavaDoc[] params = null;
30
31     // A marker.
32
private static Object JavaDoc required = new Object JavaDoc();
33     private static String JavaDoc[] emptyKws = new String JavaDoc[0];
34
35     //private PyBuiltinFunction.Info info;
36

37     private ArgParser(String JavaDoc funcname, PyObject[] args, String JavaDoc[] kws) {
38         this.funcname = funcname;
39         this.args = args;
40         if (kws == null)
41             kws = emptyKws;
42         this.kws = kws;
43     }
44
45     /**
46      * Create an ArgParser with one method argument
47      * @param funcname Name of the method. Used in error messages.
48      * @param args The actual call arguments supplied in the call.
49      * @param kws The actual keyword names supplied in the call.
50      * @param p0 The expected argument in the method definition.
51      */

52     public ArgParser(String JavaDoc funcname, PyObject[] args, String JavaDoc[] kws,
53                      String JavaDoc p0) {
54         this(funcname, args, kws);
55         this.params = new String JavaDoc[] { p0 };
56         check();
57     }
58
59     /**
60      * Create an ArgParser with two method argument
61      * @param funcname Name of the method. Used in error messages.
62      * @param args The actual call arguments supplied in the call.
63      * @param kws The actual keyword names supplied in the call.
64      * @param p0 The first expected argument in the method
65                           definition.
66      * @param p1 The second expected argument in the method
67                           definition.
68      */

69     public ArgParser(String JavaDoc funcname, PyObject[] args, String JavaDoc[] kws,
70                      String JavaDoc p0, String JavaDoc p1) {
71         this(funcname, args, kws);
72         this.params = new String JavaDoc[] { p0, p1 };
73         check();
74     }
75
76     /**
77      * Create an ArgParser with three method argument
78      * @param funcname Name of the method. Used in error messages.
79      * @param args The actual call arguments supplied in the call.
80      * @param kws The actual keyword names supplied in the call.
81      * @param p0 The first expected argument in the method
82                           definition.
83      * @param p1 The second expected argument in the method
84                           definition.
85      * @param p2 The third expected argument in the method
86                           definition.
87      */

88     public ArgParser(String JavaDoc funcname, PyObject[] args, String JavaDoc[] kws,
89                      String JavaDoc p0, String JavaDoc p1, String JavaDoc p2) {
90         this(funcname, args, kws);
91         this.params = new String JavaDoc[] { p0, p1, p2 };
92         check();
93     }
94
95     /**
96      * Create an ArgParser with three method argument
97      * @param funcname Name of the method. Used in error messages.
98      * @param args The actual call arguments supplied in the call.
99      * @param kws The actual keyword names supplied in the call.
100      * @param paramnames The list of expected argument in the method
101                           definition.
102      */

103     public ArgParser(String JavaDoc funcname, PyObject[] args, String JavaDoc[] kws,
104                      String JavaDoc[] paramnames) {
105         this(funcname, args, kws);
106         this.params = paramnames;
107         check();
108     }
109
110     public ArgParser(String JavaDoc funcname, PyObject[] args, String JavaDoc[] kws,
111             String JavaDoc[] paramnames, int minargs) {
112         this(funcname, args, kws);
113         this.params = paramnames;
114         check();
115         if (!PyBuiltinFunction.DefaultInfo.check(args.length,minargs,this.params.length))
116             throw PyBuiltinFunction.DefaultInfo.unexpectedCall(args.length, false, funcname,
117                     minargs, this.params.length);
118     }
119
120
121     /**
122      * Return a required argument as a String.
123      * @param pos The position of the .. First argument is
124      * numbered 0.
125      */

126     public String JavaDoc getString(int pos) {
127          return (String JavaDoc) getArg(pos, String JavaDoc.class, "string");
128     }
129
130     /**
131      * Return an optional argument as a String.
132      * @param pos The position of the argument. First argument is
133      * numbered 0.
134      */

135     public String JavaDoc getString(int pos, String JavaDoc def) {
136          return (String JavaDoc) getArg(pos, String JavaDoc.class, "string", def);
137     }
138
139
140     /**
141      * Return a required argument as an int.
142      * @param pos The position of the argument. First argument is
143      * numbered 0.
144      */

145     public int getInt(int pos) {
146          return ((PyInteger)getRequiredArg(pos).__int__()).getValue();
147     }
148
149     /**
150      * Return an optional argument as an int.
151      * @param pos The position of the argument. First argument is
152      * numbered 0.
153      */

154     public int getInt(int pos, int def) {
155          PyObject value = getOptionalArg(pos);
156          if (value == null)
157              return def;
158          return ((PyInteger)value.__int__()).getValue();
159     }
160
161
162     /**
163      * Return a required argument as a PyObject.
164      * @param pos The position of the argument. First argument is
165      * numbered 0.
166      */

167     public PyObject getPyObject(int pos) {
168          return getRequiredArg(pos);
169     }
170
171     /**
172      * Return an optional argument as a PyObject.
173      * @param pos The position of the argument. First argument is
174      * numbered 0.
175      */

176     public PyObject getPyObject(int pos, PyObject def) {
177          PyObject value = getOptionalArg(pos);
178          if (value == null)
179              value = def;
180          return value;
181     }
182
183     /**
184      * Return the remaining arguments as a tuple.
185      * @param pos The position of the argument. First argument is
186      * numbered 0.
187      */

188     public PyObject getList(int pos) {
189         int kws_start = args.length - kws.length;
190         if (pos < kws_start) {
191             PyObject[] ret = new PyObject[kws_start - pos];
192             System.arraycopy(args, pos, ret, 0, kws_start - pos);
193             return new PyTuple(ret);
194         }
195         return Py.EmptyTuple;
196     }
197
198
199     private void check() {
200         int nargs = args.length - kws.length;
201         l1:
202         for (int i = 0; i < kws.length; i++) {
203             for (int j = 0; j < params.length; j++) {
204                 if (kws[i].equals(params[j])) {
205                     if (j < nargs) {
206                         throw Py.TypeError("keyword parameter '" + params[j] +
207                                 "' was given by position and by name");
208                     }
209                     continue l1;
210                 }
211             }
212             throw Py.TypeError("'" + kws[i] + "' is an invalid keyword " +
213                                "argument for this function");
214         }
215     }
216
217     private PyObject getRequiredArg(int pos) {
218         PyObject ret = getOptionalArg(pos);
219         if (ret == null)
220             throw Py.TypeError(funcname + ": The " + ordinal(pos) +
221                                " argument is required");
222         return ret;
223     }
224
225     private PyObject getOptionalArg(int pos) {
226         int kws_start = args.length - kws.length;
227         if (pos < kws_start)
228             return args[pos];
229         for (int i = 0; i < kws.length; i++) {
230             if (kws[i].equals(params[pos]))
231                 return args[kws_start + i];
232         }
233         return null;
234     }
235
236
237     private Object JavaDoc getArg(int pos, Class JavaDoc clss, String JavaDoc classname) {
238         return getArg(pos, clss, classname, required);
239     }
240
241     private Object JavaDoc getArg(int pos, Class JavaDoc clss, String JavaDoc classname, Object JavaDoc def) {
242         PyObject value = null;
243         if (def == required)
244             value = getRequiredArg(pos);
245         else {
246             value = getOptionalArg(pos);
247             if (value == null)
248                 return def;
249         }
250
251         Object JavaDoc ret = value.__tojava__(clss);
252         if (ret == Py.NoConversion)
253             throw Py.TypeError("argument " + (pos+1) + ": expected " +
254                                classname + ", " + Py.safeRepr(value) +
255                                " found");
256         return ret;
257     }
258
259
260     private static String JavaDoc ordinal(int n) {
261         switch(n+1) {
262         case 1:
263             return "1st";
264         case 2:
265             return "2nd";
266         case 3:
267             return "3rd";
268         default:
269             return Integer.toString(n+1)+"th";
270         }
271     }
272 }
273
Popular Tags