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 javax.servlet.jsp.el.ELException ; 38 import java.lang.reflect.Constructor ; 39 import java.lang.reflect.InvocationTargetException ; 40 import java.lang.reflect.Modifier ; 41 import java.util.ArrayList ; 42 43 46 public class ResinType { 47 private final static L10N L = new L10N(ResinType.class); 48 49 private String _signature; 50 private String _className; 51 52 private ArrayList <String > _args = new ArrayList <String >(); 53 54 private int _index; 55 56 59 public String getSignature() 60 { 61 return _signature; 62 } 63 64 67 public String getClassName() 68 { 69 return _className; 70 } 71 72 75 public void addText(String value) 76 { 77 _signature = value; 78 } 79 80 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 96 public Object create(Class targetClass) 97 throws ClassNotFoundException , 98 InstantiationException , 99 IllegalAccessException , 100 ConfigException, 101 InvocationTargetException , 102 ELException 103 { 104 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 105 106 Class 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 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 []args = new Object [_args.size()]; 120 121 for (int i = 0; i < args.length; i++) { 122 String arg = _args.get(i); 123 124 args[i] = EL.evalObject(arg); 125 } 126 127 return constructor.newInstance(args); 128 } 129 130 private Constructor getConstructor(Class cl) 131 { 132 Constructor []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 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 204 private String 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 className = cb.toString(); 238 239 unread(ch); 240 241 return className; 242 } 243 244 247 private int skipWhitespace(int ch) 248 { 249 for (; Character.isWhitespace((char) ch); ch = read()) { 250 } 251 252 return ch; 253 } 254 255 258 private int read() 259 { 260 if (_index < _signature.length()) 261 return _signature.charAt(_index++); 262 else 263 return -1; 264 } 265 266 269 private void unread(int ch) 270 { 271 if (ch >= 0) 272 _index--; 273 } 274 } 275 276 | Popular Tags |