KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.lang.reflect.Constructor JavaDoc;
38 import java.util.ArrayList JavaDoc;
39
40 /**
41  * Configuration for an instantiation
42  */

43 public class InstantiationConfig {
44   private static L10N L = new L10N(InstantiationConfig.class);
45
46   private String JavaDoc _value;
47   private Class JavaDoc _type;
48   
49   private ArrayList JavaDoc<Object JavaDoc> _args = new ArrayList JavaDoc<Object JavaDoc>();
50
51   private int _index;
52
53   /**
54    * Returns the type.
55    */

56   public Class JavaDoc getType()
57   {
58     return _type;
59   }
60   
61   /**
62    * Adds the text value to the signature.
63    */

64   public void addText(String JavaDoc value)
65   {
66     _value = value;
67   }
68
69   /**
70    * Adds an argument.
71    */

72   public void addArg(Object JavaDoc value)
73   {
74     _args.add(value);
75   }
76
77   /**
78    * Initialize the signature.
79    */

80   @PostConstruct
81   public void init()
82     throws Exception JavaDoc
83   {
84     if (_value == null)
85       throw new ConfigException(L.l("An instantiation requires the class name."));
86
87     parseSignature();
88   }
89
90   /**
91    * Instantiates the object.
92    */

93   public Object JavaDoc create()
94     throws Exception JavaDoc
95   {
96     Object JavaDoc []args = new Object JavaDoc[_args.size()];
97     
98     Class JavaDoc []paramTypes = new Class JavaDoc[args.length];
99
100     for (int i = 0; i < _args.size(); i++) {
101       Object JavaDoc arg = _args.get(i);
102
103       args[i] = arg;
104       if (arg == null)
105     paramTypes[i] = Object JavaDoc.class;
106       else
107     paramTypes[i] = arg.getClass();
108     }
109     
110     Constructor JavaDoc constructor = getConstructor(_type, paramTypes);
111
112     if (constructor == null)
113       throw new ConfigException(L.l("Can't find public constructor for `{0}'.",
114                     _type.getName()));
115
116     return constructor.newInstance(args);
117   }
118
119   private Constructor JavaDoc getConstructor(Class JavaDoc cl, Class JavaDoc []types)
120   {
121     Constructor JavaDoc []constructors = cl.getConstructors();
122
123     for (int i = 0; i < constructors.length; i++) {
124       Class JavaDoc []args = constructors[i].getParameterTypes();
125
126       if (args.length == types.length)
127     return constructors[i];
128     }
129
130     return null;
131   }
132
133   /**
134    * Parses the constructor.
135    */

136   private void parseSignature()
137     throws Exception JavaDoc
138   {
139     _index = 0;
140
141     String JavaDoc type = parseType(skipWhitespace(read()));
142
143     ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
144     
145     _type = Class.forName(type, false, loader);
146
147     int ch = skipWhitespace(read());
148
149     if (ch < 0)
150       return;
151
152     if (ch != '(')
153       throw new ConfigException(L.l("expected `(' in constructor `{0}'",
154                                       _value));
155
156     CharBuffer cb = CharBuffer.allocate();
157
158     ch = ',';
159     while (ch == ',') {
160       ch = skipWhitespace(read());
161
162       cb.clear();
163       
164       if (ch == '\'' || ch == '"') {
165     int end = ch;
166
167     for (ch = read(); ch > 0 && ch != end; ch = read()) {
168       if (ch == '\\')
169         cb.append(read());
170       else
171         cb.append((char) ch);
172     }
173
174     _args.add(cb.toString());
175       }
176       else if (ch == '$') {
177     ch = read();
178
179     if (ch != '{')
180       throw new ConfigException(L.l("expected EL-expression at $ in `{0}'",
181                     _value));
182
183     for (ch = read(); ch > 0 && ch != '}'; ch = read()) {
184       cb.append((char) ch);
185     }
186
187     _args.add(EL.evalObject(cb.toString()));
188       }
189       else
190     throw new ConfigException(L.l("expected string or EL-expression in `{0}'",
191                       _value));
192     }
193   }
194
195   /**
196    * Parses the type.
197    */

198   private String JavaDoc parseType(int ch)
199     throws ConfigException
200   {
201     CharBuffer cb = CharBuffer.allocate();
202
203     for (; Character.isJavaIdentifierPart((char) ch) || ch == '.'; ch = read())
204       cb.append((char) ch);
205
206     if (cb.length() == 0)
207       throw new ConfigException(L.l("unexpected empty type in `{0}'",
208                     _value));
209
210     String JavaDoc className = cb.toString();
211
212     unread(ch);
213
214     return className;
215   }
216
217   /**
218    * Skips whitespace to get to the next valid value.
219    */

220   private int skipWhitespace(int ch)
221   {
222     for (; Character.isWhitespace((char) ch); ch = read()) {
223     }
224
225     return ch;
226   }
227
228   /**
229    * Reads the next character.
230    */

231   private int read()
232   {
233     if (_index < _value.length())
234       return _value.charAt(_index++);
235     else
236       return -1;
237   }
238
239   /**
240    * Unreads the last character.
241    */

242   private void unread(int ch)
243   {
244     if (ch >= 0)
245       _index--;
246   }
247 }
248
249
Popular Tags