You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

WeavingAdaptor.java 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Matthew Webster, Adrian Colyer,
  11. * Martin Lippert initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.weaver.tools;
  14. import java.io.File;
  15. import java.io.FileOutputStream;
  16. import java.io.IOException;
  17. import java.io.PrintWriter;
  18. import java.net.URL;
  19. import java.net.URLClassLoader;
  20. import java.util.ArrayList;
  21. import java.util.HashMap;
  22. import java.util.HashSet;
  23. import java.util.Iterator;
  24. import java.util.LinkedList;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Set;
  28. import java.util.StringTokenizer;
  29. import org.aspectj.bridge.AbortException;
  30. import org.aspectj.bridge.IMessage;
  31. import org.aspectj.bridge.IMessageContext;
  32. import org.aspectj.bridge.IMessageHandler;
  33. import org.aspectj.bridge.IMessageHolder;
  34. import org.aspectj.bridge.Message;
  35. import org.aspectj.bridge.MessageHandler;
  36. import org.aspectj.bridge.MessageUtil;
  37. import org.aspectj.bridge.MessageWriter;
  38. import org.aspectj.bridge.Version;
  39. import org.aspectj.bridge.WeaveMessage;
  40. import org.aspectj.bridge.IMessage.Kind;
  41. import org.aspectj.util.FileUtil;
  42. import org.aspectj.util.LangUtil;
  43. import org.aspectj.weaver.IClassFileProvider;
  44. import org.aspectj.weaver.IWeaveRequestor;
  45. import org.aspectj.weaver.ResolvedType;
  46. import org.aspectj.weaver.bcel.BcelObjectType;
  47. import org.aspectj.weaver.bcel.BcelWeaver;
  48. import org.aspectj.weaver.bcel.BcelWorld;
  49. import org.aspectj.weaver.bcel.UnwovenClassFile;
  50. import org.aspectj.weaver.bcel.Utility;
  51. /**
  52. * This adaptor allows the AspectJ compiler to be embedded in an existing
  53. * system to facilitate load-time weaving. It provides an interface for a
  54. * weaving class loader to provide a classpath to be woven by a set of
  55. * aspects. A callback is supplied to allow a class loader to define classes
  56. * generated by the compiler during the weaving process.
  57. * <p>
  58. * A weaving class loader should create a <code>WeavingAdaptor</code> before
  59. * any classes are defined, typically during construction. The set of aspects
  60. * passed to the adaptor is fixed for the lifetime of the adaptor although the
  61. * classpath can be augmented. A system property can be set to allow verbose
  62. * weaving messages to be written to the console.
  63. *
  64. */
  65. public class WeavingAdaptor implements IMessageContext {
  66. /**
  67. * System property used to turn on verbose weaving messages
  68. */
  69. public static final String WEAVING_ADAPTOR_VERBOSE = "aj.weaving.verbose";
  70. public static final String SHOW_WEAVE_INFO_PROPERTY = "org.aspectj.weaver.showWeaveInfo";
  71. public static final String TRACE_MESSAGES_PROPERTY = "org.aspectj.tracing.messages";
  72. private boolean enabled = false;
  73. protected boolean verbose = getVerbose();
  74. protected BcelWorld bcelWorld;
  75. protected BcelWeaver weaver;
  76. private IMessageHandler messageHandler;
  77. private WeavingAdaptorMessageHolder messageHolder;
  78. private boolean abortOnError = false;
  79. protected GeneratedClassHandler generatedClassHandler;
  80. protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */
  81. protected BcelObjectType delegateForCurrentClass; // lazily initialized, should be used to prevent parsing bytecode multiple times
  82. private static Trace trace = TraceFactory.getTraceFactory().getTrace(WeavingAdaptor.class);
  83. protected WeavingAdaptor () {
  84. }
  85. /**
  86. * Construct a WeavingAdaptor with a reference to a weaving class loader. The
  87. * adaptor will automatically search the class loader hierarchy to resolve
  88. * classes. The adaptor will also search the hierarchy for WeavingClassLoader
  89. * instances to determine the set of aspects to be used ofr weaving.
  90. * @param loader instance of <code>ClassLoader</code>
  91. */
  92. public WeavingAdaptor (WeavingClassLoader loader) {
  93. // System.err.println("? WeavingAdaptor.<init>(" + loader +"," + aspectURLs.length + ")");
  94. generatedClassHandler = loader;
  95. init(getFullClassPath((ClassLoader)loader),getFullAspectPath((ClassLoader)loader/*,aspectURLs*/));
  96. }
  97. /**
  98. * Construct a WeavingAdator with a reference to a
  99. * <code>GeneratedClassHandler</code>, a full search path for resolving
  100. * classes and a complete set of aspects. The search path must include
  101. * classes loaded by the class loader constructing the WeavingAdaptor and
  102. * all its parents in the hierarchy.
  103. * @param handler <code>GeneratedClassHandler</code>
  104. * @param classURLs the URLs from which to resolve classes
  105. * @param aspectURLs the aspects used to weave classes defined by this class loader
  106. */
  107. public WeavingAdaptor (GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs) {
  108. // System.err.println("? WeavingAdaptor.<init>()");
  109. generatedClassHandler = handler;
  110. init(FileUtil.makeClasspath(classURLs),FileUtil.makeClasspath(aspectURLs));
  111. }
  112. private List getFullClassPath (ClassLoader loader) {
  113. List list = new LinkedList();
  114. for (; loader != null; loader = loader.getParent()) {
  115. if (loader instanceof URLClassLoader) {
  116. URL[] urls = ((URLClassLoader)loader).getURLs();
  117. list.addAll(0,FileUtil.makeClasspath(urls));
  118. }
  119. else {
  120. warn("cannot determine classpath");
  121. }
  122. }
  123. list.addAll(0,makeClasspath(System.getProperty("sun.boot.class.path")));
  124. return list;
  125. }
  126. private List getFullAspectPath (ClassLoader loader) {
  127. List list = new LinkedList();
  128. for (; loader != null; loader = loader.getParent()) {
  129. if (loader instanceof WeavingClassLoader) {
  130. URL[] urls = ((WeavingClassLoader)loader).getAspectURLs();
  131. list.addAll(0,FileUtil.makeClasspath(urls));
  132. }
  133. }
  134. return list;
  135. }
  136. private static boolean getVerbose () {
  137. return Boolean.getBoolean(WEAVING_ADAPTOR_VERBOSE);
  138. }
  139. private void init(List classPath, List aspectPath) {
  140. abortOnError = true;
  141. createMessageHandler();
  142. info("using classpath: " + classPath);
  143. info("using aspectpath: " + aspectPath);
  144. bcelWorld = new BcelWorld(classPath,messageHandler,null);
  145. bcelWorld.setXnoInline(false);
  146. bcelWorld.getLint().loadDefaultProperties();
  147. if (LangUtil.is15VMOrGreater()) {
  148. bcelWorld.setBehaveInJava5Way(true);
  149. }
  150. weaver = new BcelWeaver(bcelWorld);
  151. registerAspectLibraries(aspectPath);
  152. enabled = true;
  153. }
  154. protected void createMessageHandler() {
  155. messageHolder = new WeavingAdaptorMessageHolder(new PrintWriter(System.err));
  156. messageHandler = messageHolder;
  157. if (verbose) messageHandler.dontIgnore(IMessage.INFO);
  158. if (Boolean.getBoolean(SHOW_WEAVE_INFO_PROPERTY)) messageHandler.dontIgnore(IMessage.WEAVEINFO);
  159. info("AspectJ Weaver Version " + Version.text + " built on " + Version.time_text); //$NON-NLS-1$
  160. }
  161. protected IMessageHandler getMessageHandler () {
  162. return messageHandler;
  163. }
  164. public IMessageHolder getMessageHolder () {
  165. return messageHolder;
  166. }
  167. protected void setMessageHandler (IMessageHandler mh) {
  168. if (mh instanceof ISupportsMessageContext) {
  169. ISupportsMessageContext smc = (ISupportsMessageContext)mh;
  170. smc.setMessageContext(this);
  171. }
  172. if (mh != messageHolder) messageHolder.setDelegate(mh);
  173. messageHolder.flushMessages();
  174. }
  175. protected void disable () {
  176. if (trace.isTraceEnabled()) trace.enter("disable",this);
  177. enabled = false;
  178. messageHolder.flushMessages();
  179. if (trace.isTraceEnabled()) trace.exit("disable");
  180. }
  181. protected void enable () {
  182. enabled = true;
  183. messageHolder.flushMessages();
  184. }
  185. protected boolean isEnabled () {
  186. return enabled;
  187. }
  188. /**
  189. * Appends URL to path used by the WeavingAdptor to resolve classes
  190. * @param url to be appended to search path
  191. */
  192. public void addURL(URL url) {
  193. File libFile = new File(url.getPath());
  194. try {
  195. weaver.addLibraryJarFile(libFile);
  196. }
  197. catch (IOException ex) {
  198. warn("bad library: '" + libFile + "'");
  199. }
  200. }
  201. /**
  202. * Weave a class using aspects previously supplied to the adaptor.
  203. * @param name the name of the class
  204. * @param bytes the class bytes
  205. * @return the woven bytes
  206. * @exception IOException weave failed
  207. */
  208. public byte[] weaveClass (String name, byte[] bytes) throws IOException {
  209. if (trace.isTraceEnabled()) trace.enter("weaveClass",this,new Object[] {name, bytes});
  210. if (!enabled) {
  211. if (trace.isTraceEnabled()) trace.exit("weaveClass",false);
  212. return bytes;
  213. }
  214. try {
  215. delegateForCurrentClass=null;
  216. name = name.replace('/','.');
  217. if (couldWeave(name, bytes)) {
  218. if (accept(name, bytes)) {
  219. // TODO @AspectJ problem
  220. // Annotation style aspects need to be included regardless in order to get
  221. // a valid aspectOf()/hasAspect() generated in them. However - if they are excluded
  222. // (via include/exclude in aop.xml) they really should only get aspectOf()/hasAspect()
  223. // and not be included in the full set of aspects being applied by 'this' weaver
  224. debug("weaving '" + name + "'");
  225. bytes = getWovenBytes(name, bytes);
  226. } else if (shouldWeaveAnnotationStyleAspect(name, bytes)) {
  227. // an @AspectJ aspect needs to be at least munged by the aspectOf munger
  228. debug("weaving '" + name + "'");
  229. bytes = getAtAspectJAspectBytes(name, bytes);
  230. } else {
  231. debug("not weaving '" + name + "'");
  232. }
  233. } else {
  234. debug("cannot weave '" + name + "'");
  235. }
  236. } finally {
  237. delegateForCurrentClass=null;
  238. }
  239. if (trace.isTraceEnabled()) trace.exit("weaveClass",bytes);
  240. return bytes;
  241. }
  242. /**
  243. * @param name
  244. * @return true if even valid to weave: either with an accept check or to munge it for @AspectJ aspectof support
  245. */
  246. private boolean couldWeave (String name, byte[] bytes) {
  247. return !generatedClasses.containsKey(name) && shouldWeaveName(name);
  248. }
  249. //ATAJ
  250. protected boolean accept(String name, byte[] bytes) {
  251. return true;
  252. }
  253. protected boolean shouldDump(String name, boolean before) {
  254. return false;
  255. }
  256. private boolean shouldWeaveName (String name) {
  257. boolean should =
  258. !((name.startsWith("org.aspectj.")
  259. || name.startsWith("java.")
  260. || name.startsWith("javax."))
  261. //|| name.startsWith("$Proxy")//JDK proxies//FIXME AV is that 1.3 proxy ? fe. ataspect.$Proxy0 is a java5 proxy...
  262. || name.startsWith("sun.reflect."));//JDK reflect
  263. return should;
  264. }
  265. /**
  266. * We allow @AJ aspect weaving so that we can add aspectOf() as part of the weaving
  267. * (and not part of the source compilation)
  268. *
  269. * @param name
  270. * @param bytes bytecode (from classloader), allow to NOT lookup stuff on disk again during resolve
  271. * @return true if @Aspect
  272. */
  273. private boolean shouldWeaveAnnotationStyleAspect(String name, byte[] bytes) {
  274. if (delegateForCurrentClass==null) {
  275. // if (weaver.getWorld().isASMAround()) return asmCheckAnnotationStyleAspect(bytes);
  276. // else
  277. ensureDelegateInitialized(name, bytes);
  278. }
  279. return (delegateForCurrentClass.isAnnotationStyleAspect());
  280. }
  281. // private boolean asmCheckAnnotationStyleAspect(byte[] bytes) {
  282. // IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor();
  283. //
  284. // ClassReader cr = new ClassReader(bytes);
  285. // try {
  286. // cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES);
  287. // } catch (Exception spe) {
  288. // // if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect...
  289. // System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation");
  290. // spe.printStackTrace();
  291. // return false;
  292. // }
  293. //
  294. // return detector.isAspect();
  295. // }
  296. protected void ensureDelegateInitialized(String name,byte[] bytes) {
  297. if (delegateForCurrentClass==null)
  298. delegateForCurrentClass = ((BcelWorld)weaver.getWorld()).addSourceObjectType(Utility.makeJavaClass(name, bytes));
  299. }
  300. /**
  301. * Weave a set of bytes defining a class.
  302. * @param name the name of the class being woven
  303. * @param bytes the bytes that define the class
  304. * @return byte[] the woven bytes for the class
  305. * @throws IOException
  306. */
  307. private byte[] getWovenBytes(String name, byte[] bytes) throws IOException {
  308. WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
  309. weaver.weave(wcp);
  310. weaver.getWorld().demote();
  311. return wcp.getBytes();
  312. }
  313. /**
  314. * Weave a set of bytes defining a class for only what is needed to turn @AspectJ aspect
  315. * in a usefull form ie with aspectOf method - see #113587
  316. * @param name the name of the class being woven
  317. * @param bytes the bytes that define the class
  318. * @return byte[] the woven bytes for the class
  319. * @throws IOException
  320. */
  321. private byte[] getAtAspectJAspectBytes(String name, byte[] bytes) throws IOException {
  322. WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
  323. wcp.setApplyAtAspectJMungersOnly();
  324. weaver.weave(wcp);
  325. return wcp.getBytes();
  326. }
  327. private void registerAspectLibraries(List aspectPath) {
  328. // System.err.println("? WeavingAdaptor.registerAspectLibraries(" + aspectPath + ")");
  329. for (Iterator i = aspectPath.iterator(); i.hasNext();) {
  330. String libName = (String)i.next();
  331. addAspectLibrary(libName);
  332. }
  333. weaver.prepareForWeave();
  334. }
  335. /*
  336. * Register an aspect library with this classloader for use during
  337. * weaving. This class loader will also return (unmodified) any of the
  338. * classes in the library in response to a <code>findClass()</code> request.
  339. * The library is not required to be on the weavingClasspath given when this
  340. * classloader was constructed.
  341. * @param aspectLibraryJarFile a jar file representing an aspect library
  342. * @throws IOException
  343. */
  344. private void addAspectLibrary(String aspectLibraryName) {
  345. File aspectLibrary = new File(aspectLibraryName);
  346. if (aspectLibrary.isDirectory()
  347. || (FileUtil.isZipFile(aspectLibrary))) {
  348. try {
  349. info("adding aspect library: '" + aspectLibrary + "'");
  350. weaver.addLibraryJarFile(aspectLibrary);
  351. } catch (IOException ex) {
  352. error("exception adding aspect library: '" + ex + "'");
  353. }
  354. } else {
  355. error("bad aspect library: '" + aspectLibrary + "'");
  356. }
  357. }
  358. private static List makeClasspath(String cp) {
  359. List ret = new ArrayList();
  360. if (cp != null) {
  361. StringTokenizer tok = new StringTokenizer(cp,File.pathSeparator);
  362. while (tok.hasMoreTokens()) {
  363. ret.add(tok.nextToken());
  364. }
  365. }
  366. return ret;
  367. }
  368. protected boolean debug (String message) {
  369. return MessageUtil.debug(messageHandler,message);
  370. }
  371. protected boolean info (String message) {
  372. return MessageUtil.info(messageHandler,message);
  373. }
  374. protected boolean warn (String message) {
  375. return MessageUtil.warn(messageHandler,message);
  376. }
  377. protected boolean warn (String message, Throwable th) {
  378. return messageHandler.handleMessage(new Message(message, IMessage.WARNING, th, null));
  379. }
  380. protected boolean error (String message) {
  381. return MessageUtil.error(messageHandler,message);
  382. }
  383. protected boolean error (String message, Throwable th) {
  384. return messageHandler.handleMessage(new Message(message, IMessage.ERROR, th, null));
  385. }
  386. public String getContextId () {
  387. return "WeavingAdaptor";
  388. }
  389. /**
  390. * Dump the given bytcode in _dump/... (dev mode)
  391. *
  392. * @param name
  393. * @param b
  394. * @param before whether we are dumping before weaving
  395. * @throws Throwable
  396. */
  397. protected void dump(String name, byte[] b, boolean before) {
  398. String dirName = "_ajdump";
  399. if (before) dirName = dirName + File.separator + "_before";
  400. String className = name.replace('.', '/');
  401. final File dir;
  402. if (className.indexOf('/') > 0) {
  403. dir = new File(dirName + File.separator + className.substring(0, className.lastIndexOf('/')));
  404. } else {
  405. dir = new File(dirName);
  406. }
  407. dir.mkdirs();
  408. String fileName = dirName + File.separator + className + ".class";
  409. try {
  410. // System.out.println("WeavingAdaptor.dump() fileName=" + new File(fileName).getAbsolutePath());
  411. FileOutputStream os = new FileOutputStream(fileName);
  412. os.write(b);
  413. os.close();
  414. }
  415. catch (IOException ex) {
  416. warn("unable to dump class " + name + " in directory " + dirName,ex);
  417. }
  418. }
  419. /**
  420. * Processes messages arising from weaver operations.
  421. * Tell weaver to abort on any message more severe than warning.
  422. */
  423. protected class WeavingAdaptorMessageHolder extends MessageHandler {
  424. private IMessageHandler delegate;
  425. private List savedMessages;
  426. protected boolean traceMessages = Boolean.getBoolean(TRACE_MESSAGES_PROPERTY);
  427. public WeavingAdaptorMessageHolder (PrintWriter writer) {
  428. this.delegate = new WeavingAdaptorMessageWriter(writer);
  429. super.dontIgnore(IMessage.WEAVEINFO);
  430. }
  431. private void traceMessage (IMessage message) {
  432. if (message instanceof WeaveMessage) {
  433. trace.debug(render(message));
  434. }
  435. else if (message.isDebug()) {
  436. trace.debug(render(message));
  437. }
  438. else if (message.isInfo()) {
  439. trace.info(render(message));
  440. }
  441. else if (message.isWarning()) {
  442. trace.warn(render(message),message.getThrown());
  443. }
  444. else if (message.isError()) {
  445. trace.error(render(message),message.getThrown());
  446. }
  447. else if (message.isFailed()) {
  448. trace.fatal(render(message),message.getThrown());
  449. }
  450. else if (message.isAbort()) {
  451. trace.fatal(render(message),message.getThrown());
  452. }
  453. else {
  454. trace.error(render(message),message.getThrown());
  455. }
  456. }
  457. protected String render(IMessage message) {
  458. return "[" + getContextId() + "] " + message.toString();
  459. }
  460. public void flushMessages () {
  461. if (savedMessages == null) {
  462. savedMessages = new ArrayList();
  463. savedMessages.addAll(super.getUnmodifiableListView());
  464. clearMessages();
  465. for (Iterator iter = savedMessages.iterator(); iter.hasNext();) {
  466. IMessage message = (IMessage)iter.next();
  467. delegate.handleMessage(message);
  468. }
  469. }
  470. // accumulating = false;
  471. // messages.clear();
  472. }
  473. public void setDelegate (IMessageHandler messageHandler) {
  474. delegate = messageHandler;
  475. }
  476. /*
  477. * IMessageHandler
  478. */
  479. public boolean handleMessage(IMessage message) throws AbortException {
  480. if (traceMessages) traceMessage(message);
  481. super.handleMessage(message);
  482. if (abortOnError && 0 <= message.getKind().compareTo(IMessage.ERROR)) {
  483. throw new AbortException(message);
  484. }
  485. // if (accumulating) {
  486. // boolean result = addMessage(message);
  487. // if (abortOnError && 0 <= message.getKind().compareTo(IMessage.ERROR)) {
  488. // throw new AbortException(message);
  489. // }
  490. // return result;
  491. // }
  492. // else return delegate.handleMessage(message);
  493. if (savedMessages != null) delegate.handleMessage(message);
  494. return true;
  495. }
  496. public boolean isIgnoring (Kind kind) {
  497. return delegate.isIgnoring(kind);
  498. }
  499. public void dontIgnore (IMessage.Kind kind) {
  500. if (null != kind && delegate != null) {
  501. delegate.dontIgnore(kind);
  502. }
  503. }
  504. public void ignore(Kind kind) {
  505. if (null != kind && delegate != null) {
  506. delegate.ignore(kind);
  507. }
  508. }
  509. /*
  510. * IMessageHolder
  511. */
  512. public List getUnmodifiableListView() {
  513. // System.err.println("? WeavingAdaptorMessageHolder.getUnmodifiableListView() savedMessages=" + savedMessages);
  514. List allMessages = new ArrayList();
  515. allMessages.addAll(savedMessages);
  516. allMessages.addAll(super.getUnmodifiableListView());
  517. return allMessages;
  518. }
  519. }
  520. protected class WeavingAdaptorMessageWriter extends MessageWriter {
  521. private Set ignoring = new HashSet();
  522. private IMessage.Kind failKind;
  523. public WeavingAdaptorMessageWriter (PrintWriter writer) {
  524. super(writer,true);
  525. ignore(IMessage.WEAVEINFO);
  526. ignore(IMessage.DEBUG);
  527. ignore(IMessage.INFO);
  528. this.failKind = IMessage.ERROR;
  529. }
  530. public boolean handleMessage(IMessage message) throws AbortException {
  531. boolean result = super.handleMessage(message);
  532. if (abortOnError && 0 <= message.getKind().compareTo(failKind)) {
  533. throw new AbortException(message);
  534. }
  535. return true;
  536. }
  537. public boolean isIgnoring (Kind kind) {
  538. return ((null != kind) && (ignoring.contains(kind)));
  539. }
  540. /**
  541. * Set a message kind to be ignored from now on
  542. */
  543. public void ignore (IMessage.Kind kind) {
  544. if ((null != kind) && (!ignoring.contains(kind))) {
  545. ignoring.add(kind);
  546. }
  547. }
  548. /**
  549. * Remove a message kind from the list of those ignored from now on.
  550. */
  551. public void dontIgnore (IMessage.Kind kind) {
  552. if (null != kind) {
  553. ignoring.remove(kind);
  554. }
  555. }
  556. protected String render(IMessage message) {
  557. return "[" + getContextId() + "] " + super.render(message);
  558. }
  559. }
  560. private class WeavingClassFileProvider implements IClassFileProvider {
  561. private UnwovenClassFile unwovenClass;
  562. private List unwovenClasses = new ArrayList(); /* List<UnovenClassFile> */
  563. private UnwovenClassFile wovenClass;
  564. private boolean isApplyAtAspectJMungersOnly = false;
  565. public WeavingClassFileProvider (String name, byte[] bytes) {
  566. ensureDelegateInitialized(name, bytes);
  567. this.unwovenClass = new UnwovenClassFile(name,delegateForCurrentClass.getResolvedTypeX().getName(),bytes);
  568. this.unwovenClasses.add(unwovenClass);
  569. if (shouldDump(name.replace('/', '.'),true)) {
  570. dump(name, bytes, true);
  571. }
  572. }
  573. public void setApplyAtAspectJMungersOnly() {
  574. isApplyAtAspectJMungersOnly = true;
  575. }
  576. public boolean isApplyAtAspectJMungersOnly() {
  577. return isApplyAtAspectJMungersOnly;
  578. }
  579. public byte[] getBytes () {
  580. if (wovenClass != null) return wovenClass.getBytes();
  581. else return unwovenClass.getBytes();
  582. }
  583. public Iterator getClassFileIterator() {
  584. return unwovenClasses.iterator();
  585. }
  586. public IWeaveRequestor getRequestor() {
  587. return new IWeaveRequestor() {
  588. public void acceptResult(UnwovenClassFile result) {
  589. if (wovenClass == null) {
  590. wovenClass = result;
  591. String name = result.getClassName();
  592. if (shouldDump(name.replace('/', '.'), false)) {
  593. dump(name, result.getBytes(), false);
  594. }
  595. }
  596. /* Classes generated by weaver e.g. around closure advice */
  597. else {
  598. String className = result.getClassName();
  599. generatedClasses.put(className,result);
  600. generatedClasses.put(wovenClass.getClassName(),result);
  601. generatedClassHandler.acceptClass(className,result.getBytes());
  602. }
  603. }
  604. public void processingReweavableState() { }
  605. public void addingTypeMungers() {}
  606. public void weavingAspects() {}
  607. public void weavingClasses() {}
  608. public void weaveCompleted() {
  609. ResolvedType.resetPrimitives();
  610. if (delegateForCurrentClass!=null) delegateForCurrentClass.weavingCompleted();
  611. ResolvedType.resetPrimitives();
  612. //bcelWorld.discardType(typeBeingProcessed.getResolvedTypeX()); // work in progress
  613. }
  614. };
  615. }
  616. }
  617. }