redeclared Map as ConcurrentHashMap

redeclared Map as ConcurrentHashMap

/*
 * Copyright (c) 2013 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.eigengo.monitor.agent.akka;

import akka.actor.*;
import org.eigengo.monitor.agent.AgentConfiguration;
import org.eigengo.monitor.output.CounterInterface;
import scala.Option;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Contains advices for monitoring behaviour of an actor; typically imprisoned in an {@code ActorCell}.
 */
public aspect ActorCellMonitoringAspect extends AbstractMonitoringAspect issingleton() {
    private AkkaAgentConfiguration agentConfiguration;
    private final CounterInterface counterInterface;
    private final Option<String> noActorClazz = Option.empty();
    private final ConcurrentHashMap<Option<String>, AtomicLong> samplingCounters  = new ConcurrentHashMap<Option<String>, AtomicLong>();
    private final ConcurrentHashMap<Option<String>, AtomicInteger> numberOfActors = new ConcurrentHashMap<Option<String>, AtomicInteger>();

    /**
     * Constructs this aspect
     */
    public ActorCellMonitoringAspect() {
        AgentConfiguration<AkkaAgentConfiguration> configuration = getAgentConfiguration("akka", AkkaAgentConfigurationJapi.apply());
        this.agentConfiguration = configuration.agent();
        this.counterInterface = createCounterInterface(configuration.common());
    }

    /**
     * Injects the new {@code AkkaAgentConfiguration} instance.
     *
     * @param agentConfiguration the new configuration
     */
    synchronized final void setAgentConfiguration(AkkaAgentConfiguration agentConfiguration) {
        this.agentConfiguration = agentConfiguration;
    }

    // decide whether to include this ActorCell in our measurements
    private boolean includeActorPath(final PathAndClass pathAndClass) {
        if (!this.agentConfiguration.incuded().accept(pathAndClass)) return false;
        if (this.agentConfiguration.excluded().accept(pathAndClass)) return false;

        if (this.agentConfiguration.includeSystemAgents()) return true;

        String userOrSystem = pathAndClass.actorPath().getElements().iterator().next();
        return "user".equals(userOrSystem);
    }

    // get the sample rate for an actor
    private int getSampleRate(final PathAndClass pathAndClass) {
        return this.agentConfiguration.sampling().getRate(pathAndClass);
    }

    // decide whether to sample an actor on a particular occasion
    private final boolean sampleMessage(final PathAndClass pathAndClass) {
        int sampleRate = getSampleRate(pathAndClass);
        if (sampleRate == 1) return true;

        this.samplingCounters.putIfAbsent(pathAndClass.actorClassName(), new AtomicLong(0));
        long timesSeenSoFar = this.samplingCounters.get(pathAndClass.actorClassName()).incrementAndGet();
        return (timesSeenSoFar % sampleRate == 1); // == 1 to log first value (incrementAndGet returns updated value)
    }

    // get the tags for the cell
    private String[] getTags(final ActorPath actorPath, final Actor actor) {
        List<String> tags = new ArrayList<String>();

        // TODO: Improve detection of routed actors. This relies only on the naming :(.
        String lastPathElement = actorPath.elements().last();
        if (lastPathElement.startsWith("$")) {
            // this is routed actor.
            tags.add(actorPath.parent().toString());
            if (this.agentConfiguration.includeRoutees()) tags.add(actorPath.toString());
        } else {
            // there is no supervisor
            tags.add(actorPath.toString());
        }
        if (actor != null) {
            tags.add(String.format("akka:%s.%s", actor.context().system().name(), actor.getClass().getCanonicalName()));
        }

        return tags.toArray(new String[tags.size()]);
    }

    // returns the canonical name of the actor type associated with an ActorCell
    private String uncheckedActorNameFrom(final ActorCell actorCell) {
        return uncheckedActorNameFrom(actorCell.props());
    }

    // returns the canonical name of the actor type associated with a Props instance
    private String uncheckedActorNameFrom(final Props props) {
        return props.actorClass().getCanonicalName();
    }

    /**
     * Advises the {@code ActorCell.receiveMessage(message: Object): Unit}
     * We proceed with the pointcut if the actor is to be included in the monitoring *and* this is
     * the 'multiple-of-n'th time we've seen a message for an actor with a sample rate of n.
     *
     * Currently, we sample queue size, the fact that the message is delivered, the simple name of the class of the
     * message, and the time taken to complete the actor's reactive action.
     *
     * @param actorCell the ActorCell where the actor that receives the message "lives"
     * @param msg the incoming message
     */
    Object around(ActorCell actorCell, Object msg) : Pointcuts.actorCellReceiveMessage(actorCell, msg) {
        final ActorPath actorPath = actorCell.self().path();
        final PathAndClass pathAndClass = new PathAndClass(actorPath, Option.apply(uncheckedActorNameFrom(actorCell)));
        if (!includeActorPath(pathAndClass) || !sampleMessage(pathAndClass)) return proceed(actorCell, msg);

        int samplingRate = getSampleRate(pathAndClass);

        // we tag by actor name
        final String[] tags = getTags(actorPath, actorCell.actor());

        // record the queue size
        this.counterInterface.recordGaugeValue("akka.queue.size", actorCell.numberOfMessages(), tags);
        // record the message, general and specific
        this.counterInterface.incrementCounter("akka.actor.delivered", samplingRate, tags);
        this.counterInterface.incrementCounter("akka.actor.delivered." + msg.getClass().getSimpleName(), samplingRate, tags);

        // measure the time. we're using the ``nanoTime`` call to access the high-precision timer.
        // since we're not really interested in wall time, but just some increasing measure of
        // elapsed time
        Object result = null;
        final long start = System.nanoTime();
        // result will always be ``null``, because target returns ``Unit``
        result = proceed(actorCell, msg);
        // ns or µs is too fine. ms will do for now.
        final long duration = (System.nanoTime() - start) / 1000000;

        // record the actor duration
        this.counterInterface.recordExecutionTime("akka.actor.duration", (int)duration, tags);

        // return null would do the trick, but we want to be _proper_.
        return result;
    }

    /**
     * Advises the {@code ActorCell.handleInvokeFailure(_, failure: Throwable): Unit}
     *
     * @param actorCell the ActorCell where the error spreads from
     * @param failure the exception that escaped from the {@code receive} method
     */
    before(ActorCell actorCell, Throwable failure) : Pointcuts.actorCellHandleInvokeFailure(actorCell, failure) {
        // record the error, general and specific
        String[] tags = getTags(actorCell.self().path(), actorCell.actor());
        this.counterInterface.incrementCounter("akka.actor.error", tags);
        this.counterInterface.incrementCounter(String.format("akka.actor.error.%s", failure.getMessage()), tags);
    }

    /**
     * Advises the {@code EventStream.publish(event: Any): Unit}
     *
     * @param event the received event
     */
    before(Object event) : Pointcuts.eventStreamPublish(event) {
        if (event instanceof UnhandledMessage) {
            UnhandledMessage unhandledMessage = (UnhandledMessage)event;
            String[] tags = getTags(unhandledMessage.recipient().path(), null);
            this.counterInterface.incrementCounter("akka.actor.undelivered", tags);
            this.counterInterface.incrementCounter("akka.actor.undelivered." + unhandledMessage.getMessage().getClass().getSimpleName(), tags);
        }
    }

    /**
     * Advises the {@code actorOf} method of {@code ActorCell} and {@code ActorSystem}
     *
     * @param props the {@code Props} instance used in the call
     * @param actor the {@code ActorRef} returned from the call
     */
    after(Props props) returning (ActorRef actor): Pointcuts.anyActorOf(props) {
        recordActorCreation(props, actor);
    }
    /**
     * Advises the {@code actorOf} method of {@code ActorCell} and {@code ActorSystem} when actor is named in construction
     *
     * @param props the {@code Props} instance used in the call
     * @param actorName the {@code String} used to name the actor at creation site
     * @param actor the {@code ActorRef} returned from the call
     */
    after(Props props, String actorName) returning (ActorRef actor): Pointcuts.namedActorOf(props, actorName) {
        recordActorCreation(props, actor);
    }

    // method containing the recording logic for advising actor creation
    private void recordActorCreation(Props props, ActorRef actor) {
        if (!includeActorPath(new PathAndClass(actor.path(), this.noActorClazz))) return;
        final String uncheckedClassName = uncheckedActorNameFrom(props);
        final Option<String> className = Option.apply(uncheckedClassName);

        this.numberOfActors.putIfAbsent(className, new AtomicInteger(0));
        // increment and get the current number of actors of this type (if the value was 0, then this returns 1 -- which is correct)
        final int currentNumberOfActors = this.numberOfActors.get(className).incrementAndGet();

        // record the current number of actors of this type
        this.counterInterface.recordGaugeValue("akka.actor.count", currentNumberOfActors, uncheckedClassName);
    }

    /**
     * Advises the {@code LocalActorRef.stop} method
     *
     *
     * @param actorCell the {@code ActorCell} of the actor being stopped
     */
    after(ActorCell actorCell) : Pointcuts.actorCellInternalStop(actorCell) {
        if (!includeActorPath(new PathAndClass(actorCell.self().path(), this.noActorClazz))) return;
        final String uncheckedClassName = uncheckedActorNameFrom(actorCell);
        final Option<String> className = Option.apply(uncheckedClassName);

        this.numberOfActors.putIfAbsent(className, new AtomicInteger(0));
        // decrement and get the current number of actors of this type (if the value was 1, then this returns 0 -- which is correct)
        final int currentNumberOfActors = this.numberOfActors.get(className).decrementAndGet();

        this.counterInterface.recordGaugeValue("akka.actor.count", currentNumberOfActors, uncheckedClassName);
    }

}

