1 29 30 package com.caucho.java.gen; 31 32 import com.caucho.java.JavaCompiler; 33 import com.caucho.java.JavaWriter; 34 import com.caucho.loader.DynamicClassLoader; 35 import com.caucho.loader.SimpleLoader; 36 import com.caucho.loader.enhancer.EnhancingClassLoader; 37 import com.caucho.server.util.CauchoSystem; 38 import com.caucho.util.CharBuffer; 39 import com.caucho.util.L10N; 40 import com.caucho.vfs.MergePath; 41 import com.caucho.vfs.Path; 42 import com.caucho.vfs.Vfs; 43 import com.caucho.vfs.WriteStream; 44 45 import java.io.IOException ; 46 import java.lang.reflect.Method ; 47 import java.util.ArrayList ; 48 import java.util.logging.Level ; 49 import java.util.logging.Logger ; 50 51 54 public class JavaClassGenerator { 55 private static final L10N L = new L10N(JavaClassGenerator.class); 56 private static final Logger log 57 = Logger.getLogger(JavaClassGenerator.class.getName()); 58 59 private ClassLoader _parentLoader; 61 private ClassLoader _loader; 63 64 private String _encoding; 65 66 private Path _searchPath; 68 69 private Path _workPath; 71 72 private ArrayList <String > _pendingFiles = new ArrayList <String >(); 73 74 private String _initMethod = "_caucho_init"; 75 private String _isModifiedMethod = "_caucho_is_modified"; 76 77 80 public static String cleanClassName(String className) 81 { 82 CharBuffer cb = new CharBuffer(); 83 84 for (int i = 0; i < className.length(); i++) { 85 char ch = className.charAt(i); 86 87 if (ch == '.' || ch == '/') 88 cb.append('.'); 89 else if (Character.isJavaIdentifierPart(ch)) 90 cb.append(ch); 91 else 92 cb.append('_'); 93 } 94 95 return cb.toString(); 96 } 97 98 101 public static Path getDefaultSearchPath() 102 { 103 MergePath mergePath = new MergePath(); 104 105 mergePath.addMergePath(Vfs.lookup()); 106 mergePath.addClassPath(); 107 108 return mergePath; 109 } 110 111 114 public void setSearchPath(Path path) 115 { 116 _searchPath = path; 117 } 118 119 122 public Path getSearchPath() 123 { 124 return _searchPath; 125 } 126 127 public void setEncoding(String encoding) 128 { 129 _encoding = encoding; 130 } 131 132 137 public void setParentLoader(ClassLoader loader) 138 { 139 if (loader instanceof EnhancingClassLoader) { 140 EnhancingClassLoader enhancingLoader = (EnhancingClassLoader) loader; 141 } 142 143 _parentLoader = loader; 144 } 145 146 151 public void setLoader(ClassLoader loader) 152 { 153 _loader = loader; 154 } 155 156 159 public ClassLoader getClassLoader() 160 { 161 return _loader; 162 170 } 171 172 177 public ClassLoader getParentLoader() 178 { 179 if (_parentLoader == null) 180 _parentLoader = Thread.currentThread().getContextClassLoader(); 181 182 return _parentLoader; 183 } 184 185 190 public ClassLoader getPreloadLoader() 191 { 192 return Thread.currentThread().getContextClassLoader(); 193 194 201 } 202 203 206 public void setWorkDir(Path workPath) 207 { 208 _workPath = workPath; 209 } 210 211 214 public Path getWorkDir() 215 { 216 if (_workPath == null) 217 return CauchoSystem.getWorkPath(); 218 else 219 return _workPath; 220 } 221 222 227 public Class preload(String fullClassName) 228 { 229 try { 230 return loadClass(fullClassName, true); 231 } catch (ClassNotFoundException e) { 232 log.log(Level.FINEST, e.toString(), e); 233 234 return null; 235 } 236 } 237 238 241 public void generate(GenClass javaClass) 242 throws Exception 243 { 244 String className = javaClass.getFullClassName(); 245 String javaPathName = className.replace('.', '/') + ".java"; 246 String classPathName = className.replace('.', '/') + ".class"; 247 248 Path javaPath = getWorkDir().lookup(javaPathName); 249 Path classPath = getWorkDir().lookup(classPathName); 250 251 try { 252 classPath.remove(); 253 } catch (IOException e) { 254 } 255 256 javaPath.getParent().mkdirs(); 257 258 WriteStream os = javaPath.openWrite(); 259 try { 260 if (_encoding != null) 261 os.setEncoding(_encoding); 262 263 JavaWriter out = new JavaWriter(os); 264 265 javaClass.generate(out); 266 } finally { 267 os.close(); 268 } 269 270 _pendingFiles.add(javaPathName); 271 } 272 273 public void addPendingFile(String javaPath) 274 { 275 _pendingFiles.add(javaPath); 276 } 277 278 281 public Class compile(String fullClassName) 282 throws Exception 283 { 284 compileJava(fullClassName); 285 286 return loadClass(fullClassName, false); 287 } 288 289 292 public void compileJava(String fullClassName) 293 throws IOException , ClassNotFoundException 294 { 295 JavaCompiler compiler = JavaCompiler.create(getPreloadLoader()); 296 297 compiler.setClassLoader(getPreloadLoader()); 298 compiler.setClassDir(getWorkDir()); 299 300 if (_encoding != null) 301 compiler.setEncoding(_encoding); 302 303 compiler.compile(fullClassName.replace('.', '/') + ".java", null); 304 } 305 306 309 public void compilePendingJava() 310 throws IOException , ClassNotFoundException 311 { 312 JavaCompiler compiler = JavaCompiler.create(getPreloadLoader()); 313 314 compiler.setClassLoader(getPreloadLoader()); 315 compiler.setClassDir(getWorkDir()); 316 317 if (_encoding != null) 318 compiler.setEncoding(_encoding); 319 320 String []files = new String [_pendingFiles.size()]; 321 _pendingFiles.toArray(files); 322 _pendingFiles.clear(); 323 324 compiler.compileBatch(files); 325 } 326 327 331 public Class loadClass(String fullClassName) 332 throws ClassNotFoundException 333 { 334 return loadClass(fullClassName, false); 335 } 336 337 341 public Class loadClass(String fullClassName, boolean preload) 342 throws ClassNotFoundException 343 { 344 DynamicClassLoader preloadLoader = null; 345 346 try { 347 ClassLoader loader; 348 349 if (preload) { 350 preloadLoader = SimpleLoader.create(getPreloadLoader(), 351 getWorkDir(), 352 fullClassName); 353 354 preloadLoader.setServletHack(true); 356 loader = preloadLoader; 357 } 358 else { 359 loader = getClassLoader(); 361 362 if (loader == null) { 363 loader = SimpleLoader.create(getParentLoader(), 364 getWorkDir(), 365 fullClassName); 366 } 367 } 368 369 Class cl = Class.forName(fullClassName, false, loader); 370 371 if (cl == null) 372 return null; 373 374 if (! preload) 375 return cl; 376 377 if (isModified(cl)) 378 return null; 379 380 if (_loader != null) 381 loader = _loader; 382 else { 383 loader = SimpleLoader.create(getParentLoader(), 384 getWorkDir(), 385 fullClassName); 386 } 387 388 return Class.forName(fullClassName, false, loader); 389 } catch (RuntimeException e) { 390 if (! preload) 391 throw e; 392 else 393 return null; 394 } catch (Error e) { 395 if (! preload) 396 throw e; 397 else 398 return null; 399 } catch (ClassNotFoundException e) { 400 if (! preload) 401 throw e; 402 else 403 return null; 404 } finally { 405 if (preloadLoader != null) 406 preloadLoader.destroy(); 407 } 408 } 409 410 413 public boolean isModified(Class cl) 414 { 415 Path searchPath = getSearchPath(); 416 417 if (searchPath == null) 418 searchPath = getDefaultSearchPath(); 419 420 try { 421 Method method = cl.getMethod(_initMethod, new Class [] { Path.class }); 422 method.invoke(null, new Object [] { searchPath }); 423 424 method = cl.getMethod(_isModifiedMethod, new Class [0]); 425 Boolean value = (Boolean ) method.invoke(null, new Object [] {}); 426 427 return value.booleanValue(); 428 } catch (NoSuchMethodException e) { 429 return false; 430 } catch (Throwable e) { 431 log.warning(e.toString()); 432 433 return true; 434 } 435 } 436 } 437 | Popular Tags |