1 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 ; 38 import java.util.ArrayList ; 39 40 43 public class InstantiationConfig { 44 private static L10N L = new L10N(InstantiationConfig.class); 45 46 private String _value; 47 private Class _type; 48 49 private ArrayList <Object > _args = new ArrayList <Object >(); 50 51 private int _index; 52 53 56 public Class getType() 57 { 58 return _type; 59 } 60 61 64 public void addText(String value) 65 { 66 _value = value; 67 } 68 69 72 public void addArg(Object value) 73 { 74 _args.add(value); 75 } 76 77 80 @PostConstruct 81 public void init() 82 throws Exception 83 { 84 if (_value == null) 85 throw new ConfigException(L.l("An instantiation requires the class name.")); 86 87 parseSignature(); 88 } 89 90 93 public Object create() 94 throws Exception 95 { 96 Object []args = new Object [_args.size()]; 97 98 Class []paramTypes = new Class [args.length]; 99 100 for (int i = 0; i < _args.size(); i++) { 101 Object arg = _args.get(i); 102 103 args[i] = arg; 104 if (arg == null) 105 paramTypes[i] = Object .class; 106 else 107 paramTypes[i] = arg.getClass(); 108 } 109 110 Constructor 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 getConstructor(Class cl, Class []types) 120 { 121 Constructor []constructors = cl.getConstructors(); 122 123 for (int i = 0; i < constructors.length; i++) { 124 Class []args = constructors[i].getParameterTypes(); 125 126 if (args.length == types.length) 127 return constructors[i]; 128 } 129 130 return null; 131 } 132 133 136 private void parseSignature() 137 throws Exception 138 { 139 _index = 0; 140 141 String type = parseType(skipWhitespace(read())); 142 143 ClassLoader 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 198 private String 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 className = cb.toString(); 211 212 unread(ch); 213 214 return className; 215 } 216 217 220 private int skipWhitespace(int ch) 221 { 222 for (; Character.isWhitespace((char) ch); ch = read()) { 223 } 224 225 return ch; 226 } 227 228 231 private int read() 232 { 233 if (_index < _value.length()) 234 return _value.charAt(_index++); 235 else 236 return -1; 237 } 238 239 242 private void unread(int ch) 243 { 244 if (ch >= 0) 245 _index--; 246 } 247 } 248 249 | Popular Tags |