KickJava   Java API By Example, From Geeks To Geeks.

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


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.el.EL;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.util.L10N;
35
36 import javax.annotation.PostConstruct;
37 import javax.servlet.jsp.el.ELException JavaDoc;
38 import java.lang.reflect.Constructor JavaDoc;
39 import java.lang.reflect.InvocationTargetException JavaDoc;
40 import java.lang.reflect.Modifier JavaDoc;
41 import java.util.ArrayList JavaDoc;
42
43 /**
44  * Constructor for a function signature.
45  */

46 public class ResinType {
47   private final static L10N L = new L10N(ResinType.class);
48
49   private String JavaDoc _signature;
50   private String JavaDoc _className;
51   
52   private ArrayList JavaDoc<String JavaDoc> _args = new ArrayList JavaDoc<String JavaDoc>();
53
54   private int _index;
55
56   /**
57    * Returns the signature.
58    */

59   public String JavaDoc getSignature()
60   {
61     return _signature;
62   }
63
64   /**
65    * Returns the class name.
66    */

67   public String JavaDoc getClassName()
68   {
69     return _className;
70   }
71   
72   /**
73    * Adds the text value to the signature.
74    */

75   public void addText(String JavaDoc value)
76   {
77     _signature = value;
78   }
79
80   /**
81    * Initialize the signature.
82    */

83   @PostConstruct
84   public void init()
85     throws ConfigException
86   {
87     if (_signature == null)
88       throw new ConfigException(L.l("A Signature requires the method signature."));
89
90     parseSignature();
91   }
92
93   /**
94    * Creates the object.
95    */

96   public Object JavaDoc create(Class JavaDoc targetClass)
97     throws ClassNotFoundException JavaDoc,
98        InstantiationException JavaDoc,
99        IllegalAccessException JavaDoc,
100        ConfigException,
101        InvocationTargetException JavaDoc,
102        ELException JavaDoc
103   {
104     ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
105     
106     Class JavaDoc cl = Class.forName(_className, false, loader);
107
108     if (targetClass != null && ! (targetClass.isAssignableFrom(cl)))
109       throw new ConfigException(L.l("{0} is not assignable to {1}",
110                     targetClass.getName(), _className));
111     
112
113     Constructor JavaDoc constructor = getConstructor(cl);
114
115     if (constructor == null)
116       throw new ConfigException(L.l("Can't find a matching public constructor for '{0}'",
117                     _signature));
118
119     Object JavaDoc []args = new Object JavaDoc[_args.size()];
120
121     for (int i = 0; i < args.length; i++) {
122       String JavaDoc arg = _args.get(i);
123
124       args[i] = EL.evalObject(arg);
125     }
126
127     return constructor.newInstance(args);
128   }
129
130   private Constructor JavaDoc getConstructor(Class JavaDoc cl)
131   {
132     Constructor JavaDoc []cons = cl.getConstructors();
133
134     for (int i = 0; i < cons.length; i++) {
135       if (! Modifier.isPublic(cons[i].getModifiers()))
136     continue;
137       
138       if (cons[i].getParameterTypes().length == _args.size())
139     return cons[i];
140     }
141
142     return null;
143   }
144   
145
146   /**
147    * Parses the function signature.
148    */

149   private void parseSignature()
150     throws ConfigException
151   {
152     _index = 0;
153
154     _className = parseType(skipWhitespace(read()));
155
156     CharBuffer cb = CharBuffer.allocate();
157     int ch = skipWhitespace(read());
158
159     if (ch < 0)
160       return;
161     
162     if (ch != '(')
163       throw new ConfigException(L.l("constructor syntax is `className(arg1, ..., argn)' in `{0}'",
164                                         _signature));
165
166     ch = skipWhitespace(read());
167     while (ch > 0 && ch != ')') {
168       cb.clear();
169
170       while (ch > 0 && ch != ',' && ch != ')') {
171     cb.append((char) ch);
172     
173     if (ch == '\'' || ch == '"') {
174       int end = ch;
175
176       for (ch = read(); ch > 0 && ch != end; ch = read()) {
177         cb.append((char) ch);
178       }
179
180       if (ch > 0)
181         cb.append((char) ch);
182     }
183
184     ch = read();
185       }
186
187       _args.add(cb.toString());
188     }
189     
190     if (ch != ')')
191       throw new ConfigException(L.l("constructor syntax is `className(arg1, ..., argn)' in `{0}'",
192                                         _signature));
193
194     ch = skipWhitespace(read());
195     
196     if (ch > 0)
197       throw new ConfigException(L.l("constructor syntax is `className(arg1, ..., argn)' in `{0}'",
198                                         _signature));
199   }
200
201   /**
202    * Parses the type.
203    */

204   private String JavaDoc parseType(int ch)
205     throws ConfigException
206   {
207     CharBuffer cb = CharBuffer.allocate();
208
209     for (; Character.isJavaIdentifierPart((char) ch) || ch == '.'; ch = read())
210       cb.append((char) ch);
211
212     if (cb.length() == 0)
213       throw new ConfigException(L.l("unexpected empty type in `{0}'",
214                                          _signature));
215
216     while (true) {
217       for (; Character.isWhitespace((char) ch); ch = read()) {
218       }
219
220       if (ch == '[') {
221     ch = read();
222     
223     if (ch != ']')
224       throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'",
225                                         _signature));
226
227     cb.append("[]");
228
229     ch = read();
230       }
231       else
232     break;
233     }
234
235     
236
237     String JavaDoc className = cb.toString();
238
239     unread(ch);
240
241     return className;
242   }
243
244   /**
245    * Skips whitespace to get to the next valid value.
246    */

247   private int skipWhitespace(int ch)
248   {
249     for (; Character.isWhitespace((char) ch); ch = read()) {
250     }
251
252     return ch;
253   }
254
255   /**
256    * Reads the next character.
257    */

258   private int read()
259   {
260     if (_index < _signature.length())
261       return _signature.charAt(_index++);
262     else
263       return -1;
264   }
265
266   /**
267    * Unreads the last character.
268    */

269   private void unread(int ch)
270   {
271     if (ch >= 0)
272       _index--;
273   }
274 }
275
276
Popular Tags