/*
 * Copyright (c) 2013 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.eigengo.monitor.agent.akka;

import akka.actor.*;
import org.eigengo.monitor.agent.AgentConfiguration;
import org.eigengo.monitor.output.CounterInterface;
import scala.Option;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Contains advices for monitoring behaviour of an actor; typically imprisoned in an {@code ActorCell}.
 */
public aspect ActorCellMonitoringAspect extends AbstractMonitoringAspect issingleton() {
    private AkkaAgentConfiguration agentConfiguration;
    private final CounterInterface counterInterface;
    private final Option<String> noActorClazz = Option.empty();
    private final Map<Option<String>, AtomicLong> samplingCounters  = new ConcurrentHashMap<Option<String>, AtomicLong>();
    private final Map<Option<String>, AtomicInteger> numberOfActors = new ConcurrentHashMap<Option<String>, AtomicInteger>();

    /**
     * Constructs this aspect
     */
    public ActorCellMonitoringAspect() {
        AgentConfiguration<AkkaAgentConfiguration> configuration = getAgentConfiguration("akka", AkkaAgentConfigurationJapi.apply());
        this.agentConfiguration = configuration.agent();
        this.counterInterface = createCounterInterface(configuration.common());
    }

    /**
     * Injects the new {@code AkkaAgentConfiguration} instance.
     *
     * @param agentConfiguration the new configuration
     */
    synchronized final void setAgentConfiguration(AkkaAgentConfiguration agentConfiguration) {
        this.agentConfiguration = agentConfiguration;
    }

    // decide whether to include this ActorCell in our measurements
    private boolean includeActorPath(final PathAndClass pathAndClass) {
        if (!this.agentConfiguration.incuded().accept(pathAndClass)) return false;
        if (this.agentConfiguration.excluded().accept(pathAndClass)) return false;

        if (this.agentConfiguration.includeSystemAgents()) return true;

        String userOrSystem = pathAndClass.actorPath().getElements().iterator().next();
        return "user".equals(userOrSystem);
    }

    // get the sample rate for an actor
    private int getSampleRate(final PathAndClass pathAndClass) {
        return this.agentConfiguration.sampling().getRate(pathAndClass);
    }

    // decide whether to sample an actor on a particular occasion
    private final boolean sampleMessage(final PathAndClass pathAndClass) {
        int sampleRate = getSampleRate(pathAndClass);
        if (sampleRate == 1) return true;

        this.samplingCounters.putIfAbsent(pathAndClass.actorClassName(), new AtomicLong(0));
        long timesSeenSoFar = this.samplingCounters.get(pathAndClass.actorClassName()).incrementAndGet();
        return (timesSeenSoFar % sampleRate == 1); // == 1 to log first value (incrementAndGet returns updated value)
    }

    // get the tags for the cell
    private String[] getTags(final ActorPath actorPath, final Actor actor) {
        List<String> tags = new ArrayList<String>();

        // TODO: Improve detection of routed actors. This relies only on the naming :(.
        String lastPathElement = actorPath.elements().last();
        if (lastPathElement.startsWith("$")) {
            // this is routed actor.
            tags.add(actorPath.parent().toString());
            if (this.agentConfiguration.includeRoutees()) tags.add(actorPath.toString());
        } else {
            // there is no supervisor
            tags.add(actorPath.toString());
        }
        if (actor != null) {
            tags.add(String.format("akka:%s.%s", actor.context().system().name(), actor.getClass().getCanonicalName()));
        }

        return tags.toArray(new String[tags.size()]);
    }

    // returns the canonical name of the actor type associated with an ActorCell
    private String uncheckedActorNameFrom(final ActorCell actorCell) {
        return uncheckedActorNameFrom(actorCell.props());
    }

    // returns the canonical name of the actor type associated with a Props instance
    private String uncheckedActorNameFrom(final Props props) {
        return props.actorClass().getCanonicalName();
    }

    /**
     * Advises the {@code ActorCell.receiveMessage(message: Object): Unit}
     * We proceed with the pointcut if the actor is to be included in the monitoring *and* this is
     * the 'multiple-of-n'th time we've seen a message for an actor with a sample rate of n.
     *
     * Currently, we sample queue size, the fact that the message is delivered, the simple name of the class of the
     * message, and the time taken to complete the actor's reactive action.
     *
     * @param actorCell the ActorCell where the actor that receives the message "lives"
     * @param msg the incoming message
     */
    Object around(ActorCell actorCell, Object msg) : Pointcuts.actorCellReceiveMessage(actorCell, msg) {
        final ActorPath actorPath = actorCell.self().path();
        final PathAndClass pathAndClass = new PathAndClass(actorPath, Option.apply(uncheckedActorNameFrom(actorCell)));
        if (!includeActorPath(pathAndClass) || !sampleMessage(pathAndClass)) return proceed(actorCell, msg);

        int samplingRate = getSampleRate(pathAndClass);

        // we tag by actor name
        final String[] tags = getTags(actorPath, actorCell.actor());

        // record the queue size
        this.counterInterface.recordGaugeValue("akka.queue.size", actorCell.numberOfMessages(), tags);
        // record the message, general and specific
        this.counterInterface.incrementCounter("akka.actor.delivered", samplingRate, tags);
        this.counterInterface.incrementCounter("akka.actor.delivered." + msg.getClass().getSimpleName(), samplingRate, tags);

        // measure the time. we're using the ``nanoTime`` call to access the high-precision timer.
        // since we're not really interested in wall time, but just some increasing measure of
        // elapsed time
        Object result = null;
        final long start = System.nanoTime();
        // result will always be ``null``, because target returns ``Unit``
        result = proceed(actorCell, msg);
        // ns or µs is too fine. ms will do for now.
        final long duration = (System.nanoTime() - start) / 1000000;

        // record the actor duration
        this.counterInterface.recordExecutionTime("akka.actor.duration", (int)duration, tags);

        // return null would do the trick, but we want to be _proper_.
        return result;
    }

    /**
     * Advises the {@code ActorCell.handleInvokeFailure(_, failure: Throwable): Unit}
     *
     * @param actorCell the ActorCell where the error spreads from
     * @param failure the exception that escaped from the {@code receive} method
     */
    before(ActorCell actorCell, Throwable failure) : Pointcuts.actorCellHandleInvokeFailure(actorCell, failure) {
        // record the error, general and specific
        String[] tags = getTags(actorCell.self().path(), actorCell.actor());
        this.counterInterface.incrementCounter("akka.actor.error", tags);
        this.counterInterface.incrementCounter(String.format("akka.actor.error.%s", failure.getMessage()), tags);
    }

    /**
     * Advises the {@code EventStream.publish(event: Any): Unit}
     *
     * @param event the received event
     */
    before(Object event) : Pointcuts.eventStreamPublish(event) {
        if (event instanceof UnhandledMessage) {
            UnhandledMessage unhandledMessage = (UnhandledMessage)event;
            String[] tags = getTags(unhandledMessage.recipient().path(), null);
            this.counterInterface.incrementCounter("akka.actor.undelivered", tags);
            this.counterInterface.incrementCounter("akka.actor.undelivered." + unhandledMessage.getMessage().getClass().getSimpleName(), tags);
        }
    }

    /**
     * Advises the {@code actorOf} method of {@code ActorCell} and {@code ActorSystem}
     *
     * @param props the {@code Props} instance used in the call
     * @param actor the {@code ActorRef} returned from the call
     */
    after(Props props) returning (ActorRef actor): Pointcuts.anyActorOf(props) {
        recordActorCreation(props, actor);
    }
    /**
     * Advises the {@code actorOf} method of {@code ActorCell} and {@code ActorSystem} when actor is named in construction
     *
     * @param props the {@code Props} instance used in the call
     * @param actorName the {@code String} used to name the actor at creation site
     * @param actor the {@code ActorRef} returned from the call
     */
    after(Props props, String actorName) returning (ActorRef actor): Pointcuts.namedActorOf(props, actorName) {
        recordActorCreation(props, actor);
    }

    // method containing the recording logic for advising actor creation
    private void recordActorCreation(Props props, ActorRef actor) {
        if (!includeActorPath(new PathAndClass(actor.path(), this.noActorClazz))) return;
        final String uncheckedClassName = uncheckedActorNameFrom(props);
        final Option<String> className = Option.apply(uncheckedClassName);

        this.numberOfActors.putIfAbsent(className, new AtomicInteger(0));
        // increment and get the current number of actors of this type (if the value was 0, then this returns 1 -- which is correct)
        final int currentNumberOfActors = this.numberOfActors.get(className).incrementAndGet();

        // record the current number of actors of this type
        this.counterInterface.recordGaugeValue("akka.actor.count", currentNumberOfActors, uncheckedClassName);
    }

    /**
     * Advises the {@code LocalActorRef.stop} method
     *
     *
     * @param actorCell the {@code ActorCell} of the actor being stopped
     */
    after(ActorCell actorCell) : Pointcuts.actorCellInternalStop(actorCell) {
        if (!includeActorPath(new PathAndClass(actorCell.self().path(), this.noActorClazz))) return;
        final String uncheckedClassName = uncheckedActorNameFrom(actorCell);
        final Option<String> className = Option.apply(uncheckedClassName);

        this.numberOfActors.putIfAbsent(className, new AtomicInteger(0));
        // decrement and get the current number of actors of this type (if the value was 1, then this returns 0 -- which is correct)
        final int currentNumberOfActors = this.numberOfActors.get(className).decrementAndGet();

        this.counterInterface.recordGaugeValue("akka.actor.count", currentNumberOfActors, uncheckedClassName);
    }

}


