Fixed #3114.

Fixed #3114.

git-svn-id: f4ecfe233223879a4a16cd7937f11b5152963d8e@21046 5e8d7ff9-d8ef-0310-90f0-a4852d11357a

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

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

import java.util.HashSet;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.search.TypeNameMatch;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.IGenericType;
import org.eclipse.jdt.internal.compiler.env.ISourceImport;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.core.ClassFile;
import org.eclipse.jdt.internal.core.CompilationUnitElementInfo;
import org.eclipse.jdt.internal.core.ImportDeclaration;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.NameLookup;
import org.eclipse.jdt.internal.core.Openable;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.core.SourceMapper;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver;
import org.eclipse.jdt.internal.core.hierarchy.HierarchyType;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.jdt.internal.corext.util.OpenTypeHistory;
import org.eclipse.jdt.internal.ui.filters.InnerClassFilesFilter;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jface.viewers.Viewer;

import scala.tools.eclipse.contribution.weaving.jdt.IScalaClassFile;
import scala.tools.eclipse.contribution.weaving.jdt.IScalaElement;

@SuppressWarnings("restriction")
public privileged aspect ClassFileProviderAspect {

  pointcut classFileCreations(PackageFragment parent, String name) :
    call(protected ClassFile.new(PackageFragment, String)) &&
    within(org.eclipse.jdt..*) &&
    args(parent, name);

  pointcut getTypeName(ClassFile cf) :
    execution(public String ClassFile.getTypeName()) &&
    target(cf);

  pointcut getType(ClassFile cf) :
    call(public IType ClassFile.getType()) &&
    target(cf);

  pointcut mapSource() :
    execution(IBuffer ClassFile.mapSource(SourceMapper, IBinaryType)) &&
    target(IScalaClassFile);

  pointcut mapSource2() :
    execution(void SourceMapper.mapSource(IType, char[], IBinaryType));

  pointcut getSourceFileName(BinaryType bt) :
    execution(String BinaryType.getSourceFileName(IBinaryType)) &&
    target(bt);

  pointcut select(Viewer viewer, Object parentElement, Object element) :
    execution(boolean InnerClassFilesFilter.select(Viewer, Object, Object)) &&
    args(viewer, parentElement, element);

  pointcut getChildren(BinaryType bt) :
    execution(IJavaElement[] BinaryType.getChildren()) &&
    target(bt);

  pointcut getAST(ITypeRoot element, SharedASTProvider.WAIT_FLAG waitFlag, IProgressMonitor progressMonitor) :
    execution(CompilationUnit SharedASTProvider.getAST(ITypeRoot, SharedASTProvider.WAIT_FLAG, IProgressMonitor)) &&
    args(element, waitFlag, progressMonitor);

  pointcut resolve(HierarchyResolver hr, IGenericType suppliedType) :
    execution(void HierarchyResolver.resolve(IGenericType)) &&
    target(hr) &&
    args(suppliedType);

  pointcut remember(HierarchyResolver hr, IType type, ReferenceBinding typeBinding) :
    execution(void HierarchyResolver.remember(IType, ReferenceBinding)) &&
    target(hr) &&
    args(type, typeBinding);

  pointcut acceptType(IType type, int acceptFlags, boolean isSourceType) :
    execution(boolean NameLookup.acceptType(IType, int, boolean)) &&
    args(type, acceptFlags, isSourceType);

  pointcut find(SearchableEnvironment se, String typeName, String packageName) :
    execution(NameEnvironmentAnswer find(String, String)) &&
    target(se) &&
    args(typeName, packageName);

  pointcut convert(SourceTypeConverter stc, ISourceType[] sourceTypes, CompilationResult compilationResult) :
    execution(CompilationUnitDeclaration SourceTypeConverter.convert(ISourceType[], CompilationResult)) &&
    target(stc) &&
    args(sourceTypes, compilationResult);

  pointcut getAncestor(JavaElement je, int ancestorType) :
    execution(IJavaElement JavaElement.getAncestor(int)) &&
    target(je) &&
    args(ancestorType);

  pointcut isContainerDirty(TypeNameMatch match) :
    execution(boolean OpenTypeHistory.isContainerDirty(TypeNameMatch)) &&
    args(match);

  ClassFile around(PackageFragment parent, String name) :
    classFileCreations(parent, name) {

    ClassFile javaClassFile = proceed(parent, name);
    byte[] bytes;

    try {
      bytes = javaClassFile.getBytes();
    } catch(Throwable t) {
      return javaClassFile;
    }

    for (IClassFileProvider provider : ClassFileProviderRegistry.getInstance().getProviders()) {
      ClassFile cf = provider.create(bytes, parent, name);
      if (cf != null)
        return cf;
    }

    return javaClassFile;
  }

  void around() :
    mapSource2() &&
    cflow(mapSource()) {
    return;
  }

  IType around(ClassFile cf) :
    getType(cf) &&
    cflow(mapSource()) {
    if (cf.binaryType == null)
      cf.binaryType = new BinaryType(cf, cf.getTypeName());
    return cf.binaryType;
  }

  String around(ClassFile cf) :
    getTypeName(cf) {
    if(cf instanceof IScalaClassFile) {
      int lastDollar = cf.name.lastIndexOf('$');
      return (lastDollar == -1 || lastDollar == cf.name.length()-1) ? cf.name : Util.localTypeName(cf.name, lastDollar, cf.name.length());
    } else
      return proceed(cf);
  }

  boolean around(Viewer viewer, Object parentElement, Object element) :
    select(viewer, parentElement, element) {
    if (element instanceof IScalaClassFile) {
      IClassFile classFile = (IClassFile) element;
      String name = classFile.getElementName();
      int dollarIndex = name.indexOf('$');
      return dollarIndex == -1 || dollarIndex == name.length()-7; // Trailing '$' implies object rather than inner class
    }
    return proceed(viewer, parentElement, element);
  }

  IJavaElement[] around(BinaryType bt) throws JavaModelException :
    getChildren(bt) &&
    target(BinaryType) {
    ClassFile cf = (ClassFile)bt.parent;
    if (cf instanceof IScalaClassFile)
      return cf.getChildren();
    else
      return proceed(bt);
  }

  CompilationUnit around(ITypeRoot element, SharedASTProvider.WAIT_FLAG waitFlag, IProgressMonitor progressMonitor) :
    getAST(element, waitFlag, progressMonitor) {
      if (element instanceof IScalaElement)
        return null;
      else
        return proceed(element, waitFlag, progressMonitor);
  }

  void around(HierarchyResolver hr, IGenericType suppliedType) :
    resolve(hr, suppliedType) {
    if (!suppliedType.isBinaryType()) {
      IType tpe = ((SourceTypeElementInfo)suppliedType).getHandle();
      IClassFile cf = tpe.getClassFile();
      if (cf instanceof IScalaClassFile) {
        hr.resolve(new Openable[]{(Openable)cf}, new HashSet(), null);
        return;
      }
    }

    proceed(hr, suppliedType);
  }

  void around(HierarchyResolver hr, IType type, ReferenceBinding typeBinding) :
    remember(hr, type, typeBinding) {
    if (((IOpenable)type.getCompilationUnit()).isOpen()) {
      try {
        IGenericType genericType = (IGenericType)((JavaElement)type).getElementInfo();
        hr.remember(genericType, typeBinding);
      } catch (JavaModelException e) {
        // cannot happen since element is open
        return;
      }
    } else {
      if (typeBinding == null) return;

      TypeDeclaration typeDeclaration = ((SourceTypeBinding)typeBinding).scope.referenceType();

      // simple super class name
      char[] superclassName = null;
      TypeReference superclass;
      if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
        superclass = typeDeclaration.allocation.type;
      } else {
        superclass = typeDeclaration.superclass;
      }
      if (superclass != null) {
        char[][] typeName = superclass.getTypeName();
        superclassName = typeName == null ? null : typeName[typeName.length-1];
      }

      // simple super interface names
      char[][] superInterfaceNames = null;
      TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
      if (superInterfaces != null) {
        int length = superInterfaces.length;
        superInterfaceNames = new char[length][];
        for (int i = 0; i < length; i++) {
          TypeReference superInterface = superInterfaces[i];
          char[][] typeName = superInterface.getTypeName();
          superInterfaceNames[i] = typeName[typeName.length-1];
        }
      }

      HierarchyType hierarchyType = new HierarchyType(
        type,
        typeDeclaration.name,
        typeDeclaration.binding.modifiers,
        superclassName,
        superInterfaceNames);
      hr.remember(hierarchyType, typeDeclaration.binding);
    }
  }

  String around(BinaryType bt) :
    getSourceFileName(bt) {
    IJavaElement parent = bt.getParent();
    if (parent instanceof IScalaClassFile)
      return ((IScalaClassFile)parent).getSourceFileName();
    else
      return proceed(bt);
  }

  boolean around(IType type, int acceptFlags, boolean isSourceType) :
    acceptType(type, acceptFlags, isSourceType) {
    if (!isSourceType && (type instanceof SourceType)) {
      IJavaElement parent = type.getParent();
      if (parent instanceof IScalaClassFile)
        return proceed(type, acceptFlags, true);
    }

    return proceed(type, acceptFlags, isSourceType);
  }

  CompilationUnitDeclaration around(SourceTypeConverter stc, ISourceType[] sourceTypes, CompilationResult compilationResult) throws JavaModelException :
    convert(stc, sourceTypes, compilationResult) {
    stc.unit = new CompilationUnitDeclaration(stc.problemReporter, compilationResult, 0);
    // not filled at this point

    if (sourceTypes.length == 0) return stc.unit;
    SourceTypeElementInfo topLevelTypeInfo = (SourceTypeElementInfo) sourceTypes[0];
    org.eclipse.jdt.core.ICompilationUnit cuHandle = topLevelTypeInfo.getHandle().getCompilationUnit();
    stc.cu = (ICompilationUnit) cuHandle;

    CompilationUnitElementInfo cuei = null;
    Object info = ((JavaElement)stc.cu).getElementInfo();
    if (info instanceof CompilationUnitElementInfo)
      cuei = (CompilationUnitElementInfo)info;

    if (stc.has1_5Compliance && cuei != null && cuei.annotationNumber > 10) { // experimental value
      // if more than 10 annotations, diet parse as this is faster
      return new Parser(stc.problemReporter, true).dietParse(stc.cu, compilationResult);
    }

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

    /* convert package and imports */
    String[] packageName = ((PackageFragment) cuHandle.getParent()).names;
    if (packageName.length > 0)
      // if its null then it is defined in the default package
      stc.unit.currentPackage =
        stc.createImportReference(packageName, start, end, false, ClassFileConstants.AccDefault);
    IImportDeclaration[] importDeclarations = topLevelTypeInfo.getHandle().getCompilationUnit().getImports();
    int importCount = importDeclarations.length;
    stc.unit.imports = new ImportReference[importCount];
    for (int i = 0; i < importCount; i++) {
      ImportDeclaration importDeclaration = (ImportDeclaration) importDeclarations[i];
      ISourceImport sourceImport = (ISourceImport) importDeclaration.getElementInfo();
      String nameWithoutStar = importDeclaration.getNameWithoutStar();
      stc.unit.imports[i] = stc.createImportReference(
        Util.splitOn('.', nameWithoutStar, 0, nameWithoutStar.length()),
        sourceImport.getDeclarationSourceStart(),
        sourceImport.getDeclarationSourceEnd(),
        importDeclaration.isOnDemand(),
        sourceImport.getModifiers());
    }
    /* convert type(s) */
    try {
      int typeCount = sourceTypes.length;
      final TypeDeclaration[] types = new TypeDeclaration[typeCount];
      /*
       * We used a temporary types collection to prevent this.unit.types from being null during a call to
       * convert(...) when the source is syntactically incorrect and the parser is flushing the unit's types.
       * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97466
       */
      for (int i = 0; i < typeCount; i++) {
        SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) sourceTypes[i];
        types[i] = stc.convert((SourceType) typeInfo.getHandle(), compilationResult);
      }
      stc.unit.types = types;
      return stc.unit;
    } catch (SourceTypeConverter.AnonymousMemberFound e) {
      return new Parser(stc.problemReporter, true).parse(stc.cu, compilationResult);
    }
  }

  IJavaElement around(JavaElement je, int ancestorType) :
    getAncestor(je, ancestorType) {
    IJavaElement element = je;
    while (element != null) {
      if (element.getElementType() == ancestorType)
        return element;
      else if (element instanceof IScalaClassFile && ancestorType == IJavaElement.COMPILATION_UNIT)
        return ((JavaElement)element).getCompilationUnit();
      element= element.getParent();
    }
    return null;
  }

  boolean around(TypeNameMatch match) :
    isContainerDirty(match) {
    org.eclipse.jdt.core.ICompilationUnit cu = match.getType().getCompilationUnit();
    if (cu == null) {
      return false;
    }
    IResource resource= cu.getResource();
    if (resource == null)
      return false;

    ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
    ITextFileBuffer textFileBuffer= manager.getTextFileBuffer(resource.getFullPath(), LocationKind.IFILE);
    if (textFileBuffer != null) {
      return textFileBuffer.isDirty();
    }
    return false;
  }
}

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

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

