Logo Search packages:      
Sourcecode: aspectj version File versions

WeavingAdaptor.java

/* *******************************************************************
 * Copyright (c) 2004 IBM Corporation
 * All rights reserved. 
 * This program and the accompanying materials are made available 
 * under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 *  
 * Contributors: 
 *     Matthew Webster, Adrian Colyer, 
 *     Martin Lippert     initial implementation 
 * ******************************************************************/

package org.aspectj.weaver.tools;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import org.aspectj.bridge.AbortException;
import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.IMessageContext;
import org.aspectj.bridge.IMessageHandler;
import org.aspectj.bridge.IMessageHolder;
import org.aspectj.bridge.Message;
import org.aspectj.bridge.MessageHandler;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.bridge.MessageWriter;
import org.aspectj.bridge.Version;
import org.aspectj.bridge.WeaveMessage;
import org.aspectj.bridge.IMessage.Kind;
import org.aspectj.util.FileUtil;
import org.aspectj.util.LangUtil;
import org.aspectj.weaver.IClassFileProvider;
import org.aspectj.weaver.IUnwovenClassFile;
import org.aspectj.weaver.IWeaveRequestor;
import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.World;
import org.aspectj.weaver.bcel.BcelObjectType;
import org.aspectj.weaver.bcel.BcelWeaver;
import org.aspectj.weaver.bcel.BcelWorld;
import org.aspectj.weaver.bcel.UnwovenClassFile;
import org.aspectj.weaver.bcel.Utility;

// OPTIMIZE add guards for all the debug/info/etc
/**
 * This adaptor allows the AspectJ compiler to be embedded in an existing system to facilitate load-time weaving. It provides an
 * interface for a weaving class loader to provide a classpath to be woven by a set of aspects. A callback is supplied to allow a
 * class loader to define classes generated by the compiler during the weaving process.
 * <p>
 * A weaving class loader should create a <code>WeavingAdaptor</code> before any classes are defined, typically during construction.
 * The set of aspects passed to the adaptor is fixed for the lifetime of the adaptor although the classpath can be augmented. A
 * system property can be set to allow verbose weaving messages to be written to the console.
 * 
 */
