001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.ioc.internal.services;
016:
017: import java.security.ProtectionDomain;
018:
019: import javassist.CtClass;
020: import javassist.NotFoundException;
021:
022: import org.apache.tapestry.ioc.services.ClassFabUtils;
023:
024: /**
025: * Wrapper around Javassist's {@link javassist.ClassPool} that manages the creation of new instances
026: * of {@link javassist.CtClass} and converts finished CtClass's into instantiable Classes.
027: */
028: class CtClassSource {
029: private final ClassFactoryClassPool _pool;
030:
031: private final ClassLoader _loader;
032:
033: private final ProtectionDomain _domain = getClass()
034: .getProtectionDomain();
035:
036: private int _createdClassCount = 0;
037:
038: /**
039: * Returns the number of classes (and interfaces) created by this source.
040: */
041: public synchronized int getCreatedClassCount() {
042: return _createdClassCount;
043: }
044:
045: public CtClassSource(ClassFactoryClassPool pool, ClassLoader loader) {
046: _pool = pool;
047: _loader = loader;
048: }
049:
050: public CtClass getCtClass(Class searchClass) {
051: ClassLoader loader = searchClass.getClassLoader();
052:
053: // Add the class loader for the searchClass to the class pool and
054: // delegating class loader if needed.
055:
056: _pool.addClassLoaderIfNeeded(loader);
057:
058: String name = ClassFabUtils.toJavaClassName(searchClass);
059:
060: try {
061: return _pool.get(name);
062: } catch (NotFoundException ex) {
063: throw new RuntimeException(ServiceMessages
064: .unableToLookupClass(name, ex), ex);
065: }
066: }
067:
068: public synchronized CtClass newClass(String name, Class super Class) {
069: CtClass ctSuperClass = getCtClass(super Class);
070:
071: return _pool.makeClass(name, ctSuperClass);
072: }
073:
074: private static final String WRITE_DIR = System
075: .getProperty("javassist-write-dir");
076:
077: public synchronized Class createClass(CtClass ctClass) {
078: if (WRITE_DIR != null)
079: writeClass(ctClass);
080:
081: try {
082: Class result = _pool.toClass(ctClass, _loader, _domain);
083:
084: _createdClassCount++;
085:
086: return result;
087: } catch (Throwable ex) {
088: throw new RuntimeException(ServiceMessages
089: .unableToWriteClass(ctClass, ex), ex);
090: }
091: }
092:
093: private void writeClass(CtClass ctClass) {
094: try {
095: boolean pruning = ctClass.stopPruning(true);
096:
097: ctClass.writeFile(WRITE_DIR);
098:
099: ctClass.defrost();
100:
101: ctClass.stopPruning(pruning);
102: } catch (Exception ex) {
103: ex.printStackTrace(System.err);
104: }
105: }
106: }
|