1 54 package org.logicalcobwebs.cglib.core; 55 56 import java.io.*; 57 import java.lang.reflect.*; 58 import java.util.*; 59 import org.logicalcobwebs.asm.ClassReader; 60 import org.logicalcobwebs.asm.ClassVisitor; 61 import org.logicalcobwebs.asm.ClassWriter; 62 import org.logicalcobwebs.asm.Type; 63 64 70 abstract public class AbstractClassGenerator 71 implements ClassGenerator 72 { 73 private static final Object NAME_KEY = new Object (); 74 75 private GeneratorStrategy strategy = DefaultGeneratorStrategy.INSTANCE; 76 private NamingPolicy namingPolicy; 77 private Source source; 78 private ClassLoader classLoader; 79 private String namePrefix; 80 private Object key; 81 private boolean useCache = true; 82 83 protected static class Source { 84 String name; 85 Map cache = new WeakHashMap(); 86 public Source(String name) { 87 this.name = name; 88 } 89 } 90 91 protected AbstractClassGenerator(Source source) { 92 this.source = source; 93 } 94 95 protected void setNamePrefix(String namePrefix) { 96 this.namePrefix = namePrefix; 97 } 98 99 final protected String getClassName() { 100 return getClassName(getClassLoader()); 101 } 102 103 private String getClassName(ClassLoader loader) { 104 NamingPolicy np = (namingPolicy != null) ? namingPolicy : DefaultNamingPolicy.INSTANCE; 105 final Set nameCache = getClassNameCache(loader); 106 return np.getClassName(namePrefix, source.name, key, new Predicate() { 107 public boolean evaluate(Object arg) { 108 return nameCache.contains(arg); 109 } 110 }); 111 } 112 113 private Set getClassNameCache(ClassLoader loader) { 114 return (Set)((Map)source.cache.get(loader)).get(NAME_KEY); 115 } 116 117 126 public void setClassLoader(ClassLoader classLoader) { 127 this.classLoader = classLoader; 128 } 129 130 135 public void setNamingPolicy(NamingPolicy namingPolicy) { 136 this.namingPolicy = namingPolicy; 137 } 138 139 143 public void setUseCache(boolean useCache) { 144 this.useCache = useCache; 145 } 146 147 151 public void setStrategy(GeneratorStrategy strategy) { 152 this.strategy = strategy; 153 } 154 155 protected ClassLoader getClassLoader() { 157 ClassLoader t = classLoader; 158 if (t == null) { 159 t = getDefaultClassLoader(); 160 } 161 if (t == null) { 162 t = getClass().getClassLoader(); 163 } 164 if (t == null) { 165 throw new IllegalStateException ("Cannot determine classloader"); 166 } 167 return t; 168 } 169 170 abstract protected ClassLoader getDefaultClassLoader(); 171 172 protected Object create(Object key) { 173 try { 174 Object instance = null; 175 synchronized (source) { 176 ClassLoader loader = getClassLoader(); 177 Map cache2 = null; 178 if (useCache) { 179 cache2 = (Map)source.cache.get(loader); 180 if (cache2 != null) { 181 instance = cache2.get(key); 182 } else { 183 cache2 = new HashMap(); 184 cache2.put(NAME_KEY, new HashSet()); 185 source.cache.put(loader, cache2); 186 } 187 } 188 if (instance == null) { 189 this.key = key; 190 byte[] b = strategy.generate(this); 191 String className = ClassNameReader.getClassName(new ClassReader(b)); 192 getClassNameCache(loader).add(className); 193 instance = firstInstance(ReflectUtils.defineClass(className, b, loader)); 194 if (useCache) { 195 cache2.put(key, instance); 196 } 197 return instance; 198 } 199 } 200 return nextInstance(instance); 201 } catch (RuntimeException e) { 202 throw e; 203 } catch (Error e) { 204 throw e; 205 } catch (Exception e) { 206 throw new CodeGenerationException(e); 207 } 208 } 209 210 abstract protected Object firstInstance(Class type) throws Exception ; 211 abstract protected Object nextInstance(Object instance) throws Exception ; 212 } 213 | Popular Tags |