Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

WeavingAdaptor.java 22KB

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