00069 public class WeavingAdaptor implements IMessageContext {

      /**
       * System property used to turn on verbose weaving messages
       */
00074       public static final String WEAVING_ADAPTOR_VERBOSE = "aj.weaving.verbose";
      public static final String SHOW_WEAVE_INFO_PROPERTY = "org.aspectj.weaver.showWeaveInfo";
      public static final String TRACE_MESSAGES_PROPERTY = "org.aspectj.tracing.messages";

      private boolean enabled = false;
      protected boolean verbose = getVerbose();
      protected BcelWorld bcelWorld;
      protected BcelWeaver weaver;
      private IMessageHandler messageHandler;
      private WeavingAdaptorMessageHolder messageHolder;
      private boolean abortOnError = false;
      protected GeneratedClassHandler generatedClassHandler;
      protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */
      protected BcelObjectType delegateForCurrentClass; // lazily initialized, should be used to prevent parsing bytecode multiple
      // times

      private boolean haveWarnedOnJavax = false;

      private int weavingSpecialTypes = 0;
      private static final int INITIALIZED = 0x1;
      private static final int WEAVE_JAVA_PACKAGE = 0x2;
      private static final int WEAVE_JAVAX_PACKAGE = 0x4;

      private static Trace trace = TraceFactory.getTraceFactory().getTrace(WeavingAdaptor.class);

      protected WeavingAdaptor() {
      }

      /**
       * Construct a WeavingAdaptor with a reference to a weaving class loader. The adaptor will automatically search the class loader
       * hierarchy to resolve classes. The adaptor will also search the hierarchy for WeavingClassLoader instances to determine the
       * set of aspects to be used ofr weaving.
       * 
       * @param loader instance of <code>ClassLoader</code>
       */
00109       public WeavingAdaptor(WeavingClassLoader loader) {
            // System.err.println("? WeavingAdaptor.<init>(" + loader +"," + aspectURLs.length + ")");
            generatedClassHandler = loader;
            init(getFullClassPath((ClassLoader) loader), getFullAspectPath((ClassLoader) loader/* ,aspectURLs */));
      }

      /**
       * Construct a WeavingAdator with a reference to a <code>GeneratedClassHandler</code>, a full search path for resolving classes
       * and a complete set of aspects. The search path must include classes loaded by the class loader constructing the
       * WeavingAdaptor and all its parents in the hierarchy.
       * 
       * @param handler <code>GeneratedClassHandler</code>
       * @param classURLs the URLs from which to resolve classes
       * @param aspectURLs the aspects used to weave classes defined by this class loader
       */
00124       public WeavingAdaptor(GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs) {
            // System.err.println("? WeavingAdaptor.<init>()");
            generatedClassHandler = handler;
            init(FileUtil.makeClasspath(classURLs), FileUtil.makeClasspath(aspectURLs));
      }

      private List getFullClassPath(ClassLoader loader) {
            List list = new LinkedList();
            for (; loader != null; loader = loader.getParent()) {
                  if (loader instanceof URLClassLoader) {
                        URL[] urls = ((URLClassLoader) loader).getURLs();
                        list.addAll(0, FileUtil.makeClasspath(urls));
                  } else {
                        warn("cannot determine classpath");
                  }
            }

            list.addAll(0, makeClasspath(System.getProperty("sun.boot.class.path")));

            return list;
      }

      private List getFullAspectPath(ClassLoader loader) {
            List list = new LinkedList();
            for (; loader != null; loader = loader.getParent()) {
                  if (loader instanceof WeavingClassLoader) {
                        URL[] urls = ((WeavingClassLoader) loader).getAspectURLs();
                        list.addAll(0, FileUtil.makeClasspath(urls));
                  }
            }

            return list;
      }

      private static boolean getVerbose() {
            return Boolean.getBoolean(WEAVING_ADAPTOR_VERBOSE);
      }

      private void init(List classPath, List aspectPath) {
            abortOnError = true;
            createMessageHandler();

            info("using classpath: " + classPath);
            info("using aspectpath: " + aspectPath);

            bcelWorld = new BcelWorld(classPath, messageHandler, null);
            bcelWorld.setXnoInline(false);
            bcelWorld.getLint().loadDefaultProperties();
            if (LangUtil.is15VMOrGreater()) {
                  bcelWorld.setBehaveInJava5Way(true);
            }

            weaver = new BcelWeaver(bcelWorld);
            registerAspectLibraries(aspectPath);

            enabled = true;
      }

      protected void createMessageHandler() {
            messageHolder = new WeavingAdaptorMessageHolder(new PrintWriter(System.err));
            messageHandler = messageHolder;
            if (verbose)
                  messageHandler.dontIgnore(IMessage.INFO);
            if (Boolean.getBoolean(SHOW_WEAVE_INFO_PROPERTY))
                  messageHandler.dontIgnore(IMessage.WEAVEINFO);
            info("AspectJ Weaver Version " + Version.text + " built on " + Version.time_text); //$NON-NLS-1$
      }

      protected IMessageHandler getMessageHandler() {
            return messageHandler;
      }

      public IMessageHolder getMessageHolder() {
            return messageHolder;
      }

      protected void setMessageHandler(IMessageHandler mh) {
            if (mh instanceof ISupportsMessageContext) {
                  ISupportsMessageContext smc = (ISupportsMessageContext) mh;
                  smc.setMessageContext(this);
            }
            if (mh != messageHolder)
                  messageHolder.setDelegate(mh);
            messageHolder.flushMessages();
      }

      protected void disable() {
            if (trace.isTraceEnabled())
                  trace.enter("disable", this);

            enabled = false;
            messageHolder.flushMessages();

            if (trace.isTraceEnabled())
                  trace.exit("disable");
      }

      protected void enable() {
            enabled = true;
            messageHolder.flushMessages();
      }

      protected boolean isEnabled() {
            return enabled;
      }

      /**
       * Appends URL to path used by the WeavingAdptor to resolve classes
       * 
       * @param url to be appended to search path
       */
00235       public void addURL(URL url) {
            File libFile = new File(url.getPath());
            try {
                  weaver.addLibraryJarFile(libFile);
            } catch (IOException ex) {
                  warn("bad library: '" + libFile + "'");
            }
      }

      /**
       * Weave a class using aspects previously supplied to the adaptor.
       * 
       * @param name the name of the class
       * @param bytes the class bytes
       * @return the woven bytes
       * @exception IOException weave failed
       */
00252       public byte[] weaveClass(String name, byte[] bytes) throws IOException {
            return weaveClass(name, bytes, false);
      }

      /**
       * Weave a class using aspects previously supplied to the adaptor.
       * 
       * @param name the name of the class
       * @param bytes the class bytes
       * @param mustWeave if true then this class *must* get woven (used for concrete aspects generated from XML)
       * @return the woven bytes
       * @exception IOException weave failed
       */
00265       public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException {
            if (trace.isTraceEnabled())
                  trace.enter("weaveClass", this, new Object[] { name, bytes });

            if (!enabled) {
                  if (trace.isTraceEnabled())
                        trace.exit("weaveClass", false);
                  return bytes;
            }

            try {
                  delegateForCurrentClass = null;
                  name = name.replace('/', '.');
                  if (couldWeave(name, bytes)) {
                        if (accept(name, bytes)) {
                              // TODO @AspectJ problem
                              // Annotation style aspects need to be included regardless in order to get
                              // a valid aspectOf()/hasAspect() generated in them. However - if they are excluded
                              // (via include/exclude in aop.xml) they really should only get aspectOf()/hasAspect()
                              // and not be included in the full set of aspects being applied by 'this' weaver
                              debug("weaving '" + name + "'");
                              bytes = getWovenBytes(name, bytes);
                        } else if (shouldWeaveAnnotationStyleAspect(name, bytes)) {
                              if (mustWeave) {
                                    if (bcelWorld.getLint().mustWeaveXmlDefinedAspects.isEnabled()) {
                                          bcelWorld.getLint().mustWeaveXmlDefinedAspects.signal(name, null);
                                    }
                              }
                              // an @AspectJ aspect needs to be at least munged by the aspectOf munger
                              debug("weaving '" + name + "'");
                              bytes = getAtAspectJAspectBytes(name, bytes);
                        } else {
                              debug("not weaving '" + name + "'");
                        }
                  } else {
                        debug("cannot weave '" + name + "'");
                  }
            } finally {
                  delegateForCurrentClass = null;
            }

            if (trace.isTraceEnabled())
                  trace.exit("weaveClass", bytes);
            return bytes;
      }

      /**
       * @param name
       * @return true if even valid to weave: either with an accept check or to munge it for @AspectJ aspectof support
       */
00315       private boolean couldWeave(String name, byte[] bytes) {
            return !generatedClasses.containsKey(name) && shouldWeaveName(name);
      }

      // ATAJ
      protected boolean accept(String name, byte[] bytes) {
            return true;
      }

      protected boolean shouldDump(String name, boolean before) {
            return false;
      }

      private boolean shouldWeaveName(String name) {
            if ((weavingSpecialTypes & INITIALIZED) == 0) {
                  weavingSpecialTypes |= INITIALIZED;
                  // initialize it
                  Properties p = weaver.getWorld().getExtraConfiguration();
                  if (p != null) {
                        boolean b = p.getProperty(World.xsetWEAVE_JAVA_PACKAGES, "false").equalsIgnoreCase("true");
                        if (b) {
                              weavingSpecialTypes |= WEAVE_JAVA_PACKAGE;
                        }
                        b = p.getProperty(World.xsetWEAVE_JAVAX_PACKAGES, "false").equalsIgnoreCase("true");
                        if (b) {
                              weavingSpecialTypes |= WEAVE_JAVAX_PACKAGE;
                        }
                  }
            }
            if (name.startsWith("org.aspectj.")) {
                  return false;
            }
            if (name.startsWith("sun.reflect.")) {// JDK reflect
                  return false;
            }
            if (name.startsWith("javax.")) {
                  if ((weavingSpecialTypes & WEAVE_JAVAX_PACKAGE) != 0) {
                        return true;
                  } else {
                        if (!haveWarnedOnJavax) {
                              haveWarnedOnJavax = true;
                              warn("javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified");
                        }
                        return false;
                  }
            }
            if (name.startsWith("java.")) {
                  if ((weavingSpecialTypes & WEAVE_JAVA_PACKAGE) != 0) {
                        return true;
                  } else {
                        return false;
                  }
            }
            // boolean should = !(name.startsWith("org.aspectj.")
            // || (name.startsWith("java.") && (weavingSpecialTypes & WEAVE_JAVA_PACKAGE) == 0)
            // || (name.startsWith("javax.") && (weavingSpecialTypes & WEAVE_JAVAX_PACKAGE) == 0)
            // // || name.startsWith("$Proxy")//JDK proxies//FIXME AV is that 1.3 proxy ? fe. ataspect.$Proxy0 is a java5 proxy...
            // || name.startsWith("sun.reflect."));
            return true;
      }

      /**
       * We allow @AJ aspect weaving so that we can add aspectOf() as part of the weaving (and not part of the source compilation)
       * 
       * @param name
       * @param bytes bytecode (from classloader), allow to NOT lookup stuff on disk again during resolve
       * @return true if @Aspect
       */
00383       private boolean shouldWeaveAnnotationStyleAspect(String name, byte[] bytes) {
            if (delegateForCurrentClass == null) {
                  // if (weaver.getWorld().isASMAround()) return asmCheckAnnotationStyleAspect(bytes);
                  // else
                  ensureDelegateInitialized(name, bytes);
            }
            return (delegateForCurrentClass.isAnnotationStyleAspect());
      }

      // private boolean asmCheckAnnotationStyleAspect(byte[] bytes) {
      // IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor();
      //
      // ClassReader cr = new ClassReader(bytes);
      // try {
      // cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES);
      // } catch (Exception spe) {
      // // if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect...
      // System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation");
      // spe.printStackTrace();
      // return false;
      // }
      //        
      // return detector.isAspect();
      // }

      protected void ensureDelegateInitialized(String name, byte[] bytes) {
            if (delegateForCurrentClass == null)
                  delegateForCurrentClass = ((BcelWorld) weaver.getWorld()).addSourceObjectType(Utility.makeJavaClass(name, bytes));
      }

      /**
       * Weave a set of bytes defining a class.
       * 
       * @param name the name of the class being woven
       * @param bytes the bytes that define the class
       * @return byte[] the woven bytes for the class
       * @throws IOException
       */
00421       private byte[] getWovenBytes(String name, byte[] bytes) throws IOException {
            WeavingClassFileProvider wcp = new WeavingClassFileProvider(name, bytes);
            weaver.weave(wcp);
            return wcp.getBytes();
      }

      /**
       * Weave a set of bytes defining a class for only what is needed to turn @AspectJ aspect in a usefull form ie with aspectOf
       * method - see #113587
       * 
       * @param name the name of the class being woven
       * @param bytes the bytes that define the class
       * @return byte[] the woven bytes for the class
       * @throws IOException
       */
00436       private byte[] getAtAspectJAspectBytes(String name, byte[] bytes) throws IOException {
            WeavingClassFileProvider wcp = new WeavingClassFileProvider(name, bytes);
            wcp.setApplyAtAspectJMungersOnly();
            weaver.weave(wcp);
            return wcp.getBytes();
      }

      private void registerAspectLibraries(List aspectPath) {
            // System.err.println("? WeavingAdaptor.registerAspectLibraries(" + aspectPath + ")");
            for (Iterator i = aspectPath.iterator(); i.hasNext();) {
                  String libName = (String) i.next();
                  addAspectLibrary(libName);
            }

            weaver.prepareForWeave();
      }

      /*
       * Register an aspect library with this classloader for use during weaving. This class loader will also return (unmodified) any
       * of the classes in the library in response to a <code>findClass()</code> request. The library is not required to be on the
       * weavingClasspath given when this classloader was constructed.
       * 
       * @param aspectLibraryJarFile a jar file representing an aspect library
       * 
       * @throws IOException
       */
      private void addAspectLibrary(String aspectLibraryName) {
            File aspectLibrary = new File(aspectLibraryName);
            if (aspectLibrary.isDirectory() || (FileUtil.isZipFile(aspectLibrary))) {
                  try {
                        info("adding aspect library: '" + aspectLibrary + "'");
                        weaver.addLibraryJarFile(aspectLibrary);
                  } catch (IOException ex) {
                        error("exception adding aspect library: '" + ex + "'");
                  }
            } else {
                  error("bad aspect library: '" + aspectLibrary + "'");
            }
      }

      private static List makeClasspath(String cp) {
            List ret = new ArrayList();
            if (cp != null) {
                  StringTokenizer tok = new StringTokenizer(cp, File.pathSeparator);
                  while (tok.hasMoreTokens()) {
                        ret.add(tok.nextToken());
                  }
            }
            return ret;
      }

      protected boolean debug(String message) {
            return MessageUtil.debug(messageHandler, message);
      }

      protected boolean info(String message) {
            return MessageUtil.info(messageHandler, message);
      }

      protected boolean warn(String message) {
            return MessageUtil.warn(messageHandler, message);
      }

      protected boolean warn(String message, Throwable th) {
            return messageHandler.handleMessage(new Message(message, IMessage.WARNING, th, null));
      }

      protected boolean error(String message) {
            return MessageUtil.error(messageHandler, message);
      }

      protected boolean error(String message, Throwable th) {
            return messageHandler.handleMessage(new Message(message, IMessage.ERROR, th, null));
      }

      public String getContextId() {
            return "WeavingAdaptor";
      }

      /**
       * Dump the given bytcode in _dump/... (dev mode)
       * 
       * @param name
       * @param b
       * @param before whether we are dumping before weaving
       * @throws Throwable
       */
00523       protected void dump(String name, byte[] b, boolean before) {
            String dirName = getDumpDir();

            if (before)
                  dirName = dirName + File.separator + "_before";

            String className = name.replace('.', '/');
            final File dir;
            if (className.indexOf('/') > 0) {
                  dir = new File(dirName + File.separator + className.substring(0, className.lastIndexOf('/')));
            } else {
                  dir = new File(dirName);
            }
            dir.mkdirs();
            String fileName = dirName + File.separator + className + ".class";
            try {
                  // System.out.println("WeavingAdaptor.dump() fileName=" + new File(fileName).getAbsolutePath());
                  FileOutputStream os = new FileOutputStream(fileName);
                  os.write(b);
                  os.close();
            } catch (IOException ex) {
                  warn("unable to dump class " + name + " in directory " + dirName, ex);
            }
      }

      /**
       * @return the directory in which to dump - default is _ajdump but it
       */
00551       protected String getDumpDir() {
            return "_ajdump";
      }

      /**
       * Processes messages arising from weaver operations. Tell weaver to abort on any message more severe than warning.
       */
00558       protected class WeavingAdaptorMessageHolder extends MessageHandler {

            private IMessageHandler delegate;
            private List savedMessages;

            protected boolean traceMessages = Boolean.getBoolean(TRACE_MESSAGES_PROPERTY);

            public WeavingAdaptorMessageHolder(PrintWriter writer) {

                  this.delegate = new WeavingAdaptorMessageWriter(writer);
                  super.dontIgnore(IMessage.WEAVEINFO);
            }

            private void traceMessage(IMessage message) {
                  if (message instanceof WeaveMessage) {
                        trace.debug(render(message));
                  } else if (message.isDebug()) {
                        trace.debug(render(message));
                  } else if (message.isInfo()) {
                        trace.info(render(message));
                  } else if (message.isWarning()) {
                        trace.warn(render(message), message.getThrown());
                  } else if (message.isError()) {
                        trace.error(render(message), message.getThrown());
                  } else if (message.isFailed()) {
                        trace.fatal(render(message), message.getThrown());
                  } else if (message.isAbort()) {
                        trace.fatal(render(message), message.getThrown());
                  } else {
                        trace.error(render(message), message.getThrown());
                  }
            }

            protected String render(IMessage message) {
                  return "[" + getContextId() + "] " + message.toString();
            }

            public void flushMessages() {
                  if (savedMessages == null) {
                        savedMessages = new ArrayList();
                        savedMessages.addAll(super.getUnmodifiableListView());
                        clearMessages();
                        for (Iterator iter = savedMessages.iterator(); iter.hasNext();) {
                              IMessage message = (IMessage) iter.next();
                              delegate.handleMessage(message);
                        }
                  }
                  // accumulating = false;
                  // messages.clear();
            }

            public void setDelegate(IMessageHandler messageHandler) {
                  delegate = messageHandler;
            }

            /*
             * IMessageHandler
             */

00617             public boolean handleMessage(IMessage message) throws AbortException {
                  if (traceMessages)
                        traceMessage(message);

                  super.handleMessage(message);

                  if (abortOnError && 0 <= message.getKind().compareTo(IMessage.ERROR)) {
                        throw new AbortException(message);
                  }
                  // if (accumulating) {
                  // boolean result = addMessage(message);
                  // if (abortOnError && 0 <= message.getKind().compareTo(IMessage.ERROR)) {
                  // throw new AbortException(message);
                  // }
                  // return result;
                  // }
                  // else return delegate.handleMessage(message);

                  if (savedMessages != null)
                        delegate.handleMessage(message);
                  return true;
            }

            public boolean isIgnoring(Kind kind) {
                  return delegate.isIgnoring(kind);
            }

00644             public void dontIgnore(IMessage.Kind kind) {
                  if (null != kind && delegate != null) {
                        delegate.dontIgnore(kind);
                  }
            }

            public void ignore(Kind kind) {
                  if (null != kind && delegate != null) {
                        delegate.ignore(kind);
                  }
            }

            /*
             * IMessageHolder
             */

00660             public List getUnmodifiableListView() {
                  // System.err.println("? WeavingAdaptorMessageHolder.getUnmodifiableListView() savedMessages=" + savedMessages);
                  List allMessages = new ArrayList();
                  allMessages.addAll(savedMessages);
                  allMessages.addAll(super.getUnmodifiableListView());
                  return allMessages;
            }
      }

      protected class WeavingAdaptorMessageWriter extends MessageWriter {

            private final Set ignoring = new HashSet();
            private final IMessage.Kind failKind;

            public WeavingAdaptorMessageWriter(PrintWriter writer) {
                  super(writer, true);

                  ignore(IMessage.WEAVEINFO);
                  ignore(IMessage.DEBUG);
                  ignore(IMessage.INFO);
                  this.failKind = IMessage.ERROR;
            }

            public boolean handleMessage(IMessage message) throws AbortException {
                  // boolean result =
                  super.handleMessage(message);
                  if (abortOnError && 0 <= message.getKind().compareTo(failKind)) {
                        throw new AbortException(message);
                  }
                  return true;
            }

            public boolean isIgnoring(Kind kind) {
                  return ((null != kind) && (ignoring.contains(kind)));
            }

            /**
             * Set a message kind to be ignored from now on
             */
            public void ignore(IMessage.Kind kind) {
                  if ((null != kind) && (!ignoring.contains(kind))) {
                        ignoring.add(kind);
                  }
            }

            /**
             * Remove a message kind from the list of those ignored from now on.
             */
            public void dontIgnore(IMessage.Kind kind) {
                  if (null != kind) {
                        ignoring.remove(kind);
                  }
            }

            protected String render(IMessage message) {
                  return "[" + getContextId() + "] " + super.render(message);
            }
      }

      private class WeavingClassFileProvider implements IClassFileProvider {

            private final UnwovenClassFile unwovenClass;
            private final List unwovenClasses = new ArrayList(); /* List<UnovenClassFile> */
            private IUnwovenClassFile wovenClass;
            private boolean isApplyAtAspectJMungersOnly = false;

            public WeavingClassFileProvider(String name, byte[] bytes) {
                  ensureDelegateInitialized(name, bytes);
                  this.unwovenClass = new UnwovenClassFile(name, delegateForCurrentClass.getResolvedTypeX().getName(), bytes);
                  this.unwovenClasses.add(unwovenClass);

                  if (shouldDump(name.replace('/', '.'), true)) {
                        dump(name, bytes, true);
                  }

            }

            public void setApplyAtAspectJMungersOnly() {
                  isApplyAtAspectJMungersOnly = true;
            }

            public boolean isApplyAtAspectJMungersOnly() {
                  return isApplyAtAspectJMungersOnly;
            }

            public byte[] getBytes() {
                  if (wovenClass != null)
                        return wovenClass.getBytes();
                  else
                        return unwovenClass.getBytes();
            }

            public Iterator getClassFileIterator() {
                  return unwovenClasses.iterator();
            }

            public IWeaveRequestor getRequestor() {
                  return new IWeaveRequestor() {

                        public void acceptResult(IUnwovenClassFile result) {
                              if (wovenClass == null) {
                                    wovenClass = result;

                                    String name = result.getClassName();
                                    if (shouldDump(name.replace('/', '.'), false)) {
                                          dump(name, result.getBytes(), false);
                                    }
                              }

                              /* Classes generated by weaver e.g. around closure advice */
                              else {
                                    String className = result.getClassName();
                                    generatedClasses.put(className, result);
                                    generatedClasses.put(wovenClass.getClassName(), result);
                                    generatedClassHandler.acceptClass(className, result.getBytes());
                              }
                        }

                        public void processingReweavableState() {
                        }

                        public void addingTypeMungers() {
                        }

                        public void weavingAspects() {
                        }

                        public void weavingClasses() {
                        }

                        public void weaveCompleted() {
                              ResolvedType.resetPrimitives();
                              if (delegateForCurrentClass != null)
                                    delegateForCurrentClass.weavingCompleted();
                              ResolvedType.resetPrimitives();
                              // bcelWorld.discardType(typeBeingProcessed.getResolvedTypeX()); // work in progress
                        }
                  };
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index