1 18 19 package org.objectweb.jac.core; 20 21 import java.io.FileNotFoundException ; 22 import java.io.Serializable ; 23 import java.lang.reflect.InvocationTargetException ; 24 import java.lang.reflect.Method ; 25 import java.util.Arrays ; 26 import java.util.Collection ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import java.util.Vector ; 33 import org.apache.log4j.Logger; 34 import org.objectweb.jac.core.rtti.*; 35 import org.objectweb.jac.util.WeakHashSet; 36 import org.objectweb.jac.util.WrappedThrowableException; 37 38 54 55 public class AspectComponent 56 implements Serializable , BaseProgramListener 57 { 58 static Logger logger = Logger.getLogger("aspects"); 59 static Logger loggerConf = Logger.getLogger("aspects.config"); 60 static Logger loggerWrap = Logger.getLogger("wrappers"); 61 static Logger loggerWuni = Logger.getLogger("wuni"); 62 static Logger loggerPerf = Logger.getLogger("perf"); 63 64 protected static final boolean SHARED = false; 65 protected static final boolean NOT_SHARED = true; 66 67 protected static final ClassRepository cr = ClassRepository.get(); 68 69 75 76 public static boolean defines(String methodName) { 77 if (ClassRepository.getDirectMethodAccess(AspectComponent.class, 78 methodName )[0] != null) 79 return true; 80 return false; 81 } 82 83 94 95 public void defineTimer(final long period, final MethodItem callback, 96 final Object [] args) { 97 final AspectComponent ac=this; 98 new Thread () { 99 public void run() { 100 while(true) { 101 try { 102 sleep(period); 103 } catch(Exception e) { 104 e.printStackTrace(); 105 } 106 callback.invoke(ac,args); 107 } 108 } 109 }.start(); 110 } 111 112 117 118 120 127 128 public int firstCall = -1; 129 130 134 135 public Class startWeavingType; 136 137 142 public String startWeavingMethod; 143 144 151 public int startWeavingCount; 152 153 159 public int startWeavingCCount; 160 161 167 protected transient WeakHashSet wrappers; 168 169 173 protected boolean systemListener = false; 174 175 183 public void setSystemListener(boolean systemListener) { 184 this.systemListener = systemListener; 185 } 186 187 193 public boolean isSystemListener() { 194 return systemListener; 195 } 196 197 206 public AspectComponent() { 207 logger.debug("New AC: "+this); 208 wrappers = new WeakHashSet(); 209 firstCall = -1; 210 startWeavingType = null; 211 startWeavingMethod = null; 212 startWeavingCount = 0; 213 startWeavingCCount = 0; 214 init(); 215 } 217 218 222 public void init() { 223 loggerWrap.debug("clearing wrappers (was "+wrappers+")"); 225 wrappers.clear(); 226 } 227 228 protected String application=null; 229 230 237 public String getApplication() { 238 return application; 239 } 240 241 250 251 public void setApplication(String application) { 252 this.application = application; 253 } 254 255 264 265 public Collection getWrappers() { 266 return wrappers; 267 } 268 269 282 283 public void addWrapper(Wrapper wrapper) { 284 wrappers.add(wrapper); 285 } 286 287 323 324 public void weave() { 325 Iterator it = ObjectRepository.getMemoryObjects().iterator(); 326 while (it.hasNext()) { 327 simulateUsingNewInstance((Wrappee)it.next()); 328 } 329 } 330 331 394 public void whenUsingNewInstance(Interaction interaction) { 395 ClassItem cli = interaction.getClassItem(); 398 AbstractMethodItem method = interaction.method; 400 401 loggerWuni.debug("whenUsingNewInstance("+interaction+"); pointcuts: "+pointcuts.size()); 402 int i = 0; 403 Iterator it = pointcuts.iterator(); 404 while (it.hasNext()) { 405 loggerWuni.debug(" pointcut "+i++); 406 ((Pointcut)it.next()).applyTo(interaction.wrappee, cli); 407 } 408 } 409 410 public void whenUsingNewClass(ClassItem cli) { 411 Iterator it = pointcuts.iterator(); 412 int i = 0; 413 loggerWuni.debug(this+".whenUsingNewClass"+cli); 414 while (it.hasNext()) { 415 ((Pointcut)it.next()).applyTo(null, cli); 416 } 417 } 418 419 427 428 protected void simulateUsingNewInstance(Wrappee wrappee) { 429 430 Collaboration collab = Collaboration.get(); 432 whenUsingNewInstance(new Interaction(null,wrappee,null,null)); 434 435 } 437 438 452 453 455 469 public void whenRemoteInstantiation(Wrappee newInstance, 470 String name) {} 471 472 483 protected final void unwrapAll() { 484 loggerWrap.debug("unwrap all"); 485 loggerWrap.debug(wrappers.size()+" wrappers: " + wrappers); 486 Iterator it = ObjectRepository.getMemoryObjects().iterator(); 487 while (it.hasNext()) { 488 Object o = it.next(); 489 if (o instanceof Wrappee) { 490 Wrappee wrappee = (Wrappee)o; 491 ClassItem wrappeeClass = cr.getClass(wrappee); 492 loggerWrap.debug("testing wrappee " + wrappee); 493 Wrapping.unwrap(wrappee,wrappeeClass,wrappers); 494 Wrapping.unwrap(null,wrappeeClass,wrappers); 495 } 496 } 497 wrappers.clear(); 498 } 499 500 509 510 public void unweave() { 511 logger.info("--- unweaving "+this+" ---"); 512 long start = System.currentTimeMillis(); 513 unwrapAll(); 514 pointcuts.clear(); 515 loggerPerf.info("unweaved "+this+" in "+(System.currentTimeMillis()-start)+"ms"); 516 } 517 518 521 522 public void whenClone(Wrappee cloned, Wrappee clone) {} 523 524 541 542 public Wrappee whenSerialized(Wrappee orgObject, 543 SerializedJacObject finalObject) { 544 return orgObject; 545 } 546 547 565 566 public Wrappee whenDeserialized(SerializedJacObject orgObject, 567 Wrappee finalObject) { 568 return finalObject; 569 } 570 571 572 public void onExit() {} 573 574 595 public boolean beforeRunningWrapper(Wrapper wrapper, 596 String wrappingMethod) { 597 return true; 598 } 599 600 616 public void afterRunningWrapper(Wrapper wrapper, 617 String wrappingMethod) {} 618 619 622 623 public void afterWrap(Wrappee wrappee, Wrapper wrapper, 624 String [] wrapping_methods, 625 String [][] wrapped_methods) {} 626 627 642 643 public void whenGetObjects(Collection objects, ClassItem cl) {} 644 645 public String whenNameObject(Object object,String name) { 646 return name; 647 } 648 649 public void getNameCounters(Map counters) { 650 } 651 652 public void updateNameCounters(Map counters) { 653 } 654 655 673 674 public void whenObjectMiss(String name) {} 675 676 public void whenDeleted(Wrappee object) {} 677 678 public void whenFree(Wrappee object) {} 679 680 public void afterApplicationStarted() {} 681 682 public void whenCloseDisplay(Display display) {} 683 684 public void whenTopologyChanged() {} 685 686 689 public void whenReload() {} 690 public void beforeReload() {} 691 692 696 697 public void whenConfigured() {} 698 699 702 public void beforeConfiguration() throws Exception { 703 } 704 705 public String getName() { 706 return ACManager.getACM().getName(this); 707 } 708 709 714 public void doRegister() { 715 } 716 717 722 public void doUnregister() { 723 } 724 725 726 Vector pointcuts = new Vector (); 727 728 745 public Pointcut pointcut(String wrappeeExpr, 746 String wrappeeClassExpr, 747 String wrappeeMethodExpr, 748 String wrappingClassName, 749 String exceptionHandler, 750 boolean one2one) { 751 752 MethodPointcut pc = new MethodPointcut( this, 753 wrappeeExpr, 754 wrappeeClassExpr, 755 wrappeeMethodExpr, 756 null, 757 wrappingClassName, 758 null, 759 null, 760 "ALL", 761 exceptionHandler, 762 one2one ); 763 pointcuts.add(pc); 764 return pc; 765 } 766 767 787 public Pointcut pointcut(String wrappeeExpr, 788 String wrappeeClassExpr, 789 String wrappeeMethodExpr, 790 String wrappingClassName, 791 Object [] initParameters, 792 String exceptionHandler, 793 boolean one2One) { 794 795 MethodPointcut pc = new MethodPointcut( this, 796 wrappeeExpr, 797 wrappeeClassExpr, 798 wrappeeMethodExpr, 799 null, 800 wrappingClassName, 801 null, 802 initParameters, 803 "ALL", 804 exceptionHandler, 805 one2One ); 806 pointcuts.add(pc); 807 return pc; 808 } 809 810 830 831 public Pointcut pointcut(String wrappeeExpr, 832 String wrappeeClassExpr, 833 String wrappeeMethodExpr, 834 String wrappingClassName, 835 String hostExpr, 836 String exceptionHandler, 837 boolean one2One) { 838 839 MethodPointcut pc = new MethodPointcut(this, 840 wrappeeExpr, 841 wrappeeClassExpr, 842 wrappeeMethodExpr, 843 null, 844 wrappingClassName, 845 null, 846 null, 847 hostExpr, 848 exceptionHandler, 849 one2One); 850 pointcuts.add(pc); 851 return pc; 852 } 853 854 878 public Pointcut pointcut(String wrappeeExpr, 879 String wrappeeClassExpr, 880 String wrappeeMethodExpr, 881 String wrappingClassName, 882 Object [] initParameters, 883 String hostExpr, 884 String exceptionHandler, 885 boolean one2One) { 886 887 MethodPointcut pc = new MethodPointcut(this, 888 wrappeeExpr, 889 wrappeeClassExpr, 890 wrappeeMethodExpr, 891 null, 892 wrappingClassName, 893 null, 894 initParameters, 895 hostExpr, 896 exceptionHandler, 897 one2One); 898 pointcuts.add(pc); 899 return pc; 900 } 901 902 919 public Pointcut pointcut(String wrappeeExpr, 920 String wrappeeClassExpr, 921 String wrappeeMethodExpr, 922 Wrapper wrapper, 923 String exceptionHandler) { 924 925 MethodPointcut pc = new MethodPointcut(this, 926 wrappeeExpr, 927 wrappeeClassExpr, 928 wrappeeMethodExpr, 929 wrapper, 930 wrapper.getClass().getName(), 931 null, 932 null, 933 "ALL", 934 exceptionHandler, 935 false); 936 pointcuts.add(pc); 937 return pc; 938 } 939 940 961 public Pointcut pointcut(String wrappeeExpr, 962 String wrappeeClassExpr, 963 String wrappeeMethodExpr, 964 Wrapper wrapper, 965 String hostExpr, 966 String exceptionHandler) { 967 968 MethodPointcut pc = new MethodPointcut(this, 969 wrappeeExpr, 970 wrappeeClassExpr, 971 wrappeeMethodExpr, 972 wrapper, 973 wrapper.getClass().getName(), 974 null, 975 null, 976 hostExpr, 977 exceptionHandler, 978 false); 979 pointcuts.add(pc); 980 return pc; 981 } 982 983 997 998 public Pointcut pointcut(String wrappeeExpr, 999 String wrappeeClassExpr, 1000 String methodName, 1001 Object [] methodArgs, 1002 String exceptionHandler) { 1003 1004 MethodPointcut pc = new MethodPointcut(this, 1005 wrappeeExpr, 1006 wrappeeClassExpr, 1007 null, 1008 null, 1009 null, 1010 methodName, 1011 methodArgs, 1012 "ALL", 1013 exceptionHandler, 1014 false); 1015 pointcuts.add(pc); 1016 return pc; 1017 } 1018 1019 1033 1034 public Pointcut pointcut(String wrappeeExpr, 1035 String wrappeeClassExpr, 1036 String methodName, 1037 Object [] methodArgs, 1038 String hostExpr, 1039 String exceptionHandler) { 1040 1041 MethodPointcut pc = new MethodPointcut(this, 1042 wrappeeExpr, 1043 wrappeeClassExpr, 1044 null, 1045 null, 1046 null, 1047 methodName, 1048 methodArgs, 1049 hostExpr, 1050 exceptionHandler, 1051 false); 1052 pointcuts.add(pc); 1053 return pc; 1054 } 1055 1056 1062 public void setAttribute(ClassItem cli, String name, String value) { 1063 cli.setAttribute(name,value); 1064 } 1065 1066 1072 public void setAttribute(FieldItem field, String name, String value) { 1073 field.setAttribute(name,value); 1074 } 1075 1076 1077 1083 public void setAttribute(AbstractMethodItem method, 1084 String name, String value) { 1085 method.setAttribute(name,value); 1086 } 1087 1088 1090 public final void attrdef(String name, Object value) { 1091 Collaboration.get().addAttribute( name, value ); 1092 } 1093 1094 public final Object attr( String name ) { 1095 return Collaboration.get().getAttribute( name ); 1096 } 1097 1098 1099 protected String [] blockKeywords = new String [0]; 1100 1101 public Set getBlockKeywords() { 1102 return new HashSet (Arrays.asList(blockKeywords)); 1103 } 1104 1105 1107 public String [] getDefaultConfigs() { 1108 return new String [0]; 1109 } 1110 1111 1115 public Collection getConfigurationMethods() { 1116 Vector result = new Vector (); 1117 Iterator ms = cr.getClass(getClass()).getAllMethods().iterator(); 1118 1119 while(ms.hasNext()){ 1120 MethodItem methodItem=(MethodItem)ms.next(); 1121 if (isConfigurationMethod(methodItem.getActualMethod())){ 1122 result.add(methodItem); 1123 } 1124 } 1125 return result; 1126 } 1127 1128 1132 public Collection getConfigurationMethodsName() { 1133 Vector result = new Vector (); 1134 Method [] ms = getClass().getMethods(); 1135 for(int i=0;i<ms.length;i++) { 1136 if (isConfigurationMethod(ms[i])) { 1137 result.add(ms[i].getName()); 1138 } 1139 } 1140 return result; 1141 } 1142 1143 1144 1151 public List getConfigurationMethodsName(Class firstParamType) { 1152 Vector result = new Vector (); 1153 Iterator ms = cr.getClass(getClass()) 1154 .getAllMethods().iterator(); 1155 HashSet names = new HashSet (); 1157 1158 while (ms.hasNext()) { 1159 MethodItem methodItem = (MethodItem)ms.next(); 1160 if (isConfigurationMethod(methodItem.getActualMethod())) { 1161 Class [] paramTypes = methodItem.getParameterTypes(); 1162 if (paramTypes.length>0 && 1163 (paramTypes[0].isAssignableFrom(firstParamType) || 1164 firstParamType.isAssignableFrom(paramTypes[0])) && 1165 !names.contains(methodItem.getName())) { 1166 result.add(methodItem.getName()); 1167 names.add(methodItem.getName()); 1168 } 1169 } 1170 } 1171 return result; 1172 } 1173 1174 1175 1180 public boolean isConfigurationMethod(Method method) { 1181 Class cl = method.getDeclaringClass(); 1182 if (AspectComponent.class.isAssignableFrom(cl)) { 1183 Class [] interfs=cl.getInterfaces(); 1184 for(int i=0;i<interfs.length;i++) { 1185 if (!interfs[i].getName().endsWith("Conf")) 1186 continue; 1187 Method [] ms = interfs[i].getMethods(); 1188 for(int j=0; j<ms.length; j++) { 1189 if (ms[j].getName().equals(method.getName())) { 1190 return true; 1191 } 1192 } 1193 } 1194 } 1195 return false; 1196 } 1197 1198 protected ConfigMethod currentConfigMethod; 1199 protected Imports currentImports; 1200 1201 1207 public void configure(String name, String filePath) { 1208 long start = System.currentTimeMillis(); 1209 if (filePath == null) { 1210 return; 1211 } 1212 loggerConf.info("configuring aspect " + name + " with file "+filePath); 1213 List configMethods = null; 1214 try { 1215 Parser acp = (Parser)NameRepository.get().getObject(Naming.PARSER_NAME); 1221 configMethods = acp.parse(filePath,this.getClass().getName(), 1222 this.getBlockKeywords()); 1223 } catch (FileNotFoundException e) { 1224 logger.warn("cannot find config file "+filePath+" for "+name+ 1225 "("+e+"), using serialized infos."); 1226 } catch (Exception e) { 1227 logger.error("configure "+name+","+filePath,e); 1228 return; 1229 } 1230 if (configMethods==null) 1231 return; 1232 currentImports = new Imports(); 1233 for (int i=0; i<configMethods.size(); i++) { 1234 MethodItem method = null; 1235 Object statement = configMethods.get(i); 1236 if (statement instanceof ImportStatement) { 1237 ImportStatement imp = (ImportStatement)statement; 1238 currentImports.add(imp.getExpr()); 1239 continue; 1240 } 1241 ConfigMethod cm = (ConfigMethod)statement; 1242 currentConfigMethod = cm; 1243 if (cm==null) { 1244 loggerConf.warn("skipping error"); 1245 continue; 1246 } 1247 try { 1248 loggerConf.debug( 1249 "invoking configuration method '"+cm.getMethod()+ 1250 "' on "+this.getClass()+" with "+Arrays.asList(cm.getArgs())); 1251 if (cm.getMethod().equals("")) 1252 continue; 1253 MethodItem[] methodItems = 1254 cr.getClass(this.getClass()). 1255 getMethods(cm.getMethod()); 1256 if (methodItems==null || methodItems.length==0) { 1257 loggerConf.warn("No such configuration method "+cm.getMethod()+ 1258 " in AC "+this.getClass()); 1259 } 1260 loggerConf.debug( 1261 "matching methods : "+Arrays.asList(methodItems)); 1262 1263 Object [] paramValues = null; 1264 Vector exceptions = new Vector (); 1267 for(int j=0; j<methodItems.length && method==null; j++) { 1268 paramValues = cm.getArgs(); 1269 if (methodItems[j].getParameterTypes().length==paramValues.length) { 1271 method = methodItems[j]; 1272 loggerConf.debug("selecting method "+method); 1273 1274 paramValues = cm.getArgs(); 1277 try { 1278 Class [] paramTypes = method.getParameterTypes(); 1279 for(int k=0; k<paramTypes.length; k++) { 1280 paramValues[k] = 1281 ACConfiguration.convertValue( 1282 paramValues[k], 1283 paramTypes[k], 1284 currentImports); 1285 } 1286 break; 1287 } catch(Exception e) { 1288 exceptions.add(e); 1289 method = null; 1290 } 1291 } 1292 if (method==null && 1295 (methodItems[j].getParameterCount()>0)) { 1296 for (int p=0; p<methodItems[j].getParameterCount(); p++) { 1297 if ((MemberItem.class.isAssignableFrom( 1298 methodItems[j].getParameterTypes()[p])) 1299 && (methodItems[j].getParameterTypes().length 1300 == paramValues.length-1)) 1301 { 1302 method = methodItems[j]; 1303 loggerConf.debug( 1304 "selecting method "+method+ 1305 " with MemberItem=ClassItem+String for param #"+p); 1306 paramValues = cm.getArgs(); 1307 Object paramValuesTranslated[] = new Object [paramValues.length-1]; 1308 try { 1309 Class [] paramTypes = method.getParameterTypes(); 1310 ClassItem classItem = 1311 (ClassItem)ACConfiguration.convertValue( 1312 paramValues[p], 1313 ClassItem.class, 1314 currentImports); 1315 paramValuesTranslated[p] = 1316 classItem.getMember( 1317 (String )ACConfiguration.convertValue( 1318 paramValues[p+1], 1319 String .class, 1320 currentImports)); 1321 if (!paramTypes[p].isAssignableFrom( 1322 paramValuesTranslated[p].getClass())) 1323 { 1324 throw new Exception ( 1325 "Error translating parameter: "+ 1326 paramValuesTranslated[0].getClass().getName()+ 1327 " can't be assigned to "+paramTypes[p].getName()); 1328 } 1329 for(int k=p+1; k<paramTypes.length; k++){ 1330 paramValuesTranslated[k] = 1331 ACConfiguration.convertValue( 1332 paramValues[k+1], 1333 paramTypes[k], 1334 currentImports); 1335 } 1336 1337 for(int k=0; k<p; k++){ 1338 paramValuesTranslated[k] = 1339 ACConfiguration.convertValue( 1340 paramValues[k], 1341 paramTypes[k], 1342 currentImports); 1343 } 1344 paramValues = paramValuesTranslated; 1345 loggerConf.debug("Parameter transformation successful"); 1346 break; 1347 } catch (Exception e) { 1348 loggerConf.debug("Exception in parameter transformation: "+e); 1349 exceptions.add(e); 1350 method = null; 1351 } 1352 } 1353 } 1354 } 1355 1356 } 1357 if (method == null) { 1358 if (exceptions.isEmpty()) { 1359 throw new Exception ("Wrong number of parameters for method "+ 1360 cm.getMethod()); 1361 } else { 1362 throw (Exception )exceptions.get(0); 1363 } 1365 } 1366 1367 loggerConf.debug( 1368 filePath+": line "+cm.getLineNumber() + 1369 ", invoke configuration method '" + 1370 (method!=null?method.toString():cm.getMethod()) + 1371 "' on " + this.getClass() + 1372 " with " + Arrays.asList(cm.getArgs())); 1373 method.invoke(this,paramValues); 1374 1375 } catch (InvocationTargetException e) { 1376 Throwable target = e.getTargetException(); 1377 loggerConf.warn(cm.getLineNumber() + 1378 ", failed to invoke configuration method '"+ 1379 (method!=null?method.getFullName():cm.getMethod())+ 1380 "' on "+this.getClass() + " with "+ 1381 Arrays.asList(cm.getArgs()),target); 1382 loggerConf.info("Stack trace follows",e); 1383 } catch (Throwable e) { 1384 if (e instanceof WrappedThrowableException) 1385 e = ((WrappedThrowableException)e).getWrappedThrowable(); 1386 loggerConf.warn(cm.getLineNumber() + 1387 ", failed to invoke configuration method '"+ 1388 (method!=null?method.getFullName():cm.getMethod())+ 1389 "' on "+this.getClass()+ 1390 " with "+Arrays.asList(cm.getArgs())+" : "+e); 1391 loggerConf.info("Stack trace follows",e); 1392 } finally { 1393 currentConfigMethod = null; 1394 } 1395 } 1396 loggerPerf.debug( 1397 "aspect configuration file "+filePath+" read in "+ 1398 (System.currentTimeMillis()-start)+"ms"); 1399 } 1400 1401 public void beforeWrappeeInit(Wrappee wrappee) {}; 1402 1403 public void afterWrappeeInit(Wrappee wrappee) {}; 1404 1405 1412 protected void warning(String message) { 1413 if (currentConfigMethod!=null) 1414 loggerConf.warn( 1415 currentConfigMethod.getLineNumber()+":"+ 1416 currentConfigMethod.getMethod()+": "+message); 1417 else 1418 loggerConf.warn(message); 1419 } 1420 1421 1428 protected void error(String message) { 1429 if (currentConfigMethod!=null) 1430 loggerConf.error( 1431 currentConfigMethod.getLineNumber()+":"+ 1432 currentConfigMethod.getMethod()+": "+message); 1433 else 1434 logger.error(message); 1435 } 1436 1437 1440 protected AspectComponent getAC(String name) { 1441 return ACManager.getACM().getACFromFullName(application+"."+name); 1442 } 1443} 1444 | Popular Tags |