import java.util.HashSet;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.ITextFileBufferManager;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.search.TypeNameMatch;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.IGenericType;
import org.eclipse.jdt.internal.compiler.env.ISourceImport;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.core.BinaryType;
import org.eclipse.jdt.internal.core.ClassFile;
import org.eclipse.jdt.internal.core.CompilationUnitElementInfo;
import org.eclipse.jdt.internal.core.ImportDeclaration;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.NameLookup;
import org.eclipse.jdt.internal.core.Openable;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.core.SourceMapper;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.hierarchy.HierarchyResolver;
import org.eclipse.jdt.internal.core.hierarchy.HierarchyType;
import org.eclipse.jdt.internal.core.util.Util;
import org.eclipse.jdt.internal.corext.util.OpenTypeHistory;
import org.eclipse.jdt.internal.ui.filters.InnerClassFilesFilter;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jface.viewers.Viewer;

import scala.tools.eclipse.contribution.weaving.jdt.IScalaClassFile;
import scala.tools.eclipse.contribution.weaving.jdt.IScalaElement;

@SuppressWarnings("restriction")
public privileged aspect ClassFileProviderAspect {

  pointcut classFileCreations(PackageFragment parent, String name) :
    call(protected ClassFile.new(PackageFragment, String)) &&
    within(org.eclipse.jdt..*) &&
    args(parent, name);

  pointcut getTypeName(ClassFile cf) :
    execution(public String ClassFile.getTypeName()) &&
    target(cf);

  pointcut mapSource() :
    execution(IBuffer ClassFile.mapSource(SourceMapper, IBinaryType)) &&
    target(IScalaClassFile);

  pointcut mapSource2() :
    execution(void SourceMapper.mapSource(IType, char[], IBinaryType));

  pointcut getSourceFileName(BinaryType bt) :
    execution(String BinaryType.getSourceFileName(IBinaryType)) &&
    target(bt);

  pointcut select(Viewer viewer, Object parentElement, Object element) :
    execution(boolean InnerClassFilesFilter.select(Viewer, Object, Object)) &&
    args(viewer, parentElement, element);

  pointcut getChildren(BinaryType bt) :
    execution(IJavaElement[] BinaryType.getChildren()) &&
    target(bt);

  pointcut getAST(ITypeRoot element, SharedASTProvider.WAIT_FLAG waitFlag, IProgressMonitor progressMonitor) :
    execution(CompilationUnit SharedASTProvider.getAST(ITypeRoot, SharedASTProvider.WAIT_FLAG, IProgressMonitor)) &&
    args(element, waitFlag, progressMonitor);

  pointcut resolve(HierarchyResolver hr, IGenericType suppliedType) :
    execution(void HierarchyResolver.resolve(IGenericType)) &&
    target(hr) &&
    args(suppliedType);

  pointcut remember(HierarchyResolver hr, IType type, ReferenceBinding typeBinding) :
    execution(void HierarchyResolver.remember(IType, ReferenceBinding)) &&
    target(hr) &&
    args(type, typeBinding);

  pointcut acceptType(IType type, int acceptFlags, boolean isSourceType) :
    execution(boolean NameLookup.acceptType(IType, int, boolean)) &&
    args(type, acceptFlags, isSourceType);

  pointcut find(SearchableEnvironment se, String typeName, String packageName) :
    execution(NameEnvironmentAnswer find(String, String)) &&
    target(se) &&
    args(typeName, packageName);

  pointcut convert(SourceTypeConverter stc, ISourceType[] sourceTypes, CompilationResult compilationResult) :
    execution(CompilationUnitDeclaration SourceTypeConverter.convert(ISourceType[], CompilationResult)) &&
    target(stc) &&
    args(sourceTypes, compilationResult);

  pointcut getAncestor(JavaElement je, int ancestorType) :
    execution(IJavaElement JavaElement.getAncestor(int)) &&
    target(je) &&
    args(ancestorType);

  pointcut isContainerDirty(TypeNameMatch match) :
    execution(boolean OpenTypeHistory.isContainerDirty(TypeNameMatch)) &&
    args(match);

  ClassFile around(PackageFragment parent, String name) :
    classFileCreations(parent, name) {

    ClassFile javaClassFile = proceed(parent, name);
    byte[] bytes;

    try {
      bytes = javaClassFile.getBytes();
    } catch(Throwable t) {
      return javaClassFile;
    }

    for (IClassFileProvider provider : ClassFileProviderRegistry.getInstance().getProviders()) {
      ClassFile cf = provider.create(bytes, parent, name);
      if (cf != null)
        return cf;
    }

    return javaClassFile;
  }

  void around() :
    mapSource2() &&
    cflow(mapSource()) {
    return;
  }

  String around(ClassFile cf) :
    getTypeName(cf) {
    if(cf instanceof IScalaClassFile) {
      int lastDollar = cf.name.lastIndexOf('$');
      return (lastDollar == -1 || lastDollar == cf.name.length()-1) ? cf.name : Util.localTypeName(cf.name, lastDollar, cf.name.length());
    } else
      return proceed(cf);
  }

  boolean around(Viewer viewer, Object parentElement, Object element) :
    select(viewer, parentElement, element) {
    if (element instanceof IScalaClassFile) {
      IClassFile classFile = (IClassFile) element;
      String name = classFile.getElementName();
      int dollarIndex = name.indexOf('$');
      return dollarIndex == -1 || dollarIndex == name.length()-7; // Trailing '$' implies object rather than inner class
    }
    return proceed(viewer, parentElement, element);
  }

  IJavaElement[] around(BinaryType bt) throws JavaModelException :
    getChildren(bt) &&
    target(BinaryType) {
    ClassFile cf = (ClassFile)bt.parent;
    if (cf instanceof IScalaClassFile)
      return cf.getChildren();
    else
      return proceed(bt);
  }

  CompilationUnit around(ITypeRoot element, SharedASTProvider.WAIT_FLAG waitFlag, IProgressMonitor progressMonitor) :
    getAST(element, waitFlag, progressMonitor) {
      if (element instanceof IScalaElement)
        return null;
      else
        return proceed(element, waitFlag, progressMonitor);
  }

  void around(HierarchyResolver hr, IGenericType suppliedType) :
    resolve(hr, suppliedType) {
    if (!suppliedType.isBinaryType()) {
      IType tpe = ((SourceTypeElementInfo)suppliedType).getHandle();
      IClassFile cf = tpe.getClassFile();
      if (cf instanceof IScalaClassFile) {
        hr.resolve(new Openable[]{(Openable)cf}, new HashSet(), null);
        return;
      }
    }

    proceed(hr, suppliedType);
  }

  void around(HierarchyResolver hr, IType type, ReferenceBinding typeBinding) :
    remember(hr, type, typeBinding) {
    if (((IOpenable)type.getCompilationUnit()).isOpen()) {
      try {
        IGenericType genericType = (IGenericType)((JavaElement)type).getElementInfo();
        hr.remember(genericType, typeBinding);
      } catch (JavaModelException e) {
        // cannot happen since element is open
        return;
      }
    } else {
      if (typeBinding == null) return;

      TypeDeclaration typeDeclaration = ((SourceTypeBinding)typeBinding).scope.referenceType();

      // simple super class name
      char[] superclassName = null;
      TypeReference superclass;
      if ((typeDeclaration.bits & ASTNode.IsAnonymousType) != 0) {
        superclass = typeDeclaration.allocation.type;
      } else {
        superclass = typeDeclaration.superclass;
      }
      if (superclass != null) {
        char[][] typeName = superclass.getTypeName();
        superclassName = typeName == null ? null : typeName[typeName.length-1];
      }

      // simple super interface names
      char[][] superInterfaceNames = null;
      TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
      if (superInterfaces != null) {
        int length = superInterfaces.length;
        superInterfaceNames = new char[length][];
        for (int i = 0; i < length; i++) {
          TypeReference superInterface = superInterfaces[i];
          char[][] typeName = superInterface.getTypeName();
          superInterfaceNames[i] = typeName[typeName.length-1];
        }
      }

      HierarchyType hierarchyType = new HierarchyType(
        type,
        typeDeclaration.name,
        typeDeclaration.binding.modifiers,
        superclassName,
        superInterfaceNames);
      hr.remember(hierarchyType, typeDeclaration.binding);
    }
  }

  String around(BinaryType bt) :
    getSourceFileName(bt) {
    IJavaElement parent = bt.getParent();
    if (parent instanceof IScalaClassFile)
      return ((IScalaClassFile)parent).getSourceFileName();
    else
      return proceed(bt);
  }

  boolean around(IType type, int acceptFlags, boolean isSourceType) :
    acceptType(type, acceptFlags, isSourceType) {
    if (!isSourceType && (type instanceof SourceType)) {
      IJavaElement parent = type.getParent();
      if (parent instanceof IScalaClassFile)
        return proceed(type, acceptFlags, true);
    }

    return proceed(type, acceptFlags, isSourceType);
  }

  CompilationUnitDeclaration around(SourceTypeConverter stc, ISourceType[] sourceTypes, CompilationResult compilationResult) throws JavaModelException :
    convert(stc, sourceTypes, compilationResult) {
    stc.unit = new CompilationUnitDeclaration(stc.problemReporter, compilationResult, 0);
    // not filled at this point

    if (sourceTypes.length == 0) return stc.unit;
    SourceTypeElementInfo topLevelTypeInfo = (SourceTypeElementInfo) sourceTypes[0];
    org.eclipse.jdt.core.ICompilationUnit cuHandle = topLevelTypeInfo.getHandle().getCompilationUnit();
    stc.cu = (ICompilationUnit) cuHandle;

    CompilationUnitElementInfo cuei = null;
    Object info = ((JavaElement)stc.cu).getElementInfo();
    if (info instanceof CompilationUnitElementInfo)
      cuei = (CompilationUnitElementInfo)info;

    if (stc.has1_5Compliance && cuei != null && cuei.annotationNumber > 10) { // experimental value
      // if more than 10 annotations, diet parse as this is faster
      return new Parser(stc.problemReporter, true).dietParse(stc.cu, compilationResult);
    }

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

    /* convert package and imports */
    String[] packageName = ((PackageFragment) cuHandle.getParent()).names;
    if (packageName.length > 0)
      // if its null then it is defined in the default package
      stc.unit.currentPackage =
        stc.createImportReference(packageName, start, end, false, ClassFileConstants.AccDefault);
    IImportDeclaration[] importDeclarations = topLevelTypeInfo.getHandle().getCompilationUnit().getImports();
    int importCount = importDeclarations.length;
    stc.unit.imports = new ImportReference[importCount];
    for (int i = 0; i < importCount; i++) {
      ImportDeclaration importDeclaration = (ImportDeclaration) importDeclarations[i];
      ISourceImport sourceImport = (ISourceImport) importDeclaration.getElementInfo();
      String nameWithoutStar = importDeclaration.getNameWithoutStar();
      stc.unit.imports[i] = stc.createImportReference(
        Util.splitOn('.', nameWithoutStar, 0, nameWithoutStar.length()),
        sourceImport.getDeclarationSourceStart(),
        sourceImport.getDeclarationSourceEnd(),
        importDeclaration.isOnDemand(),
        sourceImport.getModifiers());
    }
    /* convert type(s) */
    try {
      int typeCount = sourceTypes.length;
      final TypeDeclaration[] types = new TypeDeclaration[typeCount];
      /*
       * We used a temporary types collection to prevent this.unit.types from being null during a call to
       * convert(...) when the source is syntactically incorrect and the parser is flushing the unit's types.
       * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=97466
       */
      for (int i = 0; i < typeCount; i++) {
        SourceTypeElementInfo typeInfo = (SourceTypeElementInfo) sourceTypes[i];
        types[i] = stc.convert((SourceType) typeInfo.getHandle(), compilationResult);
      }
      stc.unit.types = types;
      return stc.unit;
    } catch (SourceTypeConverter.AnonymousMemberFound e) {
      return new Parser(stc.problemReporter, true).parse(stc.cu, compilationResult);
    }
  }

  IJavaElement around(JavaElement je, int ancestorType) :
    getAncestor(je, ancestorType) {
    IJavaElement element = je;
    while (element != null) {
      if (element.getElementType() == ancestorType)
        return element;
      else if (element instanceof IScalaClassFile && ancestorType == IJavaElement.COMPILATION_UNIT)
        return ((JavaElement)element).getCompilationUnit();
      element= element.getParent();
    }
    return null;
  }

  boolean around(TypeNameMatch match) :
    isContainerDirty(match) {
    org.eclipse.jdt.core.ICompilationUnit cu = match.getType().getCompilationUnit();
    if (cu == null) {
      return false;
    }
    IResource resource= cu.getResource();
    if (resource == null)
      return false;

    ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
    ITextFileBuffer textFileBuffer= manager.getTextFileBuffer(resource.getFullPath(), LocationKind.IFILE);
    if (textFileBuffer != null) {
      return textFileBuffer.isDirty();
    }
    return false;
  }
}


