Package org.aspectj.weaver.tools

Source Code of org.aspectj.weaver.tools.WeavingAdaptor$WeavingClassFileProvider

/* *******************************************************************
* 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.security.ProtectionDomain;
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.IMessage.Kind;
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.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.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;

// 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.
*
*/
public class WeavingAdaptor implements IMessageContext {

  /**
   * System property used to turn on verbose weaving messages
   */
  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<String, IUnwovenClassFile> generatedClasses = new HashMap<String, IUnwovenClassFile>();
  public BcelObjectType delegateForCurrentClass; // lazily initialized, should be used to prevent parsing bytecode multiple
  // times
  protected ProtectionDomain activeProtectionDomain;

  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>
   */
  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
   */
  public WeavingAdaptor(GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs) {
    // System.err.println("? WeavingAdaptor.<init>()");
    generatedClassHandler = handler;
    init(FileUtil.makeClasspath(classURLs), FileUtil.makeClasspath(aspectURLs));
  }

  private List<String> getFullClassPath(ClassLoader loader) {
    List<String> list = new LinkedList<String>();
    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<String> getFullAspectPath(ClassLoader loader) {
    List<String> list = new LinkedList<String>();
    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() {
    try {
      return Boolean.getBoolean(WEAVING_ADAPTOR_VERBOSE);
    } catch (Throwable t) {
      // security exception
      return false;
    }
  }

  private void init(List<String> classPath, List<String> 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
   */
  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
   */
  public byte[] weaveClass(String name, byte[] bytes) throws IOException {
    return weaveClass(name, bytes, false);
  }

  // Track if the weaver is already running on this thread - don't allow re-entrant calls
  private ThreadLocal<Boolean> weaverRunning = new ThreadLocal<Boolean>() {
    @Override
    protected Boolean initialValue() {
      return Boolean.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
   */
  public byte[] weaveClass(String name, byte[] bytes, boolean mustWeave) throws IOException {
    if (trace == null) {
      // Pr231945: we are likely to be under tomcat and ENABLE_CLEAR_REFERENCES hasn't been set
      System.err
          .println("AspectJ Weaver cannot continue to weave, static state has been cleared.  Are you under Tomcat? In order to weave '"
              + name
              + "' during shutdown, 'org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false' must be set (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=231945).");
      return bytes;
    }
    if (weaverRunning.get()) {
      // System.out.println("AJC: avoiding re-entrant call to transform " + name);
      return bytes;
    }
    try {
      weaverRunning.set(true);
      if (trace.isTraceEnabled()) {
        trace.enter("weaveClass", this, new Object[] { name, bytes });
      }

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

      boolean debugOn = !messageHandler.isIgnoring(Message.DEBUG);

      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
            if (debugOn) {
              debug("weaving '" + name + "'");
            }
            bytes = getWovenBytes(name, bytes);
            // temporarily out - searching for @Aspect annotated types is a slow thing to do - we should
            // expect the user to name them if they want them woven - just like code style
            // } 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
            // if (debugOn) {
            // debug("weaving '" + name + "'");
            // }
            // bytes = getAtAspectJAspectBytes(name, bytes);
          } else if (debugOn) {
            debug("not weaving '" + name + "'");
          }
        } else if (debugOn) {
          debug("cannot weave '" + name + "'");
        }
      } finally {
        delegateForCurrentClass = null;
      }

      if (trace.isTraceEnabled()) {
        trace.exit("weaveClass", bytes);
      }
      return bytes;
    } finally {
      weaverRunning.set(false);
    }
  }

  /**
   * @param name
   * @return true if even valid to weave: either with an accept check or to munge it for @AspectJ aspectof support
   */
  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 ("osj".indexOf(name.charAt(0)) != -1) {
      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
   */
  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) {
      BcelWorld world = (BcelWorld) weaver.getWorld();
      delegateForCurrentClass = world.addSourceObjectType(name, bytes, false);
    }
  }

  /**
   * 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
   */
  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
   */
  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<String> makeClasspath(String cp) {
    List<String> ret = new ArrayList<String>();
    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
   */
  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
   */
  protected String getDumpDir() {
    return "_ajdump";
  }

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

    private IMessageHandler delegate;
    private List<IMessage> 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<IMessage>();
        savedMessages.addAll(super.getUnmodifiableListView());
        clearMessages();
        for (IMessage message : savedMessages) {
          delegate.handleMessage(message);
        }
      }
      // accumulating = false;
      // messages.clear();
    }

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

    /*
     * IMessageHandler
     */

    @Override
    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;
    }

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

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

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

    /*
     * IMessageHolder
     */

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

  protected class WeavingAdaptorMessageWriter extends MessageWriter {

    private final Set<IMessage.Kind> ignoring = new HashSet<IMessage.Kind>();
    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;
    }

    @Override
    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;
    }

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

    /**
     * Set a message kind to be ignored from now on
     */
    @Override
    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.
     */
    @Override
    public void dontIgnore(IMessage.Kind kind) {
      if (null != kind) {
        ignoring.remove(kind);
      }
    }

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

  private class WeavingClassFileProvider implements IClassFileProvider {

    private final UnwovenClassFile unwovenClass;
    private final List<UnwovenClassFile> unwovenClasses = new ArrayList<UnwovenClassFile>();
    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<UnwovenClassFile> 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);
            }
          } else {
            // Classes generated by weaver e.g. around closure advice
            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
        }
      };
    }
  }

  public void setActiveProtectionDomain(ProtectionDomain protectionDomain) {
    activeProtectionDomain = protectionDomain;
  }
}
TOP

Related Classes of org.aspectj.weaver.tools.WeavingAdaptor$WeavingClassFileProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.