Add the missing '== null' check

Add the missing '== null' check

/*
 * Copyright 2005-2010 LAMP/EPFL
 */
// $Id$

package scala.tools.eclipse.contribution.weaving.jdt.core;

import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.SourceAnnotationMethodInfo;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;

import scala.tools.eclipse.contribution.weaving.jdt.IScalaCompilationUnit;

@SuppressWarnings("restriction")
public privileged aspect DOMAspect {
  pointcut internalCreateAST(ASTParser parser, IProgressMonitor monitor) :
    execution(ASTNode ASTParser.internalCreateAST(IProgressMonitor)) &&
    args(monitor) &&
    target(parser);

  pointcut convert(SourceTypeConverter stc, SourceMethod methodHandle, SourceMethodElementInfo methodInfo, CompilationResult compilationResult) :
    execution(AbstractMethodDeclaration SourceTypeConverter.convert(SourceMethod, SourceMethodElementInfo, CompilationResult)) &&
    args(methodHandle, methodInfo, compilationResult) &&
    target(stc);

  ASTNode around(ASTParser parser, IProgressMonitor monitor) :
    internalCreateAST(parser, monitor) {
    try {
      if (!(parser.typeRoot instanceof IScalaCompilationUnit))
        return proceed(parser, monitor);

      ICompilationUnit cu = (ICompilationUnit)parser.typeRoot;
      org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit)cu;

      IType[] topLevelTypes = cu.getTypes();
      int length = topLevelTypes.length;
      if (length == 0)
        throw new IllegalStateException();

      SourceTypeElementInfo[] topLevelInfos = new SourceTypeElementInfo[length];
      for (int i = 0; i < length; i++) {
        topLevelInfos[i] = (SourceTypeElementInfo) ((SourceType)topLevelTypes[i]).getElementInfo();
      }
      char[] fileName = ((ISourceType)topLevelInfos[0]).getFileName();

      CompilationResult result = new CompilationResult(fileName, 1, 1, 100);

      JavaProject javaProject = (JavaProject)cu.getJavaProject();
      Map compilerOptions0 = javaProject.getOptions(true);
      CompilerOptions compilerOptions = new CompilerOptions(compilerOptions0);
      compilerOptions.storeAnnotations = true;

      ProblemReporter problemReporter =
        new ProblemReporter(
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          compilerOptions,
          new DefaultProblemFactory(Locale.getDefault()));

      int flags = SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE;

      CompilationUnitDeclaration unit =
        SourceTypeConverter.buildCompilationUnit(topLevelInfos, flags, problemReporter, result);

      INameEnvironment ne = javaProject.newSearchableNameEnvironment(DefaultWorkingCopyOwner.PRIMARY);
      final LookupEnvironment le = new LookupEnvironment(null, compilerOptions, problemReporter, ne);
      ITypeRequestor typeRequestor = new ITypeRequestor() {
        public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
          le.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
        }
        public void accept(org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit, AccessRestriction accessRestriction) {}
        public void accept(ISourceType[] sourceType, PackageBinding packageBinding, AccessRestriction accessRestriction) {}
      };
      le.typeRequestor = typeRequestor;

      le.buildTypeBindings(unit, null);
      le.completeTypeBindings();
      fixTypes(unit.types);

      AST ast = AST.newAST(AST.JLS3);
      ast.setFlag(AST.RESOLVED_BINDINGS);
      ast.setDefaultNodeFlag(ASTNode.ORIGINAL);

      org.eclipse.jdt.core.dom.ASTConverter converter =
        new org.eclipse.jdt.core.dom.ASTConverter(compilerOptions0, true, monitor);

      org.eclipse.jdt.core.dom.BindingResolver resolver =
        new org.eclipse.jdt.core.dom.DefaultBindingResolver(
          unit.scope,
          DefaultWorkingCopyOwner.PRIMARY,
          new org.eclipse.jdt.core.dom.DefaultBindingResolver.BindingTables(),
          true);
      ast.setBindingResolver(resolver);
      converter.setAST(ast);

      ASTNode node = converter.convert(unit, sourceUnit.getContents());
      return node;
    } catch (JavaModelException ex) {
      throw new IllegalArgumentException(ex);
    }
  }

  private void fixTypes(TypeDeclaration[] types) {
    for(int i = 0, iLimit = types.length; i < iLimit ; ++i) {
      TypeDeclaration tpe = types[i];
      if (tpe != null) {
        if (tpe.binding != null) tpe.binding.getAnnotationTagBits();
        if (tpe.scope != null) {
          tpe.scope.buildFields();
          tpe.scope.buildMethods();
        }
        fixFields(tpe.fields);
        fixMethods(tpe.methods);
        fixTypes(tpe.memberTypes);
      }
    }
  }

  private void fixMethods(AbstractMethodDeclaration[] methods) {
    if (methods == null)
      return;

    for(int i = 0, iLimit = methods.length; i < iLimit; ++i) {
      AbstractMethodDeclaration m = methods[i];
      m.bodyStart = m.declarationSourceStart;
      m.bodyEnd = m.declarationSourceEnd;
      if (m.binding != null) {
        m.binding.getAnnotationTagBits();
      }
    }
  }

  private void fixFields(AbstractVariableDeclaration[] fields) {
    if (fields == null)
      return;

    for(int i = 0, iLimit = fields.length; i < iLimit; ++i) {
      AbstractVariableDeclaration f = fields[i];
      f.declarationEnd = f.declarationSourceEnd;
    }
  }

  AbstractMethodDeclaration around(SourceTypeConverter stc, SourceMethod methodHandle, SourceMethodElementInfo methodInfo, CompilationResult compilationResult) throws JavaModelException :
    convert(stc, methodHandle, methodInfo, compilationResult) {
    AbstractMethodDeclaration method;

    /* only source positions available */
    int start = methodInfo.getNameSourceStart();
    int end = methodInfo.getNameSourceEnd();

    // convert 1.5 specific constructs only if compliance is 1.5 or above
    TypeParameter[] typeParams = null;
    if (stc.has1_5Compliance) {
      /* convert type parameters */
      char[][] typeParameterNames = methodInfo.getTypeParameterNames();
      if (typeParameterNames != null) {
        int parameterCount = typeParameterNames.length;
        if (parameterCount > 0) { // method's type parameters must be null if no type parameter
          char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
          typeParams = new TypeParameter[parameterCount];
          for (int i = 0; i < parameterCount; i++) {
            typeParams[i] = stc.createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
          }
        }
      }
    }

    int modifiers = methodInfo.getModifiers();
    if (methodInfo.isConstructor()) {
      ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
      decl.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.IsDefaultConstructor;
      method = decl;
      decl.typeParameters = typeParams;
    } else {
      MethodDeclaration decl;
      if (methodInfo.isAnnotationMethod()) {
        AnnotationMethodDeclaration annotationMethodDeclaration = new AnnotationMethodDeclaration(compilationResult);

        /* conversion of default value */
        SourceAnnotationMethodInfo annotationMethodInfo = (SourceAnnotationMethodInfo) methodInfo;
        boolean hasDefaultValue = annotationMethodInfo.defaultValueStart != -1 || annotationMethodInfo.defaultValueEnd != -1;
        if ((stc.flags & SourceTypeConverter.FIELD_INITIALIZATION) != 0) {
          if (hasDefaultValue) {
            char[] defaultValueSource = CharOperation.subarray(stc.getSource(), annotationMethodInfo.defaultValueStart, annotationMethodInfo.defaultValueEnd+1);
            if (defaultValueSource != null) {
                Expression expression =  stc.parseMemberValue(defaultValueSource);
                if (expression != null) {
                  annotationMethodDeclaration.defaultValue = expression;
                }
            } else {
              // could not retrieve the default value
              hasDefaultValue = false;
            }
          }
        }
        if (hasDefaultValue)
          modifiers |= ClassFileConstants.AccAnnotationDefault;
        decl = annotationMethodDeclaration;
      } else {
        decl = new MethodDeclaration(compilationResult);
      }

      // convert return type
      decl.returnType = stc.createTypeReference(methodInfo.getReturnTypeName(), start, end);

      // type parameters
      decl.typeParameters = typeParams;

      method = decl;
    }
    method.selector = methodHandle.getElementName().toCharArray();
    boolean isVarargs = (modifiers & ClassFileConstants.AccVarargs) != 0;
    method.modifiers = modifiers & ~ClassFileConstants.AccVarargs;
    method.sourceStart = start;
    method.sourceEnd = end;
    method.declarationSourceStart = methodInfo.getDeclarationSourceStart();
    method.declarationSourceEnd = methodInfo.getDeclarationSourceEnd();

    // convert 1.5 specific constructs only if compliance is 1.5 or above
    if (stc.has1_5Compliance) {
      /* convert annotations */
      method.annotations = stc.convertAnnotations(methodHandle);
    }

    /* convert arguments */
    String[] argumentTypeSignatures = methodHandle.getParameterTypes();
    char[][] argumentNames = methodInfo.getArgumentNames();
    int argumentCount = argumentTypeSignatures == null ? 0 : argumentTypeSignatures.length;
    if (argumentCount > 0) {
      long position = ((long) start << 32) + end;
      method.arguments = new Argument[argumentCount];
      for (int i = 0; i < argumentCount; i++) {
        TypeReference typeReference = stc.createTypeReference(argumentTypeSignatures[i], start, end);
        if (isVarargs && i == argumentCount-1) {
          typeReference.bits |= org.eclipse.jdt.internal.compiler.ast.ASTNode.IsVarArgs;
        }
        method.arguments[i] =
          new Argument(
            argumentNames[i],
            position,
            typeReference,
            ClassFileConstants.AccDefault);
        // do not care whether was final or not
      }
    }

    /* convert thrown exceptions */
    char[][] exceptionTypeNames = methodInfo.getExceptionTypeNames();
    int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
    if (exceptionCount > 0) {
      method.thrownExceptions = new TypeReference[exceptionCount];
      for (int i = 0; i < exceptionCount; i++) {
        method.thrownExceptions[i] =
          stc.createTypeReference(exceptionTypeNames[i], start, end);
      }
    }

    /* convert local and anonymous types */
    if ((stc.flags & SourceTypeConverter.LOCAL_TYPE) != 0) {
      IJavaElement[] children = methodInfo.getChildren();
      int typesLength = 0;
      int childrenLength = children.length;
      for (int i = 0; i < childrenLength; ++i)
        if (children[i] instanceof SourceType)
          ++typesLength;

      if (typesLength != 0) {
        Statement[] statements = new Statement[typesLength];
        int typeIndex = 0;
        for (int i = 0; i < childrenLength; i++) {
          if (children[i] instanceof SourceType) {
            SourceType type = (SourceType) children[i];
            TypeDeclaration localType = stc.convert(type, compilationResult);
            if ((localType.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) {
              QualifiedAllocationExpression expression = new QualifiedAllocationExpression(localType);
              expression.type = localType.superclass;
              localType.superclass = null;
              localType.superInterfaces = null;
              localType.allocation = expression;
              statements[typeIndex] = expression;
            } else {
              statements[typeIndex] = localType;
            }
            ++typeIndex;
          }
        }
        method.statements = statements;
      }
    }

    return method;
  }
}

