KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > config > types > Signature


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.config.types;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.server.util.CauchoSystem;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.util.L10N;
35
36 import javax.annotation.PostConstruct;
37 import java.lang.reflect.Method JavaDoc;
38 import java.util.ArrayList JavaDoc;
39
40 /**
41  * Configuration for a function signature.
42  */

43 public class Signature {
44   private static L10N L = new L10N(Signature.class);
45
46   private String JavaDoc _signature;
47   private String JavaDoc _className;
48   private String JavaDoc _name;
49   private String JavaDoc []_parameterTypes;
50   private String JavaDoc _returnType;
51
52   private int _index;
53
54   public Signature()
55   {
56   }
57
58   public Signature(String JavaDoc sig)
59   {
60     addText(sig);
61     init();
62   }
63
64   /**
65    * Returns the signature.
66    */

67   public String JavaDoc getSignature()
68   {
69     return _signature;
70   }
71
72   /**
73    * Returns the method name.
74    */

75   public String JavaDoc getName()
76   {
77     return _name;
78   }
79
80   /**
81    * Returns the class name
82    */

83   public String JavaDoc getClassName()
84   {
85     return _className;
86   }
87
88   /**
89    * Returns the method.
90    */

91   public Method JavaDoc getMethod()
92   {
93     if (_className == null)
94       return null;
95
96     try {
97       Class JavaDoc cl = CauchoSystem.loadClass(_className);
98       if (cl == null)
99         return null;
100
101       Method JavaDoc []methods = cl.getMethods();
102       for (int i = 0; i < methods.length; i++) {
103         if (matches(methods[i])) {
104           return methods[i];
105         }
106       }
107     } catch (Exception JavaDoc e) {
108     }
109     
110     return null;
111   }
112
113   /**
114    * Returns the return type.
115    */

116   public String JavaDoc getReturnType()
117   {
118     return _returnType;
119   }
120   
121   /**
122    * Returns the method parameters. If null, then the parameters
123    * were not specified.
124    */

125   public String JavaDoc []getParameterTypes()
126   {
127     return _parameterTypes;
128   }
129   
130   /**
131    * Adds the text value to the signature.
132    */

133   public void addText(String JavaDoc value)
134   {
135     _signature = value;
136   }
137
138   /**
139    * Initialize the signature.
140    */

141   @PostConstruct
142   public void init()
143     throws ConfigException
144   {
145     if (_signature == null)
146       throw new ConfigException(L.l("A Signature requires the method signature."));
147
148     parseSignature();
149   }
150
151   /**
152    * Returns true if the method matches the signature.
153    */

154   public boolean matches(Method JavaDoc method)
155   {
156     if (! method.getName().equals(getName()))
157       return false;
158
159     Class JavaDoc []parameterTypes = method.getParameterTypes();
160     String JavaDoc []sigTypes = getParameterTypes();
161
162     if (parameterTypes.length != sigTypes.length)
163       return false;
164
165     for (int i = 0; i < parameterTypes.length; i++) {
166       String JavaDoc param = getName(parameterTypes[i]);
167
168       if (! param.equals(sigTypes[i]) &&
169           ! param.endsWith("." + sigTypes[i]))
170         return false;
171     }
172
173     return true;
174   }
175
176   private String JavaDoc getName(Class JavaDoc cl)
177   {
178     if (cl.isArray())
179       return getName(cl.getComponentType()) + "[]";
180     else
181       return cl.getName();
182   }
183
184   /**
185    * Parses the function signature.
186    */

187   private void parseSignature()
188     throws ConfigException
189   {
190     _index = 0;
191
192     _returnType = parseType(skipWhitespace(read()));
193
194     CharBuffer cb = CharBuffer.allocate();
195     int ch = skipWhitespace(read());
196
197     if (ch == '(' || ch < 0) {
198       _name = _returnType;
199       _returnType = null;
200     }
201     else {
202       for (; Character.isJavaIdentifierPart((char) ch) || ch == '.'; ch = read())
203         cb.append((char) ch);
204
205       if (cb.length() == 0)
206         throw new ConfigException(L.l("unexpected empty function name in `{0}'",
207                                       _signature));
208
209       _name = cb.toString();
210
211       int p = _name.lastIndexOf('.');
212       if (p > 0) {
213         _className = _name.substring(0, p);
214         _name = _name.substring(p + 1);
215       }
216
217       ch = skipWhitespace(ch);
218     }
219
220     if (ch != '(')
221       throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'",
222                                         _signature));
223
224     ArrayList JavaDoc<String JavaDoc> argList = new ArrayList JavaDoc<String JavaDoc>();
225     
226     ch = read();
227     while (Character.isJavaIdentifierPart((char) (ch = skipWhitespace(ch))) ||
228            ch == '.') {
229       String JavaDoc type = parseType(ch);
230
231       argList.add(type);
232
233       ch = skipWhitespace(read());
234
235       for (;
236        Character.isJavaIdentifierPart((char) ch) || ch == '.';
237        ch = read()) {
238       }
239       
240       if (ch == ',')
241         ch = read();
242     }
243
244     _parameterTypes = (String JavaDoc []) argList.toArray(new String JavaDoc[argList.size()]);
245
246     if (ch != ')')
247       throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'",
248                                         _signature));
249
250     ch = skipWhitespace(read());
251
252     if (ch != -1)
253       throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'",
254                                         _signature));
255   }
256
257   /**
258    * Parses the type.
259    */

260   private String JavaDoc parseType(int ch)
261     throws ConfigException
262   {
263     CharBuffer cb = CharBuffer.allocate();
264
265     for (; Character.isJavaIdentifierPart((char) ch) || ch == '.'; ch = read())
266       cb.append((char) ch);
267
268     if (cb.length() == 0)
269       throw new ConfigException(L.l("unexpected empty type in `{0}'",
270                                          _signature));
271
272     while (true) {
273       for (; Character.isWhitespace((char) ch); ch = read()) {
274       }
275
276       if (ch == '[') {
277     ch = read();
278     
279     if (ch != ']')
280       throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'",
281                                         _signature));
282
283     cb.append("[]");
284
285     ch = read();
286       }
287       else
288     break;
289     }
290
291     
292
293     String JavaDoc className = cb.toString();
294
295     unread(ch);
296
297     return className;
298   }
299
300   /**
301    * Skips whitespace to get to the next valid value.
302    */

303   private int skipWhitespace(int ch)
304   {
305     for (; Character.isWhitespace((char) ch); ch = read()) {
306     }
307
308     return ch;
309   }
310
311   /**
312    * Reads the next character.
313    */

314   private int read()
315   {
316     if (_index < _signature.length())
317       return _signature.charAt(_index++);
318     else
319       return -1;
320   }
321
322   /**
323    * Unreads the last character.
324    */

325   private void unread(int ch)
326   {
327     if (ch >= 0)
328       _index--;
329   }
330
331   public String JavaDoc toString()
332   {
333     return "Signature[" + _signature + "]";
334   }
335 }
336
337
Popular Tags