1 22 package org.jboss.aop; 23 24 import java.lang.reflect.Field ; 25 import java.lang.reflect.Method ; 26 import java.security.AccessController ; 27 import java.security.PrivilegedAction ; 28 import java.util.ArrayList ; 29 import java.util.Arrays ; 30 import java.util.Collections ; 31 import java.util.Iterator ; 32 import java.util.LinkedHashMap ; 33 34 import org.jboss.aop.advice.AdviceBinding; 35 import org.jboss.aop.metadata.ClassMetaDataBinding; 36 import org.jboss.aop.metadata.ClassMetaDataLoader; 37 import org.jboss.aop.util.Advisable; 38 import org.jboss.aop.util.ConstructorComparator; 39 import org.jboss.aop.util.FieldComparator; 40 import org.jboss.aop.util.MethodHashing; 41 import gnu.trove.TLongObjectHashMap; 42 43 49 public class ClassContainer extends Advisor 50 { 51 public ClassContainer(String name, AspectManager manager) 52 { 53 super(name, manager); 54 } 55 56 public void initializeClassContainer() 57 { 58 initializeMetadata(); 59 rebuildInterceptors(); 60 } 61 62 public void setClass(Class clazz) 63 { 64 this.clazz = clazz; 65 } 66 67 public void initializeMetadata() 68 { 69 createMethodMap(); 70 createConstructorTables(); 71 createFieldTable(); 72 rebindClassMetaData(); 73 deployAnnotationOverrides(); 74 } 75 76 protected Field [] advisedFields; 77 78 private void populateFieldTable(ArrayList fields, final Class superclass) 79 { 80 if (superclass == null) return; 81 if (superclass.equals(Object .class)) return; 82 83 populateFieldTable(fields, superclass.getSuperclass()); 84 85 87 ArrayList temp = new ArrayList (); 88 Field [] declaredFields = (Field []) AccessController.doPrivileged(new PrivilegedAction () 89 { 90 public Object run() 91 { 92 return superclass.getDeclaredFields(); 93 } 94 }); 95 for (int i = 0; i < declaredFields.length; i++) 96 { 97 if (Advisable.isAdvisable(declaredFields[i])) 98 { 99 temp.add(declaredFields[i]); 100 } 101 } 102 Collections.sort(temp, FieldComparator.INSTANCE); 103 fields.addAll(temp); 104 } 105 106 109 protected void createFieldTable() 110 { 111 ArrayList fields = new ArrayList (); 112 113 populateFieldTable(fields, clazz); 114 115 advisedFields = (Field []) fields.toArray(new Field [fields.size()]); 116 117 } 118 119 protected void rebuildInterceptors() 120 { 121 adviceBindings.clear(); 122 createInterceptorChains(); 123 } 124 125 public void addClassMetaData(ClassMetaDataBinding data) 126 { 127 classMetaDataBindings.add(data); 128 if (this.clazz == null) return; 130 bindClassMetaData(data); 131 adviceBindings.clear(); 133 doesHaveAspects = false; 134 rebuildInterceptors(); 135 136 } 137 138 139 140 public void removeClassMetaData(ClassMetaDataBinding data) 141 { 142 if (classMetaDataBindings.remove(data)) 143 { 144 if (this.clazz == null) return; rebindClassMetaData(); 146 adviceBindings.clear(); 148 doesHaveAspects = false; 149 rebuildInterceptors(); 150 } 151 } 152 153 protected void bindClassMetaData(ClassMetaDataBinding data) 154 { 155 try 156 { 157 ClassMetaDataLoader loader = data.getLoader(); 158 Object [] objs = advisedMethods.getValues(); 159 Method [] methods = new Method [objs.length]; 160 for (int i = 0; i < objs.length; i++) methods[i] = (Method ) objs[i]; 161 loader.bind(this, data, methods, advisedFields, clazz.getDeclaredConstructors()); 162 } 163 catch (Exception ex) 164 { 165 ex.printStackTrace(); 167 } 168 } 169 170 protected void rebindClassMetaData() 171 { 172 defaultMetaData.clear(); 173 methodMetaData.clear(); 174 fieldMetaData.clear(); 175 constructorMetaData.clear(); 176 classMetaData.clear(); 177 178 for (int i = 0; i < classMetaDataBindings.size(); i++) 179 { 180 ClassMetaDataBinding data = (ClassMetaDataBinding) classMetaDataBindings.get(i); 181 bindClassMetaData(data); 182 } 183 } 184 185 protected void createMethodMap() 186 { 187 try 188 { 189 Method [] declaredMethods = clazz.getMethods(); 190 for (int i = 0; i < declaredMethods.length; i++) 191 { 192 if (ClassAdvisor.isAdvisable(declaredMethods[i])) 193 { 194 long hash = MethodHashing.methodHash(declaredMethods[i]); 195 advisedMethods.put(hash, declaredMethods[i]); 196 } 197 } 198 } 199 catch (Exception e) 200 { 201 throw new RuntimeException (e); 202 } 203 } 204 205 protected MethodInterceptors initializeMethodChain() 206 { 207 MethodInterceptors newInterceptors = new MethodInterceptors(this); 208 long[] keys = advisedMethods.keys(); 209 for (int i = 0; i < keys.length; i++) 210 { 211 MethodInfo info = new MethodInfo(); 212 Method amethod = (Method ) advisedMethods.get(keys[i]); 213 info.setAdvisedMethod(amethod); 214 info.setUnadvisedMethod(amethod); 215 info.setHash(keys[i]); 216 info.setAdvisor(this); 217 newInterceptors.put(keys[i], info); 218 } 219 return newInterceptors; 220 } 221 222 protected void createConstructorTables() 223 { 224 constructors = clazz.getDeclaredConstructors(); 225 if (constructors.length > 0) 226 { 227 for (int i = 0; i < constructors.length; i++) 228 { 229 constructors[i].setAccessible(true); 230 } 231 Arrays.sort(constructors, ConstructorComparator.INSTANCE); 232 } 233 } 234 235 protected void createInterceptorChains() 236 { 237 MethodInterceptors newMethodInfos = initializeMethodChain(); 238 ArrayList newConstructorInfos = initializeConstructorChain(); 239 240 LinkedHashMap bindings = manager.getBindings(); 241 synchronized (bindings) 242 { 243 if (bindings.size() > 0) 244 { 245 Iterator it = bindings.values().iterator(); 246 while (it.hasNext()) 247 { 248 AdviceBinding binding = (AdviceBinding) it.next(); 249 if (AspectManager.verbose) System.out.println("iterate binding " + binding.getName()); 250 resolveMethodPointcut(newMethodInfos, binding); 251 resolveConstructorPointcut(newConstructorInfos, binding); 252 } 253 } 254 } 255 finalizeConstructorChain(newConstructorInfos); 256 finalizeMethodChain(newMethodInfos); 257 constructorInfos = new ConstructorInfo[newConstructorInfos.size()]; 258 if (constructorInfos.length > 0) 259 constructorInfos = (ConstructorInfo[]) newConstructorInfos.toArray(constructorInfos); 260 261 populateInterceptorsFromInfos(); 262 263 doesHaveAspects = adviceBindings.size() > 0; 264 } 265 } 266 | Popular Tags |