/*
 * Copyright 2005-2010 LAMP/EPFL
 */
// $Id$

package scala.tools.eclipse.contribution.weaving.jdt.core;

import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.jdt.internal.core.JavaProject;
import org.eclipse.jdt.internal.core.SourceAnnotationMethodInfo;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;

import scala.tools.eclipse.contribution.weaving.jdt.IScalaCompilationUnit;

@SuppressWarnings("restriction")
public privileged aspect DOMAspect {
  pointcut internalCreateAST(ASTParser parser, IProgressMonitor monitor) :
    execution(ASTNode ASTParser.internalCreateAST(IProgressMonitor)) &&
    args(monitor) &&
    target(parser);

  pointcut convert(SourceTypeConverter stc, SourceMethod methodHandle, SourceMethodElementInfo methodInfo, CompilationResult compilationResult) :
    execution(AbstractMethodDeclaration SourceTypeConverter.convert(SourceMethod, SourceMethodElementInfo, CompilationResult)) &&
    args(methodHandle, methodInfo, compilationResult) &&
    target(stc);

  ASTNode around(ASTParser parser, IProgressMonitor monitor) :
    internalCreateAST(parser, monitor) {
    try {
      if (!(parser.typeRoot instanceof IScalaCompilationUnit))
        return proceed(parser, monitor);

      ICompilationUnit cu = (ICompilationUnit)parser.typeRoot;
      org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit)cu;

      IType[] topLevelTypes = cu.getTypes();
      int length = topLevelTypes.length;
      if (length == 0)
        throw new IllegalStateException();

      SourceTypeElementInfo[] topLevelInfos = new SourceTypeElementInfo[length];
      for (int i = 0; i < length; i++) {
        topLevelInfos[i] = (SourceTypeElementInfo) ((SourceType)topLevelTypes[i]).getElementInfo();
      }
      char[] fileName = ((ISourceType)topLevelInfos[0]).getFileName();

      CompilationResult result = new CompilationResult(fileName, 1, 1, 100);

      JavaProject javaProject = (JavaProject)cu.getJavaProject();
      Map compilerOptions0 = javaProject.getOptions(true);
      CompilerOptions compilerOptions = new CompilerOptions(compilerOptions0);
      compilerOptions.storeAnnotations = true;

      ProblemReporter problemReporter =
        new ProblemReporter(
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          compilerOptions,
          new DefaultProblemFactory(Locale.getDefault()));

      int flags = SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE;

      CompilationUnitDeclaration unit =
        SourceTypeConverter.buildCompilationUnit(topLevelInfos, flags, problemReporter, result);

      INameEnvironment ne = javaProject.newSearchableNameEnvironment(DefaultWorkingCopyOwner.PRIMARY);
      final LookupEnvironment le = new LookupEnvironment(null, compilerOptions, problemReporter, ne);
      ITypeRequestor typeRequestor = new ITypeRequestor() {
        public void accept(IBinaryType binaryType, PackageBinding packageBinding, AccessRestriction accessRestriction) {
          le.createBinaryTypeFrom(binaryType, packageBinding, accessRestriction);
        }
        public void accept(org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit, AccessRestriction accessRestriction) {}
        public void accept(ISourceType[] sourceType, PackageBinding packageBinding, AccessRestriction accessRestriction) {}
      };
      le.typeRequestor = typeRequestor;

      le.buildTypeBindings(unit, null);
      le.completeTypeBindings();
      fixTypes(unit.types);

      AST ast = AST.newAST(AST.JLS3);
      ast.setFlag(AST.RESOLVED_BINDINGS);
      ast.setDefaultNodeFlag(ASTNode.ORIGINAL);

      org.eclipse.jdt.core.dom.ASTConverter converter =
        new org.eclipse.jdt.core.dom.ASTConverter(compilerOptions0, true, monitor);

      org.eclipse.jdt.core.dom.BindingResolver resolver =
        new org.eclipse.jdt.core.dom.DefaultBindingResolver(
          unit.scope,
          DefaultWorkingCopyOwner.PRIMARY,
          new org.eclipse.jdt.core.dom.DefaultBindingResolver.BindingTables(),
          true);
      ast.setBindingResolver(resolver);
      converter.setAST(ast);

      ASTNode node = converter.convert(unit, sourceUnit.getContents());
      return node;
    } catch (JavaModelException ex) {
      throw new IllegalArgumentException(ex);
    }
  }

  private void fixTypes(TypeDeclaration[] types) {
    for(int i = 0, iLimit = types.length; i < iLimit ; ++i) {
      TypeDeclaration tpe = types[i];
      if (tpe != null) {
        if (tpe.binding != null) tpe.binding.getAnnotationTagBits();
        if (tpe.scope != null) {
          tpe.scope.buildFields();
          tpe.scope.buildMethods();
        }
        fixFields(tpe.fields);
        fixMethods(tpe.methods);
        fixTypes(tpe.memberTypes);
      }
    }
  }

  private void fixMethods(AbstractMethodDeclaration[] methods) {
    if (methods == null)
      return;

    for(int i = 0, iLimit = methods.length; i < iLimit; ++i) {
      AbstractMethodDeclaration m = methods[i];
      m.bodyStart = m.declarationSourceStart;
      m.bodyEnd = m.declarationSourceEnd;
      m.binding.getAnnotationTagBits();
    }
  }

  private void fixFields(AbstractVariableDeclaration[] fields) {
    if (fields == null)
      return;

    for(int i = 0, iLimit = fields.length; i < iLimit; ++i) {
      AbstractVariableDeclaration f = fields[i];
      f.declarationEnd = f.declarationSourceEnd;
    }
  }

  AbstractMethodDeclaration around(SourceTypeConverter stc, SourceMethod methodHandle, SourceMethodElementInfo methodInfo, CompilationResult compilationResult) throws JavaModelException :
    convert(stc, methodHandle, methodInfo, compilationResult) {
    AbstractMethodDeclaration method;

    /* only source positions available */
    int start = methodInfo.getNameSourceStart();
    int end = methodInfo.getNameSourceEnd();

    // convert 1.5 specific constructs only if compliance is 1.5 or above
    TypeParameter[] typeParams = null;
    if (stc.has1_5Compliance) {
      /* convert type parameters */
      char[][] typeParameterNames = methodInfo.getTypeParameterNames();
      if (typeParameterNames != null) {
        int parameterCount = typeParameterNames.length;
        if (parameterCount > 0) { // method's type parameters must be null if no type parameter
          char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds();
          typeParams = new TypeParameter[parameterCount];
          for (int i = 0; i < parameterCount; i++) {
            typeParams[i] = stc.createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end);
          }
        }
      }
    }

    int modifiers = methodInfo.getModifiers();
    if (methodInfo.isConstructor()) {
      ConstructorDeclaration decl = new ConstructorDeclaration(compilationResult);
      decl.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.IsDefaultConstructor;
      method = decl;
      decl.typeParameters = typeParams;
    } else {
      MethodDeclaration decl;
      if (methodInfo.isAnnotationMethod()) {
        AnnotationMethodDeclaration annotationMethodDeclaration = new AnnotationMethodDeclaration(compilationResult);

        /* conversion of default value */
        SourceAnnotationMethodInfo annotationMethodInfo = (SourceAnnotationMethodInfo) methodInfo;
        boolean hasDefaultValue = annotationMethodInfo.defaultValueStart != -1 || annotationMethodInfo.defaultValueEnd != -1;
        if ((stc.flags & SourceTypeConverter.FIELD_INITIALIZATION) != 0) {
          if (hasDefaultValue) {
            char[] defaultValueSource = CharOperation.subarray(stc.getSource(), annotationMethodInfo.defaultValueStart, annotationMethodInfo.defaultValueEnd+1);
            if (defaultValueSource != null) {
                Expression expression =  stc.parseMemberValue(defaultValueSource);
                if (expression != null) {
                  annotationMethodDeclaration.defaultValue = expression;
                }
            } else {
              // could not retrieve the default value
              hasDefaultValue = false;
            }
          }
        }
        if (hasDefaultValue)
          modifiers |= ClassFileConstants.AccAnnotationDefault;
        decl = annotationMethodDeclaration;
      } else {
        decl = new MethodDeclaration(compilationResult);
      }

      // convert return type
      decl.returnType = stc.createTypeReference(methodInfo.getReturnTypeName(), start, end);

      // type parameters
      decl.typeParameters = typeParams;

      method = decl;
    }
    method.selector = methodHandle.getElementName().toCharArray();
    boolean isVarargs = (modifiers & ClassFileConstants.AccVarargs) != 0;
    method.modifiers = modifiers & ~ClassFileConstants.AccVarargs;
    method.sourceStart = start;
    method.sourceEnd = end;
    method.declarationSourceStart = methodInfo.getDeclarationSourceStart();
    method.declarationSourceEnd = methodInfo.getDeclarationSourceEnd();

    // convert 1.5 specific constructs only if compliance is 1.5 or above
    if (stc.has1_5Compliance) {
      /* convert annotations */
      method.annotations = stc.convertAnnotations(methodHandle);
    }

    /* convert arguments */
    String[] argumentTypeSignatures = methodHandle.getParameterTypes();
    char[][] argumentNames = methodInfo.getArgumentNames();
    int argumentCount = argumentTypeSignatures == null ? 0 : argumentTypeSignatures.length;
    if (argumentCount > 0) {
      long position = ((long) start << 32) + end;
      method.arguments = new Argument[argumentCount];
      for (int i = 0; i < argumentCount; i++) {
        TypeReference typeReference = stc.createTypeReference(argumentTypeSignatures[i], start, end);
        if (isVarargs && i == argumentCount-1) {
          typeReference.bits |= org.eclipse.jdt.internal.compiler.ast.ASTNode.IsVarArgs;
        }
        method.arguments[i] =
          new Argument(
            argumentNames[i],
            position,
            typeReference,
            ClassFileConstants.AccDefault);
        // do not care whether was final or not
      }
    }

    /* convert thrown exceptions */
    char[][] exceptionTypeNames = methodInfo.getExceptionTypeNames();
    int exceptionCount = exceptionTypeNames == null ? 0 : exceptionTypeNames.length;
    if (exceptionCount > 0) {
      method.thrownExceptions = new TypeReference[exceptionCount];
      for (int i = 0; i < exceptionCount; i++) {
        method.thrownExceptions[i] =
          stc.createTypeReference(exceptionTypeNames[i], start, end);
      }
    }

    /* convert local and anonymous types */
    if ((stc.flags & SourceTypeConverter.LOCAL_TYPE) != 0) {
      IJavaElement[] children = methodInfo.getChildren();
      int typesLength = 0;
      int childrenLength = children.length;
      for (int i = 0; i < childrenLength; ++i)
        if (children[i] instanceof SourceType)
          ++typesLength;

      if (typesLength != 0) {
        Statement[] statements = new Statement[typesLength];
        int typeIndex = 0;
        for (int i = 0; i < childrenLength; i++) {
          if (children[i] instanceof SourceType) {
            SourceType type = (SourceType) children[i];
            TypeDeclaration localType = stc.convert(type, compilationResult);
            if ((localType.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) {
              QualifiedAllocationExpression expression = new QualifiedAllocationExpression(localType);
              expression.type = localType.superclass;
              localType.superclass = null;
              localType.superInterfaces = null;
              localType.allocation = expression;
              statements[typeIndex] = expression;
            } else {
              statements[typeIndex] = localType;
            }
            ++typeIndex;
          }
        }
        method.statements = statements;
      }
    }

    return method;
  }
}