- clear wrong aspect

- clear wrong aspect

package ru.agentlab.maia.context.injector.log;

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

import ru.agentlab.maia.memory.IMaiaContext;
import ru.agentlab.maia.memory.aj.AMaiaContextFactory;

public aspect AMaiaContextInjectorLog extends AMaiaContextFactory {

//	before(IMaiaContextFactory factory) :
//		onCreateContext(factory) {
//		Logger logger = LoggerFactory.getLogger(factory.getClass());
//		logger.info("Try to create context...");
//	}
//
//	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.injector.log;

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

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

public aspect AMaiaContextInjectorLog extends AMaiaContextFactory {

	before(IMaiaContextFactory factory) :
		onCreateContext(factory) {
		Logger logger = LoggerFactory.getLogger(factory.getClass());
		logger.info("Try to create context...");
	}

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


added log message for non-local case

added log message for non-local case

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * 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 de.cosmocode.palava.jpa.aspectj;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.aop.AbstractPalavaAspect;
import de.cosmocode.palava.jpa.Transactional;

public final aspect EntityTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(EntityTransactionAspect.class);

    private Provider<EntityManager> currentManager;

    @Inject
    public void setProvider(Provider<EntityManager> manager) {
        this.currentManager = Preconditions.checkNotNull(manager, "Manager");
    }

    pointcut transactional(): execution(@Transactional * *.*(..));

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final EntityManager manager = currentManager.get();
        LOG.trace("Retrieved entitymanager {}", manager);
        final EntityTransaction tx = manager.getTransaction();
        LOG.trace("Using transaction {}", tx);
        final boolean localTx = !tx.isActive();

        if (localTx) {
            LOG.trace("Beginning automatic transaction");
            tx.begin();
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (RuntimeException e) {
            LOG.debug("Exception inside automatic transaction context; rolling back", e);
            tx.rollback();
            throw e;
        }

        if (localTx && tx.isActive()) {
            if (tx.getRollbackOnly()) {
                LOG.debug("Transaction was marked as rollback only. Rolling back...");
                tx.rollback();
            } else {
                try {
                    tx.commit();
                    LOG.trace("Committed automatic transaction");
                } catch (PersistenceException e) {
                    LOG.debug("Commit in automatic transaction context failed", e);
                    if (tx.isActive()) {
                        LOG.debug("Rolling back {}", tx);
                        tx.rollback();
                    } else {
                        LOG.debug("Can't roll back inactive transaction {}", tx);
                    }
                    throw e;
                }
            }
        } else {
            LOG.trace("Not committing non-local transaction {}", tx);
        }

        return returnValue;
    }

}

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * 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 de.cosmocode.palava.jpa.aspectj;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceException;

import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Provider;

import de.cosmocode.palava.core.aop.AbstractPalavaAspect;
import de.cosmocode.palava.jpa.Transactional;

public final aspect EntityTransactionAspect extends AbstractPalavaAspect issingleton() {

    private static final Logger LOG = LoggerFactory.getLogger(EntityTransactionAspect.class);

    private Provider<EntityManager> currentManager;

    @Inject
    public void setProvider(Provider<EntityManager> manager) {
        this.currentManager = Preconditions.checkNotNull(manager, "Manager");
    }

    pointcut transactional(): execution(@Transactional * *.*(..));

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final EntityManager manager = currentManager.get();
        LOG.trace("Retrieved entitymanager {}", manager);
        final EntityTransaction tx = manager.getTransaction();
        LOG.trace("Using transaction {}", tx);
        final boolean localTx = !tx.isActive();

        if (localTx) {
            LOG.trace("Beginning automatic transaction");
            tx.begin();
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (RuntimeException e) {
            LOG.debug("Exception inside automatic transaction context; rolling back", e);
            tx.rollback();
            throw e;
        }

        if (localTx && tx.isActive()) {
            if (tx.getRollbackOnly()) {
                LOG.debug("Transaction was marked as rollback only. Rolling back...");
                tx.rollback();
            } else {
                try {
                    tx.commit();
                    LOG.trace("Committed automatic transaction");
                } catch (PersistenceException e) {
                    LOG.debug("Commit in automatic transaction context failed", e);
                    if (tx.isActive()) {
                        LOG.debug("Rolling back {}", tx);
                        tx.rollback();
                    } else {
                        LOG.debug("Can't roll back inactive transaction {}", tx);
                    }
                    throw e;
                }
            }
        }

        return returnValue;
    }

}


multipage table for pdf

multipage table for pdf

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Iterator;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import model.db.DataObject;
import model.db.GameData;
import view.GUI;
import view.SchafkopfTableModel;

public privileged aspect PdfExport {

    /** This precendence makes the order of the items in the file menu sure */
    declare precedence : Import, HtmlExport, PdfExport;
    private GUI gui;

    /**
     * catch constructor call, so that we have the correct gui, to refer to everywhere
     */
    after() returning(GUI gui): call(GUI.new(*)) {
        this.gui = gui;
    }

    private String[][] SchafkopfTableModel.asTextArray() {
        String[][] completeTable = data.asTextArray();

        String[] headerLine = new String[getColumnCount()];
        for (int i = 0; i < getColumnCount(); i++) {
            headerLine[i] = getColumnName(i);
        }
        completeTable[0] = headerLine;
        return completeTable;
    }

    private String[][] GameData.asTextArray() {
        Iterator<DataObject> it = data.iterator();
        String[][] rows = new String[data.size()+1][];
        int index = 1;
        while (it.hasNext()) {
            rows[index] = it.next().asTextArray(index-1);
            index++;
        }
        return rows;
    }

    /**
     * Add pdf report feature to menu bar
     */
    after() returning(JMenuBar bar): call(JMenuBar GUI.createMenu()) {
        JMenuItem itemExportPdf = new JMenuItem("Generiere PDF Report");
        itemExportPdf.addActionListener(new PDFReportListener());

        Component[] menus = bar.getComponents();
        if (menus.length != 0 && menus[0] instanceof JMenu) {
            ((JMenu)bar.getComponents()[0]).add(itemExportPdf, 0);
        } else {
            throw new AssertionError("There should be a menu entry!");
        }
    }

    /**
     * generate pdf report (execution of PDFReportListener is suppressed, this
     * is just an empty method, to be able to create this pointcut
     */
    void around(PDDocument document) throws IOException
          : execution (* PDFReportListener.drawTable(PDDocument))
          && args(document) {

        String[][] content = ((SchafkopfTableModel) gui.table.getModel()).asTextArray();

        // we have inches in us letter (8.5x11) therefore calculate correct width in points here
        // 1 pt = 1/72 inch
        final int height = 11 * 72;
        final int width = (int) (8.5* 72);
        // some values for drawing the table
        final int margin = 50;
        final int rowHeight = 20;
        final int maxRowsPerPage = (int) (height - 2*margin) / rowHeight;
        final int tableWidth = width - (2*margin);
        final int cellMargin=5;

        int rowsToBeDone = content.length;
        int actRow = 0;
        final int cols = content[0].length;
        final float colWidth = tableWidth/(float)cols;

        //draw the table
        do {
            // create initial page
            PDPage page = new PDPage();
            document.addPage(page);
            PDPageContentStream contentStream = new PDPageContentStream(document, page);
            final float tableHeight = rowHeight * (Math.min(rowsToBeDone, maxRowsPerPage));
            float y = height - margin;

            // draw table borders
            float nexty = y;
            for (int i = 0; i <= Math.min(rowsToBeDone, maxRowsPerPage); i++) {
                contentStream.drawLine(margin,nexty,margin+tableWidth,nexty);
                nexty-= rowHeight;
            }
            float nextx = margin;
            for (int i = 0; i <= cols; i++) {
                contentStream.drawLine(nextx,y,nextx,y-tableHeight);
                nextx += colWidth;
            }

          //now add the text
            contentStream.setFont(PDType1Font.HELVETICA_BOLD,10);
            float textx = margin+cellMargin;
            float texty = y-15;
            for(int i = actRow; i < Math.min(rowsToBeDone, maxRowsPerPage)+actRow; i++){
                for(int j = 0 ; j < cols; j++){
                    contentStream.beginText();
                    contentStream.moveTextPositionByAmount(textx,texty);
                    contentStream.drawString(content[i][j]);
                    contentStream.endText();
                    textx += colWidth;
                }
                texty-=rowHeight;
                textx = margin+cellMargin;
            }
            contentStream.close();

            // reduce number of rows that still have to be done
            rowsToBeDone -= maxRowsPerPage;
            actRow += maxRowsPerPage;
        } while (rowsToBeDone > 0);
    }
}

class PDFReportListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // Create a document and add a page to it
        PDDocument document = new PDDocument();

        try {
            drawTable(document);

            // Save the results and ensure that the document is properly closed:
            document.save("Session_vom_"+new SimpleDateFormat("dd.MM_'um'_HH:mm").format(Calendar.getInstance().getTime()) + ".pdf");
        } catch (IOException | COSVisitorException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** filled with pointcut from pdfExport.aj*/
    public static void drawTable(PDDocument document) throws IOException {
    }
}

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Iterator;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

import model.db.DataObject;
import model.db.GameData;
import view.GUI;
import view.SchafkopfTableModel;

public privileged aspect PdfExport {

    /** This precendence makes the order of the items in the file menu sure */
    declare precedence : Import, HtmlExport, PdfExport;
    private GUI gui;

    /**
     * catch constructor call, so that we have the correct gui, to refer to everywhere
     */
    after() returning(GUI gui): call(GUI.new(*)) {
        this.gui = gui;
    }

    private String[][] SchafkopfTableModel.asTextArray() {
        String[][] completeTable = data.asTextArray();

        String[] headerLine = new String[getColumnCount()];
        for (int i = 0; i < getColumnCount(); i++) {
            headerLine[i] = getColumnName(i);
        }
        completeTable[0] = headerLine;
        return completeTable;
    }

    private String[][] GameData.asTextArray() {
        Iterator<DataObject> it = data.iterator();
        String[][] rows = new String[data.size()+1][];
        int index = 1;
        while (it.hasNext()) {
            rows[index] = it.next().asTextArray(index-1);
            index++;
        }
        return rows;
    }

    /**
     * Add pdf report feature to menu bar
     */
    after() returning(JMenuBar bar): call(JMenuBar GUI.createMenu()) {
        JMenuItem itemExportPdf = new JMenuItem("Generiere PDF Report");
        itemExportPdf.addActionListener(new PDFReportListener());

        Component[] menus = bar.getComponents();
        if (menus.length != 0 && menus[0] instanceof JMenu) {
            ((JMenu)bar.getComponents()[0]).add(itemExportPdf, 0);
        } else {
            throw new AssertionError("There should be a menu entry!");
        }
    }

    /**
     * generate pdf report (execution of PDFReportListener is suppressed, this
     * is just an empty method, to be able to create this pointcut
     */
    void around(PDDocument document) throws IOException
          : execution (* PDFReportListener.drawTable(PDDocument))
          && args(document) {
        PDPage page = new PDPage();
        document.addPage(page);
        PDPageContentStream contentStream = new PDPageContentStream(document, page);
        float y =750f;
        float margin =60f;
        String[][] content = ((SchafkopfTableModel) gui.table.getModel()).asTextArray();

        final int rows = content.length;
        final int cols = content[0].length;
        final float rowHeight = 20f;
        final float tableWidth = page.findMediaBox().getWidth()-(2*margin);
        final float tableHeight = rowHeight * rows;
        final float colWidth = tableWidth/(float)cols;
        final float cellMargin=5f;

        // TODO multisite tables
        //draw the rows
        float nexty = y ;
        for (int i = 0; i <= rows; i++) {
            contentStream.drawLine(margin,nexty,margin+tableWidth,nexty);
            nexty-= rowHeight;
        }

        //draw the columns
        float nextx = margin;
        for (int i = 0; i <= cols; i++) {
            contentStream.drawLine(nextx,y,nextx,y-tableHeight);
            nextx += colWidth;
        }

        //now add the text
        contentStream.setFont(PDType1Font.HELVETICA_BOLD,10);

        float textx = margin+cellMargin;
        float texty = y-15;
        for(int i = 0; i < content.length; i++){
            for(int j = 0 ; j < content[i].length; j++){
                String text = content[i][j];
                contentStream.beginText();
                contentStream.moveTextPositionByAmount(textx,texty);
                contentStream.drawString(text);
                contentStream.endText();
                textx += colWidth;
            }
            texty-=rowHeight;
            textx = margin+cellMargin;
        }
        contentStream.close();
    }
}

class PDFReportListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // Create a document and add a page to it
        PDDocument document = new PDDocument();

        try {
            drawTable(document);

            // Save the results and ensure that the document is properly closed:
            document.save("Session_vom_"+new SimpleDateFormat("dd.MM_'um'_HH:mm").format(Calendar.getInstance().getTime()) + ".pdf");
        } catch (IOException | COSVisitorException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /** filled with pointcut from pdfExport.aj*/
    public static void drawTable(PDDocument document) throws IOException {
    }
}


Fixing xpp3 imports for plugin realms.

Fixing xpp3 imports for plugin realms.

git-svn-id: 2c527eb49caa05e19d6b2be874bf74fa9d7ea670@654198 13f79535-47bb-0310-9956-ffa450edef68

package org.apache.maven.compat;

import org.apache.maven.lifecycle.binding.DefaultLifecycleBindingManager;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.codehaus.plexus.PlexusContainer;
import org.apache.maven.DefaultMaven;
import org.apache.maven.lifecycle.DefaultLifecycleExecutor;
import org.apache.maven.lifecycle.MojoBindingUtils;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.NoSuchPhaseException;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.extension.DefaultExtensionManager;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.DefaultPluginManager;
import org.apache.maven.plugin.InvalidPluginException;
import org.apache.maven.plugin.PluginManager;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.realm.MavenRealmManager;
import org.apache.maven.settings.MavenSettingsBuilder;
import org.apache.maven.settings.DefaultMavenSettingsBuilder;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.logging.Logger;

import java.util.List;
import java.io.IOException;
import java.util.Iterator;
import java.util.Collection;
import java.util.Set;
import java.util.LinkedHashSet;

public privileged aspect Maven20xCompatAspect
{

    // GRAB Session as soon as it's constructed.
    private MavenSession session;

    // GRAB the request when it's passed into a method that returns a corresponding result.
    // NOTE: We'll use this in multiple places below...
    private MavenExecutionRequest request;

    // Grab this so we have a voice!
    private Logger logger;

    // used for injecting plexus-utils into extension and plugin artifact sets.
    private VersionRange vr = null;
    private Artifact plexusUtilsArtifact = null;

    private pointcut mavenEmbedderStop():
        execution( * org.apache.maven.embedder.MavenEmbedder.stop( .. ) );

    // TODO: There must be a more elegant way to release these resources than depending on MavenEmbedder.stop().
    after(): mavenEmbedderStop()
    {
        session = null;
        request = null;
        logger = null;
        vr = null;
        plexusUtilsArtifact = null;
    }

    // pointcut to avoid recursive matching on behavior injected by this aspect.
    private pointcut notHere(): !within( Maven20xCompatAspect );

    private pointcut sessionCreation( MavenSession session ):
        execution( public MavenSession+.new(..) )
        && this( session )
        && notHere();

    // capture the session instance.
    after( MavenSession session ): sessionCreation( session )
    {
        if ( logger != null && logger.isDebugEnabled() )
        {
            logger.debug( "Capturing session for backward compatibility aspect: " + session );
        }

        this.session = session;
    }

    // Re-Introduce old verifyPlugin(..) API.
    public PluginDescriptor PluginManager.verifyPlugin( Plugin plugin,
                                                        MavenProject project,
                                                        Settings settings,
                                                        ArtifactRepository localRepository )
        throws ArtifactResolutionException, ArtifactNotFoundException, PluginNotFoundException,
        PluginVersionResolutionException, InvalidPluginException, PluginManagerException,
        PluginVersionNotFoundException
    {
        // this will always be diverted, so no need to do anything.
        throw new IllegalStateException( "This introduced method should ALWAYS be intercepted by backward compatibility aspect." );
    }

    // USE Session to compensate for old verifyPlugin(..) API.
    private pointcut verifyPlugin( Plugin plugin, MavenProject project, PluginManager manager ):
        execution( PluginDescriptor PluginManager+.verifyPlugin( Plugin, MavenProject, Settings, ArtifactRepository+ ) )
        && args( plugin, project, .. )
        && this( manager );

    // redirect the old verifyPlugin(..) call to the new one, using the captured session instance above.
    PluginDescriptor around( Plugin plugin,
                             MavenProject project,
                             PluginManager manager )
        throws ArtifactResolutionException, ArtifactNotFoundException, PluginNotFoundException,
        PluginVersionResolutionException, InvalidPluginException, PluginManagerException,
        PluginVersionNotFoundException:
            verifyPlugin( plugin, project, manager )
    {
        if ( logger != null && logger.isDebugEnabled() )
        {
            logger.debug( "Diverting legacy PluginManager.verifyPlugin(..) call to replacement method using session: " + session );
        }

        return manager.verifyPlugin( plugin, project, session );
    }

    private pointcut getPluginDescriptorForPrefix( String prefix, PluginManager manager ):
        execution( public PluginDescriptor PluginManager+.getPluginDescriptorForPrefix( String ) )
        && args( prefix )
        && this( manager )
        && notHere();

    PluginDescriptor around( String prefix, PluginManager manager ): getPluginDescriptorForPrefix( prefix, manager )
    {
        // TODO: Implement Me!
        throw new UnsupportedOperationException( "This method has not yet been implemented in Maven's backward-compatibility library." );
    }

    public PluginDescriptor PluginManager.getPluginDescriptorForPrefix( String prefix )
    {
        return null;
    }

    // Intercept retrieval of artifact dependencies of an extension, inject plexus-utils if it's not there.
    private pointcut extDepArtifactsResolved( DefaultExtensionManager mgr ):
        call( public Set ResolutionGroup+.getArtifacts() )
        && within( DefaultExtensionManager+ )
        && this( mgr )
        && notHere();

    // We use the same hack here to make sure that plexus 1.1 is available for extensions that do
    // not declare plexus-utils but need it. MNG-2900
    Set around( DefaultExtensionManager mgr ): extDepArtifactsResolved( mgr )
    {
        Set result = proceed( mgr );

        result = checkPlexusUtils( result, mgr.artifactFactory );

        return result;
    }

    // Intercept retrieval of artifact dependencies of a plugin, inject plexus-utils if it's not there.
    private pointcut pluginDepArtifactsResolved( DefaultPluginManager mgr ):
        call( public Set ResolutionGroup+.getArtifacts() )
        && cflow( execution( Set DefaultPluginManager+.getPluginArtifacts(..) ) )
        && this( mgr )
        && notHere();

    Set around( DefaultPluginManager mgr ): pluginDepArtifactsResolved( mgr )
    {
        Set result = proceed( mgr );

        result = checkPlexusUtils( result, mgr.artifactFactory );

        return result;
    }

    private pointcut methodsTakingRequest( MavenExecutionRequest request ):
        execution( MavenExecutionResult *.*( MavenExecutionRequest ) )
        && !withincode( * *.*( MavenExecutionRequest ) )
        && args( request )
        && notHere();

    // capture the request instance before it's passed into any method that returns a corresponding MavenExecutionResult.
    Object around( MavenExecutionRequest request ): methodsTakingRequest( request )
    {
        this.request = request;

        try
        {
            return proceed( request );
        }
        finally
        {
            this.request = null;
        }
    }

    // Re-Introduce old buildSettings() API.
    public Settings MavenSettingsBuilder.buildSettings()
        throws IOException, XmlPullParserException
    {
        return null;
    }

    public Settings DefaultMavenSettingsBuilder.buildSettings()
    throws IOException, XmlPullParserException
    {
        return null;
    }

    // USE Request to compensate for old buildSettings() API.
    private pointcut buildSettings( MavenSettingsBuilder builder ):
        execution( public Settings MavenSettingsBuilder+.buildSettings() )
        && target( builder );

    // redirect old buildSettings() call to the new one, using the request captured above.
    Settings around( MavenSettingsBuilder builder )
        throws IOException, XmlPullParserException:
            buildSettings( builder )
    {
        return builder.buildSettings( request );
    }

    private pointcut pluginManager( DefaultPluginManager manager ):
        execution( * DefaultPluginManager.*( .. ) )
        && this( manager );

    private pointcut pluginRealmCreation( Plugin plugin, DefaultPluginManager manager ):
        call( ClassRealm MavenRealmManager+.createPluginRealm( Plugin, Artifact, List, .. ) )
        && cflow( pluginManager( manager ) )
        && args( plugin, .. );

    // Add various imports for Xpp3 stuff back into the core realm every time a plugin realm is created.
    ClassRealm around( Plugin plugin, DefaultPluginManager manager ): pluginRealmCreation( plugin, manager )
    {
        ClassRealm pluginRealm = proceed( plugin, manager );

        try
        {
            String parentRealmId = manager.container.getContainerRealm().getId();

            // adding for MNG-3012 to try to work around problems with Xpp3Dom (from plexus-utils)
            // spawning a ClassCastException when a mojo calls plugin.getConfiguration() from maven-model...
            pluginRealm.importFrom( parentRealmId, Xpp3Dom.class.getName() );
            pluginRealm.importFrom( parentRealmId, "org.codehaus.plexus.util.xml.pull" );

            // Adding for MNG-2878, since maven-reporting-impl was removed from the
            // internal list of artifacts managed by maven, the classloader is different
            // between maven-reporting-impl and maven-reporting-api...so this resource
            // is not available from the AbstractMavenReport since it uses:
            // getClass().getResourceAsStream( "/default-report.xml" )
            // (maven-reporting-impl version 2.0; line 134; affects: checkstyle plugin, and probably others)
            pluginRealm.importFrom( parentRealmId, "/default-report.xml" );
        }
        catch ( NoSuchRealmException e )
        {
            // can't happen here. All realms are concretely resolved by now.
        }

        return pluginRealm;
    }

    before( DefaultMaven maven ):
        execution( MavenExecutionResult DefaultMaven.execute( MavenExecutionRequest ) )
        && this( maven )
    {
        if ( this.logger == null )
        {
            this.logger = maven.getLogger();
        }
    }

    private pointcut addMojoBindingCall( String phase, MojoBinding binding ):
        call( void LifecycleUtils.addMojoBinding( String, MojoBinding, .. ) )
        && args( phase, binding, .. );

    void around( String phase, MojoBinding binding ): addMojoBindingCall( phase, binding )
    {
        try
        {
            proceed( phase, binding );
        }
        catch ( NoSuchPhaseException e )
        {
            logger.debug( "Mojo execution: " + MojoBindingUtils.toString( binding )
                          + " cannot be attached to lifecycle phase: " + phase
                          + "; it does not exist. Ignoring this binding." );
        }
    }

    // --------------------------
    // UTILITIES
    // --------------------------

    private Set checkPlexusUtils( Set dependencyArtifacts, ArtifactFactory artifactFactory )
    {
        // ----------------------------------------------------------------------------
        // If the plugin already declares a dependency on plexus-utils then we're all
        // set as the plugin author is aware of its use. If we don't have a dependency
        // on plexus-utils then we must protect users from stupid plugin authors who
        // did not declare a direct dependency on plexus-utils because the version
        // Maven uses is hidden from downstream use. We will also bump up any
        // anything below 1.1 to 1.1 as this mimics the behaviour in 2.0.5 where
        // plexus-utils 1.1 was being forced into use.
        // ----------------------------------------------------------------------------

        if ( vr == null )
        {
            try
            {
                vr = VersionRange.createFromVersionSpec( "[1.1,)" );
            }
            catch ( InvalidVersionSpecificationException e )
            {
                // Won't happen
            }
        }

        for ( Iterator i = dependencyArtifacts.iterator(); i.hasNext(); )
        {
            Artifact a = (Artifact) i.next();

            if ( a.getArtifactId().equals( "plexus-utils" )
                 && vr.containsVersion( new DefaultArtifactVersion( a.getVersion() ) ) )
            {
                return dependencyArtifacts;
            }
        }

        // We will add plexus-utils as every plugin was getting this anyway from Maven itself. We will set the
        // version to the latest version we know that works as of the 2.0.6 release. We set the scope to runtime
        // as this is what's implicitly happening in 2.0.6.

        if ( plexusUtilsArtifact == null )
        {
            plexusUtilsArtifact = artifactFactory.createArtifact( "org.codehaus.plexus",
                                                                  "plexus-utils",
                                                                  "1.1",
                                                                  Artifact.SCOPE_RUNTIME,
                                                                  "jar" );
        }

        Set result = new LinkedHashSet( dependencyArtifacts );
        result.add( plexusUtilsArtifact );

        return result;
    }

    // This is to support the maven-enforcer-plugin.
    private List DefaultLifecycleExecutor.lifecycles;

    private pointcut lifecycleExecutorExecute( DefaultLifecycleExecutor executor ):
        execution( * DefaultLifecycleExecutor.execute( .. ) )
        && this( executor );

    before( DefaultLifecycleExecutor executor ): lifecycleExecutorExecute( executor )
    {
        PlexusContainer container = executor.container;
        DefaultLifecycleBindingManager bindingMgr;
        try
        {
            bindingMgr = (DefaultLifecycleBindingManager) container.lookup( LifecycleBindingManager.ROLE, "default" );
        }
        catch ( ComponentLookupException e )
        {
            IllegalStateException err = new IllegalStateException( "Cannot lookup default role-hint for: " + LifecycleBindingManager.ROLE );
            err.initCause( e );

            throw err;
        }

        executor.lifecycles = bindingMgr.lifecycles;
    }

}

package org.apache.maven.compat;

import org.apache.maven.lifecycle.binding.DefaultLifecycleBindingManager;
import org.apache.maven.lifecycle.binding.LifecycleBindingManager;
import org.codehaus.plexus.PlexusContainer;
import org.apache.maven.DefaultMaven;
import org.apache.maven.lifecycle.DefaultLifecycleExecutor;
import org.apache.maven.lifecycle.MojoBindingUtils;
import org.apache.maven.lifecycle.LifecycleUtils;
import org.apache.maven.lifecycle.NoSuchPhaseException;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.extension.DefaultExtensionManager;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.lifecycle.model.MojoBinding;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.DefaultPluginManager;
import org.apache.maven.plugin.InvalidPluginException;
import org.apache.maven.plugin.PluginManager;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.realm.MavenRealmManager;
import org.apache.maven.settings.MavenSettingsBuilder;
import org.apache.maven.settings.DefaultMavenSettingsBuilder;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.logging.Logger;

import java.util.List;
import java.io.IOException;
import java.util.Iterator;
import java.util.Collection;
import java.util.Set;
import java.util.LinkedHashSet;

public privileged aspect Maven20xCompatAspect
{

    // GRAB Session as soon as it's constructed.
    private MavenSession session;

    // GRAB the request when it's passed into a method that returns a corresponding result.
    // NOTE: We'll use this in multiple places below...
    private MavenExecutionRequest request;

    // Grab this so we have a voice!
    private Logger logger;

    // used for injecting plexus-utils into extension and plugin artifact sets.
    private VersionRange vr = null;
    private Artifact plexusUtilsArtifact = null;

    private pointcut mavenEmbedderStop():
        execution( * org.apache.maven.embedder.MavenEmbedder.stop( .. ) );

    // TODO: There must be a more elegant way to release these resources than depending on MavenEmbedder.stop().
    after(): mavenEmbedderStop()
    {
        session = null;
        request = null;
        logger = null;
        vr = null;
        plexusUtilsArtifact = null;
    }

    // pointcut to avoid recursive matching on behavior injected by this aspect.
    private pointcut notHere(): !within( Maven20xCompatAspect );

    private pointcut sessionCreation( MavenSession session ):
        execution( public MavenSession+.new(..) )
        && this( session )
        && notHere();

    // capture the session instance.
    after( MavenSession session ): sessionCreation( session )
    {
        if ( logger != null && logger.isDebugEnabled() )
        {
            logger.debug( "Capturing session for backward compatibility aspect: " + session );
        }

        this.session = session;
    }

    // Re-Introduce old verifyPlugin(..) API.
    public PluginDescriptor PluginManager.verifyPlugin( Plugin plugin,
                                                        MavenProject project,
                                                        Settings settings,
                                                        ArtifactRepository localRepository )
        throws ArtifactResolutionException, ArtifactNotFoundException, PluginNotFoundException,
        PluginVersionResolutionException, InvalidPluginException, PluginManagerException,
        PluginVersionNotFoundException
    {
        // this will always be diverted, so no need to do anything.
        throw new IllegalStateException( "This introduced method should ALWAYS be intercepted by backward compatibility aspect." );
    }

    // USE Session to compensate for old verifyPlugin(..) API.
    private pointcut verifyPlugin( Plugin plugin, MavenProject project, PluginManager manager ):
        execution( PluginDescriptor PluginManager+.verifyPlugin( Plugin, MavenProject, Settings, ArtifactRepository+ ) )
        && args( plugin, project, .. )
        && this( manager );

    // redirect the old verifyPlugin(..) call to the new one, using the captured session instance above.
    PluginDescriptor around( Plugin plugin,
                             MavenProject project,
                             PluginManager manager )
        throws ArtifactResolutionException, ArtifactNotFoundException, PluginNotFoundException,
        PluginVersionResolutionException, InvalidPluginException, PluginManagerException,
        PluginVersionNotFoundException:
            verifyPlugin( plugin, project, manager )
    {
        if ( logger != null && logger.isDebugEnabled() )
        {
            logger.debug( "Diverting legacy PluginManager.verifyPlugin(..) call to replacement method using session: " + session );
        }

        return manager.verifyPlugin( plugin, project, session );
    }

    private pointcut getPluginDescriptorForPrefix( String prefix, PluginManager manager ):
        execution( public PluginDescriptor PluginManager+.getPluginDescriptorForPrefix( String ) )
        && args( prefix )
        && this( manager )
        && notHere();

    PluginDescriptor around( String prefix, PluginManager manager ): getPluginDescriptorForPrefix( prefix, manager )
    {
        // TODO: Implement Me!
        throw new UnsupportedOperationException( "This method has not yet been implemented in Maven's backward-compatibility library." );
    }

    public PluginDescriptor PluginManager.getPluginDescriptorForPrefix( String prefix )
    {
        return null;
    }

    // Intercept retrieval of artifact dependencies of an extension, inject plexus-utils if it's not there.
    private pointcut extDepArtifactsResolved( DefaultExtensionManager mgr ):
        call( public Set ResolutionGroup+.getArtifacts() )
        && within( DefaultExtensionManager+ )
        && this( mgr )
        && notHere();

    // We use the same hack here to make sure that plexus 1.1 is available for extensions that do
    // not declare plexus-utils but need it. MNG-2900
    Set around( DefaultExtensionManager mgr ): extDepArtifactsResolved( mgr )
    {
        Set result = proceed( mgr );

        result = checkPlexusUtils( result, mgr.artifactFactory );

        return result;
    }

    // Intercept retrieval of artifact dependencies of a plugin, inject plexus-utils if it's not there.
    private pointcut pluginDepArtifactsResolved( DefaultPluginManager mgr ):
        call( public Set ResolutionGroup+.getArtifacts() )
        && cflow( execution( Set DefaultPluginManager+.getPluginArtifacts(..) ) )
        && this( mgr )
        && notHere();

    Set around( DefaultPluginManager mgr ): pluginDepArtifactsResolved( mgr )
    {
        Set result = proceed( mgr );

        result = checkPlexusUtils( result, mgr.artifactFactory );

        return result;
    }

    private pointcut methodsTakingRequest( MavenExecutionRequest request ):
        execution( MavenExecutionResult *.*( MavenExecutionRequest ) )
        && !withincode( * *.*( MavenExecutionRequest ) )
        && args( request )
        && notHere();

    // capture the request instance before it's passed into any method that returns a corresponding MavenExecutionResult.
    Object around( MavenExecutionRequest request ): methodsTakingRequest( request )
    {
        this.request = request;

        try
        {
            return proceed( request );
        }
        finally
        {
            this.request = null;
        }
    }

    // Re-Introduce old buildSettings() API.
    public Settings MavenSettingsBuilder.buildSettings()
        throws IOException, XmlPullParserException
    {
        return null;
    }

    public Settings DefaultMavenSettingsBuilder.buildSettings()
    throws IOException, XmlPullParserException
    {
        return null;
    }

    // USE Request to compensate for old buildSettings() API.
    private pointcut buildSettings( MavenSettingsBuilder builder ):
        execution( public Settings MavenSettingsBuilder+.buildSettings() )
        && target( builder );

    // redirect old buildSettings() call to the new one, using the request captured above.
    Settings around( MavenSettingsBuilder builder )
        throws IOException, XmlPullParserException:
            buildSettings( builder )
    {
        return builder.buildSettings( request );
    }

    private pointcut pluginManager( DefaultPluginManager manager ):
        execution( * DefaultPluginManager.*( .. ) )
        && this( manager );

    private pointcut pluginRealmCreation( Plugin plugin, DefaultPluginManager manager ):
        call( ClassRealm MavenRealmManager+.createPluginRealm( Plugin, Artifact, Collection, .. ) )
        && cflow( pluginManager( manager ) )
        && args( plugin, .. );

    // Add various imports for Xpp3 stuff back into the core realm every time a plugin realm is created.
    ClassRealm around( Plugin plugin, DefaultPluginManager manager ): pluginRealmCreation( plugin, manager )
    {
        ClassRealm pluginRealm = proceed( plugin, manager );

        try
        {
            String parentRealmId = manager.container.getContainerRealm().getId();

            // adding for MNG-3012 to try to work around problems with Xpp3Dom (from plexus-utils)
            // spawning a ClassCastException when a mojo calls plugin.getConfiguration() from maven-model...
            pluginRealm.importFrom( parentRealmId, Xpp3Dom.class.getName() );
            pluginRealm.importFrom( parentRealmId, "org.codehaus.plexus.util.xml.pull" );

            // Adding for MNG-2878, since maven-reporting-impl was removed from the
            // internal list of artifacts managed by maven, the classloader is different
            // between maven-reporting-impl and maven-reporting-api...so this resource
            // is not available from the AbstractMavenReport since it uses:
            // getClass().getResourceAsStream( "/default-report.xml" )
            // (maven-reporting-impl version 2.0; line 134; affects: checkstyle plugin, and probably others)
            pluginRealm.importFrom( parentRealmId, "/default-report.xml" );
        }
        catch ( NoSuchRealmException e )
        {
            // can't happen here. All realms are concretely resolved by now.
        }

        return pluginRealm;
    }

    before( DefaultMaven maven ):
        execution( MavenExecutionResult DefaultMaven.execute( MavenExecutionRequest ) )
        && this( maven )
    {
        if ( this.logger == null )
        {
            this.logger = maven.getLogger();
        }
    }

    private pointcut addMojoBindingCall( String phase, MojoBinding binding ):
        call( void LifecycleUtils.addMojoBinding( String, MojoBinding, .. ) )
        && args( phase, binding, .. );

    void around( String phase, MojoBinding binding ): addMojoBindingCall( phase, binding )
    {
        try
        {
            proceed( phase, binding );
        }
        catch ( NoSuchPhaseException e )
        {
            logger.debug( "Mojo execution: " + MojoBindingUtils.toString( binding )
                          + " cannot be attached to lifecycle phase: " + phase
                          + "; it does not exist. Ignoring this binding." );
        }
    }

    // --------------------------
    // UTILITIES
    // --------------------------

    private Set checkPlexusUtils( Set dependencyArtifacts, ArtifactFactory artifactFactory )
    {
        // ----------------------------------------------------------------------------
        // If the plugin already declares a dependency on plexus-utils then we're all
        // set as the plugin author is aware of its use. If we don't have a dependency
        // on plexus-utils then we must protect users from stupid plugin authors who
        // did not declare a direct dependency on plexus-utils because the version
        // Maven uses is hidden from downstream use. We will also bump up any
        // anything below 1.1 to 1.1 as this mimics the behaviour in 2.0.5 where
        // plexus-utils 1.1 was being forced into use.
        // ----------------------------------------------------------------------------

        if ( vr == null )
        {
            try
            {
                vr = VersionRange.createFromVersionSpec( "[1.1,)" );
            }
            catch ( InvalidVersionSpecificationException e )
            {
                // Won't happen
            }
        }

        for ( Iterator i = dependencyArtifacts.iterator(); i.hasNext(); )
        {
            Artifact a = (Artifact) i.next();

            if ( a.getArtifactId().equals( "plexus-utils" )
                 && vr.containsVersion( new DefaultArtifactVersion( a.getVersion() ) ) )
            {
                return dependencyArtifacts;
            }
        }

        // We will add plexus-utils as every plugin was getting this anyway from Maven itself. We will set the
        // version to the latest version we know that works as of the 2.0.6 release. We set the scope to runtime
        // as this is what's implicitly happening in 2.0.6.

        if ( plexusUtilsArtifact == null )
        {
            plexusUtilsArtifact = artifactFactory.createArtifact( "org.codehaus.plexus",
                                                                  "plexus-utils",
                                                                  "1.1",
                                                                  Artifact.SCOPE_RUNTIME,
                                                                  "jar" );
        }

        Set result = new LinkedHashSet( dependencyArtifacts );
        result.add( plexusUtilsArtifact );

        return result;
    }

    // This is to support the maven-enforcer-plugin.
    private List DefaultLifecycleExecutor.lifecycles;

    private pointcut lifecycleExecutorExecute( DefaultLifecycleExecutor executor ):
        execution( * DefaultLifecycleExecutor.execute( .. ) )
        && this( executor );

    before( DefaultLifecycleExecutor executor ): lifecycleExecutorExecute( executor )
    {
        PlexusContainer container = executor.container;
        DefaultLifecycleBindingManager bindingMgr;
        try
        {
            bindingMgr = (DefaultLifecycleBindingManager) container.lookup( LifecycleBindingManager.ROLE, "default" );
        }
        catch ( ComponentLookupException e )
        {
            IllegalStateException err = new IllegalStateException( "Cannot lookup default role-hint for: " + LifecycleBindingManager.ROLE );
            err.initCause( e );

            throw err;
        }

        executor.lifecycles = bindingMgr.lifecycles;
    }

}