Fix NPE.

Fix NPE.

package org.openmole.commons.aspect.eventdispatcher;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.openmole.commons.aspect.eventdispatcher.internal.Activator;
import org.openmole.commons.exception.InternalProcessingError;
import org.openmole.commons.exception.UserBadDataError;
import java.lang.InterruptedException;
import java.lang.reflect.Method;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.annotation.Annotation;

public aspect EventAspect {

	before() throws InternalProcessingError, UserBadDataError : execution(* *(..)) && @annotation(org.openmole.commons.aspect.eventdispatcher.BeforeObjectModified) {

		Object object = thisJoinPoint.getThis();

                Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
                ObjectModified annotation = method.getAnnotation(BeforeObjectModified.class);

                String type = annotation.type();
                Object[] args = thisJoinPoint.getArgs();

                Activator.getEventDispatcher().objectChanged(object,type, args);
	}

	after() throws InternalProcessingError, UserBadDataError : execution(* *(..)) && @annotation(org.openmole.commons.aspect.eventdispatcher.ObjectModified) {

		Object object = thisJoinPoint.getThis();

                Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
                ObjectModified annotation = method.getAnnotation(ObjectModified.class);

                Activator.getEventDispatcher().objectChanged(object,annotation.type(), thisJoinPoint.getArgs());
	}

        after() : execution(*.new(..)) && @annotation(org.openmole.commons.aspect.eventdispatcher.ObjectConstructed) {

		// construct genericIdentifier
		Object object = thisJoinPoint.getThis();
		//Object ret = proceed();

               // Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
               // ObjectModified annotation = method.getAnnotation(ObjectModified.class);

               // Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO,"ctr: " + thisJoinPointStaticPart.getSignature().toString());

                Activator.getEventDispatcher().objectConstructed(object);
		//Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO,object.toString() + " "+ method);

		//return ret;
	}
}

package org.openmole.commons.aspect.eventdispatcher;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.openmole.commons.aspect.eventdispatcher.internal.Activator;
import org.openmole.commons.exception.InternalProcessingError;
import org.openmole.commons.exception.UserBadDataError;
import java.lang.InterruptedException;
import java.lang.reflect.Method;
import org.aspectj.lang.reflect.MethodSignature;
import java.lang.annotation.Annotation;

public aspect EventAspect {

	before() throws InternalProcessingError, UserBadDataError : execution(* *(..)) && @annotation(org.openmole.commons.aspect.eventdispatcher.BeforeObjectModified) {

		Object object = thisJoinPoint.getThis();

                Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
                ObjectModified annotation = method.getAnnotation(ObjectModified.class);

                Activator.getEventDispatcher().objectChanged(object,annotation.type(), thisJoinPoint.getArgs());
	}

	after() throws InternalProcessingError, UserBadDataError : execution(* *(..)) && @annotation(org.openmole.commons.aspect.eventdispatcher.ObjectModified) {

		Object object = thisJoinPoint.getThis();

                Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
                ObjectModified annotation = method.getAnnotation(ObjectModified.class);

                Activator.getEventDispatcher().objectChanged(object,annotation.type(), thisJoinPoint.getArgs());
	}

        after() : execution(*.new(..)) && @annotation(org.openmole.commons.aspect.eventdispatcher.ObjectConstructed) {

		// construct genericIdentifier
		Object object = thisJoinPoint.getThis();
		//Object ret = proceed();

               // Method method = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod();
               // ObjectModified annotation = method.getAnnotation(ObjectModified.class);

               // Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO,"ctr: " + thisJoinPointStaticPart.getSignature().toString());

                Activator.getEventDispatcher().objectConstructed(object);
		//Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO,object.toString() + " "+ method);

		//return ret;
	}
}


* change aspect signature

* change aspect signature

package ru.agentlab.maia.context.log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.agentlab.maia.context.IMaiaContext;
import ru.agentlab.maia.context.IMaiaContextFactory;
import ru.agentlab.maia.context.aj.AMaiaContextFactory;

public aspect AMaiaContextFactoryLog extends AMaiaContextFactory {

	after(IMaiaContextFactory factory) returning (IMaiaContext result):
		onCreateContext(factory) {
		Logger logger = LoggerFactory.getLogger(factory.getClass());
		logger.info("Context [" + result.getUuid() + "] successfully created");
	}
}

package ru.agentlab.maia.context.log;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.agentlab.maia.context.IMaiaContext;
import ru.agentlab.maia.context.IMaiaContextFactory;
import ru.agentlab.maia.context.aj.AMaiaContextFactory;

public aspect AMaiaContextFactoryLog extends AMaiaContextFactory {

	before(IMaiaContextFactory factory, IMaiaContext parent, String name) :
		onCreateChildContext(factory, parent, name) {
		Logger logger = LoggerFactory.getLogger(factory.getClass());
		logger.info("Try to create [" + name + "] context with [" + parent
				+ "] parent...");
	}

	after(IMaiaContextFactory factory, String name) returning:
		onCreateChildContext(factory, *, name) {
		Logger logger = LoggerFactory.getLogger(factory.getClass());
		logger.info("Context [" + name + "] successfully created");
	}

	after(IMaiaContextFactory factory, String name) returning:
		onCreateContext(factory, name) {
		Logger logger = LoggerFactory.getLogger(factory.getClass());
		logger.info("Context [" + name + "] successfully created");
	}
}


used named pointcuts to clarify implementation

git-svn-id: b619a0c99665f88f1afe72824344cefe9a1c8c90@8628 fd5a2b45-1f63-4059-99e9-3c7cb7fd75c8

/*
 * Copyright 2002-2006 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.aspectj;

import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.annotation.Transactional;

/**
 * Concrete AspectJ transaction aspect using Java 5 annotations, and Spring
 * transactional annotation.
 * <p>
 * validation.
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @author Adrian Colyer
 * @since 2.0
 * @see AbstractTransactionAspect
 */
public aspect TransactionalAnnotationTransactionAspect extends AbstractTransactionAspect {

	public TransactionalAnnotationTransactionAspect() {
		super(new AnnotationTransactionAttributeSource());
	}

	/**
	 * Matches the execution of any public method in a type with the
	 * Transactional annotation, or any subtype of a type with the
	 * Transactional annotation.
	 */
	private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
		execution(public * (@Transactional *+).*(..));

	/**
	 * Matches the execution of any public method with the
	 * Transactional annotation.
	 */
	private pointcut executionOfTransactionalPublicMethod() :
		execution(public * *(..)) && @annotation(Transactional);

	/**
	 * Definition of pointcut from super aspect - matched join points
	 * will have Spring transaction management applied.
	 */
	protected pointcut transactionalMethodExecution(Object txObject) :
		(executionOfAnyPublicMethodInAtTransactionalType()
		 || executionOfTransactionalPublicMethod())
		&& this(txObject);

}

/*
 * Copyright 2002-2006 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.transaction.aspectj;

import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
import org.springframework.transaction.annotation.Transactional;

/**
 * Concrete AspectJ transaction aspect using Java 5 annotations, and Spring
 * transactional annotation.
 * <p>
 * validation.
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @since 2.0
 * @see AbstractTransactionAspect
 */
public aspect TransactionalAnnotationTransactionAspect extends AbstractTransactionAspect {

	public TransactionalAnnotationTransactionAspect() {
		super(new AnnotationTransactionAttributeSource());
	}

	protected pointcut transactionalMethodExecution(Object txObject) :
		(execution(public * (@Transactional *+).*(..))
		 || (execution(public * *(..))) && @annotation(Transactional))
		&& this(txObject);

}


Explain mock scope in static method mocking aspect

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.mock.staticmock;

/**
 * Annotation-based aspect to use in test builds to enable mocking of static methods
 * on JPA-annotated {@code @Entity} classes, as used by Spring Roo for so-called
 * finder methods.
 *
 *
Mocking will occur within the call stack of any {@code public} method in a
 * class (typically a test class) that is annotated with {@code @MockStaticEntityMethods}.
 * Thus mocking is not limited to {@code @Test} methods. Furthermore, new mock
 * state will be created for the invocation of each such public method, even when
 * the method is invoked from another such public method.
 *
 *
This aspect also provides static methods to simplify the programming model for
 * setting expectations and entering playback mode.
 *
 *
Usage

 *

 *
Annotate a test class with {@code @MockStaticEntityMethods}.
 *
In each test method, the {@code AnnotationDrivenStaticEntityMockingControl}
 * will begin in recording mode.
 *
Invoke static methods on JPA-annotated {@code @Entity} classes, with each
 * recording-mode invocation being followed by an invocation of either
 * {@link #expectReturn(Object)} or {@link #expectThrow(Throwable)} on the
 * {@code AnnotationDrivenStaticEntityMockingControl}.
 *
Invoke the {@link #playback()} method.
 *
Call the code you wish to test that uses the static methods on the
 * JPA-annotated {@code @Entity} classes.
 *
Verification will occur automatically after the test method has executed
 * and returned. However, mock verification will not occur if the test method
 * throws an exception.
 *

 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @author Sam Brannen
 * @see MockStaticEntityMethods
 */
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {

	/**
	 * Expect the supplied {@link Object} to be returned by the previous static
	 * method invocation.
	 * @see #playback()
	 */
	public static void expectReturn(Object retVal) {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
	}

	/**
	 * Expect the supplied {@link Throwable} to be thrown by the previous static
	 * method invocation.
	 * @see #playback()
	 */
	public static void expectThrow(Throwable throwable) {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
	}

	/**
	 * Stop recording mock expectations and enter playback mode.
	 * @see #expectReturn(Object)
	 * @see #expectThrow(Throwable)
	 */
	public static void playback() {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
	}

	// Apparently, the following pointcut was originally defined to only match
	// methods directly annotated with @Test (in order to allow methods in
	// @MockStaticEntityMethods classes to invoke each other without resetting
	// the mocking environment); however, this is no longer the case. The current
	// pointcut applies to all public methods in @MockStaticEntityMethods classes.
	protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));

	protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));

}

/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.mock.staticmock;

/**
 * Annotation-based aspect to use in test builds to enable mocking of static methods
 * on JPA-annotated {@code @Entity} classes, as used by Spring Roo for so-called
 * finder methods.
 *
 *
Mocking will occur within the call stack of any method in a class (typically a
 * test class) that is annotated with {@code @MockStaticEntityMethods}.
 *
 *
This aspect also provides static methods to simplify the programming model for
 * setting expectations and entering playback mode.
 *
 *
Usage

 *

 *
Annotate a test class with {@code @MockStaticEntityMethods}.
 *
In each test method, the {@code AnnotationDrivenStaticEntityMockingControl}
 * will begin in recording mode.
 *
Invoke static methods on JPA-annotated {@code @Entity} classes, with each
 * recording-mode invocation being followed by an invocation of either
 * {@link #expectReturn(Object)} or {@link #expectThrow(Throwable)} on the
 * {@code AnnotationDrivenStaticEntityMockingControl}.
 *
Invoke the {@link #playback()} method.
 *
Call the code you wish to test that uses the static methods on the
 * JPA-annotated {@code @Entity} classes.
 *
Verification will occur automatically after the test method has executed
 * and returned. However, mock verification will not occur if the test method
 * throws an exception.
 *

 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @author Sam Brannen
 * @see MockStaticEntityMethods
 */
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {

	/**
	 * Expect the supplied {@link Object} to be returned by the previous static
	 * method invocation.
	 * @see #playback()
	 */
	public static void expectReturn(Object retVal) {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
	}

	/**
	 * Expect the supplied {@link Throwable} to be thrown by the previous static
	 * method invocation.
	 * @see #playback()
	 */
	public static void expectThrow(Throwable throwable) {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
	}

	/**
	 * Stop recording mock expectations and enter playback mode.
	 * @see #expectReturn(Object)
	 * @see #expectThrow(Throwable)
	 */
	public static void playback() {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
	}

	// Apparently, the following pointcut was originally defined to only match
	// methods directly annotated with @Test (in order to allow methods in
	// @MockStaticEntityMethods classes to invoke each other without resetting
	// the mocking environment); however, this is no longer the case. The current
	// pointcut applies to all public methods in @MockStaticEntityMethods classes.
	protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));

	protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));

}


- unused aspects

- unused aspects

package ru.agentlab.maia.context.event;

import ru.agentlab.maia.event.IMaiaEventBroker;
import ru.agentlab.maia.memory.IMaiaContext;
import ru.agentlab.maia.memory.IMaiaContextFactory;
import ru.agentlab.maia.memory.aj.AMaiaContextFactory;

public aspect AMaiaContextFactoryEvent extends AMaiaContextFactory {

	after(IMaiaContextFactory factory) returning (IMaiaContext result):
		onCreateContext(factory) {
		IMaiaEventBroker broker = result.get(IMaiaEventBroker.class);
		broker.post(new MaiaContextFactoryCreateChildEvent(result.getParent(), result));
	}

	after() returning (IMaiaContext result):
		onCreateContext(*) {
		IMaiaEventBroker broker = result.get(IMaiaEventBroker.class);
		broker.post(new MaiaContextFactoryCreateEvent(result));
	}
}


Counting of failures, errors and successes now gives same number as JUnit.

git-svn-id: dc8158aad167a3007ca64719d3939bef820f4b72@581 ab42f6e0-554d-0410-b580-99e487e6eeb2

package org.planet_sl.apimigration.benchmark.analysis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Collections;

import junit.framework.TestSuite;
import junit.textui.TestRunner;

import org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.*;

@SuppressWarnings("unused")
public aspect InterceptTestFailure {

	static int tests = 0;
	static int assertionsTotal = 0;
	static int failuresTotal = 0;
	static int errorsTotal = 0;
	static String currentTest = null;
	static String currentMethod = null;

	private static String prettyName(String name) {
		name = name.replaceAll("execution\\(\\1\\)$", "\\1");
		name = name.replaceAll("\\)$", "");
		name = name.replaceAll("org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.", "");
		name = name.substring(name.indexOf(" ") + 1);
		return name;
	}

	after(): execution(public static void CollectFailures.main(..)) {
		System.out.println(tests + " tests with " + assertionsTotal + " assertions");
		System.out.println(failuresTotal + " failures; " + errorsTotal + " errors");
		for (String method: assertionCount.keySet()) {
			System.out.println("assertion of " + method + ": " + assertionCount.get(method));
		}
		for (String method: failureCount.keySet()) {
			System.out.println("failures of " + method + ": " + failureCount.get(method));
		}
		for (String method: errorCount.keySet()) {
			System.out.println("errors of " + method + ": " + errorCount.get(method));
		}
		for (String method: successCount.keySet()) {
			System.out.println("successes of " + method + ": " + successCount.get(method));
		}
	}

	private static Map<String,Integer> failureCount = new HashMap<String, Integer>();
	private static Map<String,Integer> errorCount = new HashMap<String, Integer>();
	private static Map<String,Integer> assertionCount = new HashMap<String, Integer>();
	private static Map<String,Integer> successCount = new HashMap<String, Integer>();
	private static java.util.List<String> methods = new ArrayList<String>();
	private static int assertions = 0;

	private static void inc(Map<String,Integer> table, String currentMethod) {
		inc(table, currentMethod, 1);
	}

	private static void inc(Map<String,Integer> table, String currentMethod, int count) {
		if (!table.containsKey(currentMethod)) {
			table.put(currentMethod, 0);
		}
		table.put(currentMethod, table.get(currentMethod) + count);
	}

	before(): call(void assert*(..)) && within(org.planet_sl.apimigration.benchmark.jdom.test_as_xom.*) {
		assertions++;
		assertionsTotal++;
	}

	private static boolean wasFeature = false;
	private static Map<String,Integer> featureCallCount = new HashMap<String, Integer>();

	after(): execution(* org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.*.*(..)) {
		currentMethod = thisJoinPoint.toShortString();
		inc(featureCallCount, currentMethod);
		if (!methods.contains(currentMethod)) {
			methods.add(currentMethod);
		}
	}

	void around(): execution(void test*()) && within(org.planet_sl.apimigration.benchmark.jdom.test_as_xom.*) {
		methods.clear();
		assertions = 0;
		tests++;
		try {
			proceed();
		}
		catch (AssertionError e) {
			failuresTotal++;
			for (String method: methods) {
				inc(failureCount, method);
			}
			throw e;
		}
		catch (Throwable e) {
			errorsTotal++;
			for (String method: methods) {
				inc(errorCount, method);
			}
			//throw e;
		}
		for (String method: methods) {
			inc(successCount, method, assertions);
		}
	}

//	Collections.sort(methods);
//	for (String method: methods) {
//		System.out.println(method + ": ");
//		System.out.println("\t" + assertionCount.get(method) + " assertions");
//		System.out.println("\t" + failureCount.get(method) + " failed");
//		System.out.println("\t" + errorCount.get(method) + " errors");
//	}
//	System.out.println("***** FAILURES ****** (" + failures.size() + " out of " + tests + ")");
//	int i = 1;
//	for (String test: failures.keySet()) {
//		String prettyTest = test.replaceAll("execution\\(", "").replaceAll("\\)$", "");
//		String prettyMethod = failures.get(test);
//		prettyMethod = prettyMethod.replaceAll("execution\\(", "");
//		prettyMethod = prettyMethod.replaceAll("\\)$", "");
//		prettyMethod = prettyMethod.replaceAll("org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.", "");
//		prettyMethod = prettyMethod.substring(prettyMethod.indexOf(" ") + 1);
//		System.out.println(i + " " + prettyTest + ": " + prettyMethod);
//		i++;
//	}
//	System.out.println("***** ERRORS ****** (" + errors.size() + " out of " + tests + ")");
//	// TODO refactor...
//	i = 1;
//	for (String test: errors.keySet()) {
//		String prettyTest = test.replaceAll("execution\\(", "").replaceAll("\\)$", "");
//		String prettyMethod = errors.get(test);
//		prettyMethod = prettyMethod.replaceAll("execution\\(", "");
//		prettyMethod = prettyMethod.replaceAll("\\)$", "");
//		prettyMethod = prettyMethod.replaceAll("org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.", "");
//		prettyMethod = prettyMethod.substring(prettyMethod.indexOf(" ") + 1);
//		System.out.println(i + " " + prettyTest + ": " + prettyMethod + " ("
//				+ exceptions.get(test).getClass() + ")");
//		i++;
//	}

}

package org.planet_sl.apimigration.benchmark.analysis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Collections;

import junit.framework.TestSuite;
import junit.textui.TestRunner;

import org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.*;

@SuppressWarnings("unused")
public aspect InterceptTestFailure {

	static int tests = 0;
	static Map<String, String> failures = new HashMap<String, String>();
	static Map<String, String> errors = new HashMap<String, String>();
	static Map<String, String> success = new HashMap<String, String>();
	static Map<String, RuntimeException> exceptions = new HashMap<String, RuntimeException>();
	static String currentTest = null;
	static String currentMethod = null;

	private static String prettyName(String name) {
		name = name.replaceAll("execution\\(\\1\\)$", "\\1");
		name = name.replaceAll("\\)$", "");
		name = name.replaceAll("org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.", "");
		name = name.substring(name.indexOf(" ") + 1);
		return name;
	}

	after(): execution(public static void CollectFailures.main(..)) {
		System.out.println(tests + " tests with " + assertions + " assertions");
		Collections.sort(methods);
		for (String method: methods) {
			System.out.println(method + ": ");
			System.out.println("\t" + assertionCount.get(method) + " assertions");
			System.out.println("\t" + failureCount.get(method) + " failed");
			System.out.println("\t" + errorCount.get(method) + " errors");
		}
//		System.out.println("***** FAILURES ****** (" + failures.size() + " out of " + tests + ")");
//		int i = 1;
//		for (String test: failures.keySet()) {
//			String prettyTest = test.replaceAll("execution\\(", "").replaceAll("\\)$", "");
//			String prettyMethod = failures.get(test);
//			prettyMethod = prettyMethod.replaceAll("execution\\(", "");
//			prettyMethod = prettyMethod.replaceAll("\\)$", "");
//			prettyMethod = prettyMethod.replaceAll("org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.", "");
//			prettyMethod = prettyMethod.substring(prettyMethod.indexOf(" ") + 1);
//			System.out.println(i + " " + prettyTest + ": " + prettyMethod);
//			i++;
//		}
//		System.out.println("***** ERRORS ****** (" + errors.size() + " out of " + tests + ")");
//		// TODO refactor...
//		i = 1;
//		for (String test: errors.keySet()) {
//			String prettyTest = test.replaceAll("execution\\(", "").replaceAll("\\)$", "");
//			String prettyMethod = errors.get(test);
//			prettyMethod = prettyMethod.replaceAll("execution\\(", "");
//			prettyMethod = prettyMethod.replaceAll("\\)$", "");
//			prettyMethod = prettyMethod.replaceAll("org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.", "");
//			prettyMethod = prettyMethod.substring(prettyMethod.indexOf(" ") + 1);
//			System.out.println(i + " " + prettyTest + ": " + prettyMethod + " ("
//					+ exceptions.get(test).getClass() + ")");
//			i++;
//		}
	}

	private static Map<String,Integer> failureCount = new HashMap<String, Integer>();
	private static Map<String,Integer> errorCount = new HashMap<String, Integer>();
	private static Map<String,Integer> assertionCount = new HashMap<String, Integer>();
	private static java.util.List<String> methods = new ArrayList<String>();
	private static int assertions = 0;
	private static String testedMethod = "<unknown>";
	private static void inc(Map<String,Integer> table, String currentMethod) {
		if (!table.containsKey(currentMethod)) {
			table.put(currentMethod, 0);
		}
		table.put(currentMethod, table.get(currentMethod) + 1);
	}

	before() : call(void assert*(..)) {
		inc(assertionCount, testedMethod);
		assertions++;
	}

	before (): execution(void test*()) {
		currentTest = thisJoinPoint.toShortString();
		testedMethod = "<unknown>";
	}

	void around(): execution(void test*()) {
		tests++;
		try {
			proceed();
		}
		catch (AssertionError e) {
			failures.put(currentTest, testedMethod);
			inc(failureCount, testedMethod);
			throw e;
		}
		catch (RuntimeException e) {
			errors.put(currentTest, testedMethod);
			exceptions.put(currentTest, e);
			inc(errorCount, testedMethod);
			throw e;
		}
		// We cannot count success; because than we only count it for the method
		// in the last assertion.
//		success.put(currentTest, currentMethod);
	}

	before(): execution(* org.planet_sl.apimigration.benchmark.jdom.wrapped_as_xom.*.*(..)) {
		currentMethod = thisJoinPoint.toString();
		String prettyName = prettyName(currentMethod);
		String name = prettyName.substring(prettyName.indexOf(".") + 1);
		name = name.replaceAll("\\(.*\\)$", "");
		name = name.toLowerCase();
		if (currentTest.toLowerCase().indexOf(name) != -1) {
			testedMethod = prettyName;
		}
		if (!methods.contains(testedMethod)) {
			methods.add(testedMethod);
		}
	}

}


corrected package name on the aspect

corrected package name on the aspect

/*
 The MIT License

Copyright (c) 2009-2014 NOrad Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */
package com.noradltd.easybuilder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public aspect TracingAspect {

	final Logger logger = LoggerFactory.getLogger(EasyBuilder.class);

	void emit(String message) {
		logger.info(message);
	}

	pointcut traceAssemblyInstruction(EasyBuilder.AssemblyInstruction instruction): target(instruction) && call(void invoke(EasyBuilder));

	before(EasyBuilder.AssemblyInstruction instruction):traceAssemblyInstruction(instruction) {
		emit("Invoking Assembly Instruction " + instruction.toString());
	}

	pointcut traceAssembleObject(EasyBuilder builder):target(builder) && call(Object assembleObject());

	before(EasyBuilder builder):traceAssembleObject(builder) {
		emit("Assembling Object with " + builder.toString());
	}

	pointcut tracePreCompileResult(EasyBuilder builder):target(builder) && call(void preCompile());

	before(EasyBuilder builder):tracePreCompileResult(builder) {
		emit("Before PreCompile: AssemblyInstructions " + builder.toString());
	}

	after(EasyBuilder builder):tracePreCompileResult(builder) {
		emit("After PreCompile: AssemblyInstructions " + builder.toString());
	}

}

/*
 The MIT License

Copyright (c) 2009-2014 NOrad Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */
package easybuilder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public aspect TracingAspect {

	final Logger logger = LoggerFactory.getLogger(EasyBuilder.class);

	void emit(String message) {
		logger.info(message);
	}

	pointcut traceAssemblyInstruction(EasyBuilder.AssemblyInstruction instruction): target(instruction) && call(void invoke(EasyBuilder));

	before(EasyBuilder.AssemblyInstruction instruction):traceAssemblyInstruction(instruction) {
		emit("Invoking Assembly Instruction " + instruction.toString());
	}

	pointcut traceAssembleObject(EasyBuilder builder):target(builder) && call(Object assembleObject());

	before(EasyBuilder builder):traceAssembleObject(builder) {
		emit("Assembling Object with " + builder.toString());
	}

	pointcut tracePreCompileResult(EasyBuilder builder):target(builder) && call(void preCompile());

	before(EasyBuilder builder):tracePreCompileResult(builder) {
		emit("Before PreCompile: AssemblyInstructions " + builder.toString());
	}

	after(EasyBuilder builder):tracePreCompileResult(builder) {
		emit("After PreCompile: AssemblyInstructions " + builder.toString());
	}

}