Account for null contents, i.e. when the sources are not attached

/*
 * 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.BufferManager;
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);

  // For 3.6
  pointcut mapSource(ClassFile cf, SourceMapper mapper, IBinaryType info, IClassFile owner) :
    execution(IBuffer ClassFile.mapSource(SourceMapper, IBinaryType, IClassFile)) &&
    target(cf) &&
    target(IScalaClassFile) &&
    args(mapper, info, owner);

  // For 3.5
  pointcut mapSource2(ClassFile cf, SourceMapper mapper, IBinaryType info) :
    execution(IBuffer ClassFile.mapSource(SourceMapper, IBinaryType)) &&
    target(cf) &&
    target(IScalaClassFile) &&
    args(mapper, info);

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

  IBuffer around(ClassFile cf, SourceMapper mapper, IBinaryType info, IClassFile owner) :
    mapSource(cf, mapper, info, owner) {
    return mapSourceSubst(cf, mapper, info);
  }

  IBuffer around(ClassFile cf, SourceMapper mapper, IBinaryType info) :
    mapSource2(cf, mapper, info) {
    return mapSourceSubst(cf, mapper, info);
  }

  IBuffer mapSourceSubst(ClassFile cf, SourceMapper mapper, IBinaryType info) {
    char[] contents = mapper.findSource(cf.getType(), info);
    IBuffer buffer;
    if (contents != null) {
      buffer = BufferManager.createBuffer(cf);
      buffer.setContents(contents);
    } else {
      buffer = BufferManager.createNullBuffer(cf);
    }
    BufferManager bufManager = cf.getBufferManager();
    bufManager.addBuffer(buffer);
    buffer.addBufferChangedListener(cf);
    return buffer;
  }

  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.getTypeRoot();
    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.BufferManager;
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);

  // For 3.6
  pointcut mapSource(ClassFile cf, SourceMapper mapper, IBinaryType info, IClassFile owner) :
    execution(IBuffer ClassFile.mapSource(SourceMapper, IBinaryType, IClassFile)) &&
    target(cf) &&
    target(IScalaClassFile) &&
    args(mapper, info, owner);

  // For 3.5
  pointcut mapSource2(ClassFile cf, SourceMapper mapper, IBinaryType info) :
    execution(IBuffer ClassFile.mapSource(SourceMapper, IBinaryType)) &&
    target(cf) &&
    target(IScalaClassFile) &&
    args(mapper, info);

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

  IBuffer around(ClassFile cf, SourceMapper mapper, IBinaryType info, IClassFile owner) :
    mapSource(cf, mapper, info, owner) {
    return mapSourceSubst(cf, mapper, info);
  }

  IBuffer around(ClassFile cf, SourceMapper mapper, IBinaryType info) :
    mapSource2(cf, mapper, info) {
    return mapSourceSubst(cf, mapper, info);
  }

  IBuffer mapSourceSubst(ClassFile cf, SourceMapper mapper, IBinaryType info) {
    char[] contents = mapper.findSource(cf.getType(), info);
    assert(contents != null);
    IBuffer buffer = BufferManager.createBuffer(cf);
    BufferManager bufManager = cf.getBufferManager();
    bufManager.addBuffer(buffer);
    buffer.setContents(contents);
    buffer.addBufferChangedListener(cf);
    return buffer;
  }

  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.getTypeRoot();
    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;
  }
}


*around pointcuts added for lock and unlock

package benchmark.competition.java.jUnitRV_MMT.monitoring;

import java.util.concurrent.locks.Lock;

import monitoring.impl.MonitorFactory;
import monitoring.intf.Monitor;
import properties.Property;
import properties.competition.JavaRV_mmt;
import structure.impl.other.Verdict;
import structure.intf.QEA;
import benchmark.competition.java.jUnitRV_MMT.ExampleLocking;

public aspect JUnitRV_MMTThreeAspect {

	private final Monitor monitor;

	private final int RUN = 1;
	private final int LOCK_TRUE = 2;
	private final int UNLOCK = 3;
	private final int ACTION = 4;

	public JUnitRV_MMTThreeAspect() {
		QEA qea = new JavaRV_mmt().make(Property.JAVARV_MMT_THREE);
		monitor = MonitorFactory.create(qea);
	}

	pointcut run(ExampleLocking thread) : execution(void ExampleLocking.run())
		&& target(thread);

	pointcut action(ExampleLocking thread) : call(void ExampleLocking.action())
		&& target(thread);

	before(ExampleLocking thread) : run(thread) {
		Verdict verdict = null;
		synchronized (monitor) {
			verdict = monitor.step(RUN, thread);
		}
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JUnitRV (MMT) 3. [thread="
							+ thread
							+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
		}
	};

	boolean around(Lock lockObj, ExampleLocking thread) :
			call(boolean Lock.tryLock())
			&& cflow(call(boolean ExampleLocking.lock())) && target(lockObj)
			&& this(thread) {

		boolean result = false;
		synchronized (lockObj) {
			result = proceed(lockObj, thread); // TODO Not sure if this is right
		}
		if (result) {
			Verdict verdict = null;
			synchronized (monitor) {
				verdict = monitor.step(LOCK_TRUE, thread);
			}
			if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
				System.err
						.println("Violation in JUnitRV (MMT) 3. [thread="
								+ thread
								+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
			}

		}
		return result;
	};

	void around(Lock lockObj, ExampleLocking thread) :
		call(void Lock.unlock()) && cflow(call(void ExampleLocking.unlock()))
		&& target(lockObj) && this(thread) {

		synchronized (lockObj) {
			proceed(lockObj, thread); // TODO Not sure if this is right
		}
		Verdict verdict = null;
		synchronized (monitor) {
			verdict = monitor.step(LOCK_TRUE, thread);
		}
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JUnitRV (MMT) 3. [thread="
							+ thread
							+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
		}
	};

	before(ExampleLocking thread) : action(thread) {
		Verdict verdict = null;
		synchronized (monitor) {
			verdict = monitor.step(ACTION, thread);
		}
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JUnitRV (MMT) 3. [id="
							+ thread
							+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
		}
	};

}

package benchmark.competition.java.jUnitRV_MMT.monitoring;

import monitoring.impl.MonitorFactory;
import monitoring.intf.Monitor;
import properties.Property;
import properties.competition.JavaRV_mmt;
import structure.impl.other.Verdict;
import structure.intf.QEA;
import benchmark.competition.java.jUnitRV_MMT.ExampleLocking;

public aspect JUnitRV_MMTThreeAspect {

	private final Monitor monitor;

	private final int RUN = 1;
	private final int LOCK_TRUE = 2;
	private final int UNLOCK = 3;
	private final int ACTION = 4;

	public JUnitRV_MMTThreeAspect() {
		QEA qea = new JavaRV_mmt().make(Property.JAVARV_MMT_THREE);
		monitor = MonitorFactory.create(qea);
	}

	pointcut run(ExampleLocking t) : execution(void ExampleLocking.run())
		&& target(t);

	pointcut lockEvent(ExampleLocking t) : call(boolean ExampleLocking.lock())
		&& target(t);

	pointcut unlockEvent(ExampleLocking t) :
		call(void ExampleLocking.unlock()) && target(t);

	pointcut action(ExampleLocking t) : call(void ExampleLocking.action())
		&& target(t);

	before(ExampleLocking t) : run(t) {
		Verdict verdict = null;
		synchronized (monitor) {
			verdict = monitor.step(RUN, t.getId());
		}
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JUnitRV (MMT) 3. [id="
							+ t.getId()
							+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
		}
	};

	after(ExampleLocking t) returning(boolean result) : lockEvent(t) {
		if (result) {
			Verdict verdict = null;
			synchronized (monitor) {
				verdict = monitor.step(LOCK_TRUE, t.getId());
			}
			if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
				System.err
						.println("Violation in JUnitRV (MMT) 3. [id="
								+ t.getId()
								+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
			}
		}
	};

	before(ExampleLocking t) : unlockEvent(t) {
		Verdict verdict = null;
		synchronized (monitor) {
			verdict = monitor.step(UNLOCK, t.getId());
		}
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JUnitRV (MMT) 3. [id="
							+ t.getId()
							+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
		}
	};

	before(ExampleLocking t) : action(t) {
		Verdict verdict = null;
		synchronized (monitor) {
			verdict = monitor.step(ACTION, t.getId());
		}
		if (verdict == Verdict.FAILURE || verdict == Verdict.WEAK_FAILURE) {
			System.err
					.println("Violation in JUnitRV (MMT) 3. [id="
							+ t.getId()
							+ "]. - A thread has to call lock (returning true) to acquire the lock before it may call action - A call to lock only returns true, if no thread is currently holding the lock.");
		}
	};

}


Update Tracer.aj

Update Tracer.aj

import java.lang.reflect.Method;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.lang.String;

import org.aspectj.lang.reflect.MethodSignature;

public aspect Tracer {
	static boolean running;
	public static String sequence = "";

	ArrayList<String> caller = new ArrayList<String>();
	int count = 0;
	String counter = "";

		pointcut traceMethods()
		: 	(execution(* *.*(..)))
		&& if(running)
		;

	before(): traceMethods(){
		caller.add(0, "Actor");

		if(
				(thisJoinPoint.getThis()!=null)
				&&
				(thisJoinPointStaticPart.getKind()=="method-execution")
				&& (thisJoinPoint.getTarget()!=null)

				){

			String method = thisJoinPointStaticPart.getSignature().toString();
			MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
			Method method1 = signature.getMethod();

			boolean first = true;
			String paramTypes = new String();

			for(Parameter p : method1.getParameters()){

				if(!first){
					paramTypes += "," + p.getType().getSimpleName();
				}
				else{
					paramTypes += p.getType().getSimpleName();
					first = false;
				}
			}

			String returnString = "";

			if((method1.getReturnType() != null)
					&&
					(method1.getReturnType()!=void.class)){
				returnString = thisJoinPoint.getTarget().getClass().getSimpleName()
						+ "-->"
						+ caller.get(caller.size()-1);
			}

			if(!returnString.contains("-->")){
				returnString= "";

			}

			String returnType = method.subSequence(0, method.indexOf(" ")).toString();
			count++;
			sequence += "\n"+caller.get(caller.size()-1)
			+ " ->"
			+ thisJoinPoint.getTarget().getClass().getSimpleName()
			+ ":"
			+ count+".  "
			+ thisJoinPointStaticPart.getSignature().getName()
			+ "("+paramTypes+"):"
			+ returnType
			+ "\nactivate " + thisJoinPoint.getTarget().getClass().getSimpleName()
			+"\n" + returnString
			;

			caller.add(caller.size(), thisJoinPoint.getTarget().getClass().getSimpleName() );
		}
	}

	after(): traceMethods(){
		if(
				(thisJoinPoint.getThis()!=null)
				&&
				(thisJoinPointStaticPart.getKind()=="method-execution")
				&& (thisJoinPoint.getTarget()!=null)
				){		sequence += "\ndeactivate " + caller.get(caller.size()-1) + "\n";

				caller.remove(caller.size()-1);
		}
	}

	public static String getSequence() {

		return sequence;
	}
}

import java.lang.reflect.Method;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.lang.String;

import org.aspectj.lang.reflect.MethodSignature;

public aspect Tracer {
	static boolean running;
	public static String sequence = "";

	ArrayList<String> caller = new ArrayList<String>();
	int count = 0;
	String counter = "";

		pointcut traceMethods()
		: 	(execution(* *.*(..)))
		&& if(running)
		;

	before(): traceMethods(){
		caller.add(0, "InitialActor");

		if(
				(thisJoinPoint.getThis()!=null)
				&&
				(thisJoinPointStaticPart.getKind()=="method-execution")
				&& (thisJoinPoint.getTarget()!=null)

				){

			String method = thisJoinPointStaticPart.getSignature().toString();
			MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
			Method method1 = signature.getMethod();

			boolean first = true;
			String paramTypes = new String();

			for(Parameter p : method1.getParameters()){

				if(!first){
					paramTypes += "," + p.getType().getSimpleName();
				}
				else{
					paramTypes += p.getType().getSimpleName();
					first = false;
				}
			}

			String returnString = "";

			if((method1.getReturnType() != null)
					&&
					(method1.getReturnType()!=void.class)){
				returnString = thisJoinPoint.getTarget().getClass().getSimpleName()
						+ "-->"
						+ caller.get(caller.size()-1);
			}

			if(!returnString.contains("-->")){
				returnString= "";

			}

			String returnType = method.subSequence(0, method.indexOf(" ")).toString();
			count++;
			sequence += "\n"+caller.get(caller.size()-1)
			+ " ->"
			+ thisJoinPoint.getTarget().getClass().getSimpleName()
			+ ":"
			+ count+".  "
			+ thisJoinPointStaticPart.getSignature().getName()
			+ "("+paramTypes+"):"
			+ returnType
			+"\n" + returnString
			+ "\nactivate " + thisJoinPoint.getTarget().getClass().getSimpleName()
			;
			caller.add(caller.size(), thisJoinPoint.getTarget().getClass().getSimpleName() );

//			for(int i : count){
//				counter += i;
//			}
//			System.out.println(counter);

			System.out.println(sequence);
		}
	}

	after(): traceMethods(){
		if(
				(thisJoinPoint.getThis()!=null)
				&&
				(thisJoinPointStaticPart.getKind()=="method-execution")
				&& (thisJoinPoint.getTarget()!=null)
				){		sequence += "\ndeactivate " + caller.get(caller.size()-1) + "\n";

				caller.remove(caller.size()-1);
//				count.remove(count.size()-1);

				System.out.println(sequence);
		}
	}

	public static String getSequence() {

		return sequence;
	}

}


This code should not be commented as it needed for backward compatibility...

git-svn-id: cfa2b40e478804c47c05d0f328c574ec5aa2b82e@9683 f329d543-caf0-0310-9063-dda96c69346f

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 */
package com.xpn.xwiki.stats.impl;

import java.util.Date;

/**
 * Add a backward compatibility layer to the {@link StatsUtil} class.
 *
 * @version $Id: $
 */
public privileged aspect StatsUtilCompatibilityAspect
{
    /**
     * @deprecated Use {@link PeriodType} since 1.4M1.
     */
    @Deprecated
    public static int StatsUtil.PERIOD_MONTH = 0;

    /**
     * @deprecated Use {@link PeriodType} since 1.4M1.
     */
    @Deprecated
    public static int StatsUtil.PERIOD_DAY = 1;

    /**
     * Computes an integer representation of the passed date using the following format:
     *

     *
"yyyMMdd" for {@link PERIOD_DAY}

     *
"yyyMM" for {@link PERIOD_MONTH}

     *

     *
     * @param date the date for which to return an integer representation
     * @param type the date type. It can be {@link PERIOD_DAY} or {@link PERIOD_MONTH}
     * @return the integer representation of the specified date
     * @see java.text.SimpleDateFormat
     * @deprecated Use
     *             {@link StatsUtil#getPeriodAsInt(Date, com.xpn.xwiki.stats.impl.StatsUtil.PeriodType)}
     *             since 1.4M1.
     */
    @Deprecated
    public static int StatsUtil.getPeriodAsInt(Date date, int type)
    {
        return StatsUtil.getPeriodAsInt(date, PeriodType.values()[type]);
    }
}

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 */
package com.xpn.xwiki.stats.impl;

import java.util.Date;

/**
 * Add a backward compatibility layer to the {@link StatsUtil} class.
 *
 * @version $Id: $
 */
public privileged aspect StatsUtilCompatibilityAspect
{
    /**
     * @deprecated Use {@link PeriodType} since 1.4M1.
     */
    //@Deprecated
    //public static int StatsUtil.PERIOD_MONTH = 0;

    /**
     * @deprecated Use {@link PeriodType} since 1.4M1.
     */
    //@Deprecated
    //public static int StatsUtil.PERIOD_DAY = 1;

    /**
     * Computes an integer representation of the passed date using the following format:
     *

     *
"yyyMMdd" for {@link PERIOD_DAY}

     *
"yyyMM" for {@link PERIOD_MONTH}

     *

     *
     * @param date the date for which to return an integer representation
     * @param type the date type. It can be {@link PERIOD_DAY} or {@link PERIOD_MONTH}
     * @return the integer representation of the specified date
     * @see java.text.SimpleDateFormat
     * @deprecated Use
     *             {@link StatsUtil#getPeriodAsInt(Date, com.xpn.xwiki.stats.impl.StatsUtil.PeriodType)}
     *             since 1.4M1.
     */
    //@Deprecated
    /*public static int StatsUtil.getPeriodAsInt(Date date, int type)
    {
        return StatsUtil.getPeriodAsInt(date, PeriodType.values()[type]);
    }*/
}


@Entity no longer required with spring-aspect

This commits complements 222d2b1 for another required dependency.

javax.persistence.Entity was previously required, regardless of which
aspects were actually used by the project. It is now optional and will
not break the build if it is not present. Note that the side effect is that
AnnotationDrivenStaticEntityMockingControl is disabled as well if the
JPA API is not available.

Issue: SPR-6819

/*
 * 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;

import org.aspectj.lang.annotation.RequiredTypes;

/**
 * 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.
 *

 *
 *
Programmatic Control of the Mock

 *
For scenarios where it would be convenient to programmatically verify
 * the recorded expectations or reset the state of the mock, consider
 * using combinations of {@link #verify()} and {@link #reset()}.
 *
 * @author Rod Johnson
 * @author Ramnivas Laddad
 * @author Sam Brannen
 * @see MockStaticEntityMethods
 */
@RequiredTypes("javax.persistence.Entity")
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();
	}

	/**
	 * Verify that all expectations have been fulfilled.
	 * @since 4.0.2
	 * @see #reset()
	 */
	public static void verify() {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().verifyInternal();
	}

	/**
	 * Reset the state of the mock and enter recording mode.
	 * @since 4.0.2
	 * @see #verify()
	 */
	public static void reset() {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().resetInternal();
	}

	// 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 creating a
	// new 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 {@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.
 *

 *
 *
Programmatic Control of the Mock

 *
For scenarios where it would be convenient to programmatically verify
 * the recorded expectations or reset the state of the mock, consider
 * using combinations of {@link #verify()} and {@link #reset()}.
 *
 * @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();
	}

	/**
	 * Verify that all expectations have been fulfilled.
	 * @since 4.0.2
	 * @see #reset()
	 */
	public static void verify() {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().verifyInternal();
	}

	/**
	 * Reset the state of the mock and enter recording mode.
	 * @since 4.0.2
	 * @see #verify()
	 */
	public static void reset() {
		AnnotationDrivenStaticEntityMockingControl.aspectOf().resetInternal();
	}

	// 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 creating a
	// new 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 *).*(..));

}


Added headline to statistics export

Added headline to statistics export

import java.io.IOException;

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 view.GUI;

public privileged aspect StatisticsExport {

    declare precedence: StatisticsExport, GraphExport, 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;
    }

    /**
     * Catch the call on {@link PDFReportListener.drawTable(PDDocument)} to get the pdf
     * creator object.
     *
     * @param document
     * @throws IOException
     */
    after(PDDocument document) returning() throws IOException
    : call(* PDFReportListener.drawTable(PDDocument))
    && args(document) {
        PDPage page = new PDPage();
        document.addPage(page);
        PDPageContentStream contentStream = new PDPageContentStream(document,
                page);

        contentStream.beginText();
        contentStream.setFont(PDType1Font.HELVETICA_BOLD, 15);
        contentStream.moveTextPositionByAmount(100, 680);
        contentStream.drawString("Statistik ueber das gesamte Spiel");
        contentStream.endText();

        contentStream.beginText();
        contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10);
        createOverallContent(contentStream);
        contentStream.endText();
        contentStream.close();
    }

	/**
	 * Write statistics to given contentStream of a pdf page.
	 *
	 * @param contentStream The contentStream of the pdf page to write on.
	 * @throws IOException
	 */
	private void createOverallContent(PDPageContentStream contentStream) throws IOException {
		OverallStatistics data = gui.model.gameDB.getOverallStatistics();

        contentStream.moveTextPositionByAmount(50, 650);
        contentStream.drawString("#Spiele (ohne weiter): " + data.getAnzahlSpieleGesamt()
        		+ " (gewonnen: "
        		+ String.format("%.2f", data.getGesamtWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(0, -16);
        contentStream.drawString("#Rufspiele: " + data.getAnzahlRufspiele() + " (gewonnen: "
        		+ String.format("%.2f", data.getRufspieleWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(50, -16);
        contentStream.drawString("-> teuerstes Rufspiel: "
        + data.getTeuerstesRufspiel());

        contentStream.moveTextPositionByAmount(-50, -16);
        contentStream.drawString("#Soli gesamt: "
        		+ data.getAnzahlSoliGesamt() + " (gewonnen: "
        		+ String.format("%.2f", data.getSoliGesamtWinPerc())
        		+ "%)");

        contentStream.moveTextPositionByAmount(0, -16);
        contentStream.drawString("#Soli normal: " + data.getAnzahlSoli()
        		+ " (gewonnen: "
        		+ String.format("%.2f", data.getSoliNormalWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(50, -16);
        contentStream.drawString("-> teuerstes Solo: " + data.getTeuerstesSolo());

        contentStream.moveTextPositionByAmount(-50, -16);
        contentStream.drawString("#Solo Tout: " + data.getAnzahlSoliTout()
        		+ " (gewonnen: "
        		+ String.format("%.2f", data.getSoliToutWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(50, -16);
        contentStream.drawString("-> teuerstes Solo Tout: "
        		+ data.getTeuerstesSoloTout());

        contentStream.moveTextPositionByAmount(-50, -16);
        contentStream.drawString("#Solo Sie: " + data.getAnzahlSoliSie());

        contentStream.moveTextPositionByAmount(50, -16);
        contentStream.drawString("-> teuerstes Solo Sie: " + data.getTeuerstesSoloSie());

        contentStream.moveTextPositionByAmount(-50, -16);
        contentStream.drawString("#Weiter: " + data.getAnzahlWeiter());
	}
}

import java.io.IOException;

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 view.GUI;

public privileged aspect StatisticsExport {

    declare precedence: StatisticsExport, GraphExport, 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;
    }

    /**
     * Catch the call on {@link PDFReportListener.drawTable(PDDocument)} to get the pdf
     * creator object.
     *
     * @param document
     * @throws IOException
     */
    after(PDDocument document) returning() throws IOException
    : call(* PDFReportListener.drawTable(PDDocument))
    && args(document) {
        PDPage page = new PDPage();
        document.addPage(page);
        PDPageContentStream contentStream = new PDPageContentStream(document,
                page);
        contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10);
        contentStream.beginText();
        createContent(contentStream);
        contentStream.endText();
        contentStream.close();
    }

	/**
	 * Write statistics to given contentStream of a pdf page.
	 *
	 * @param contentStream The contentStream of the pdf page to write on.
	 * @throws IOException
	 */
	private void createContent(PDPageContentStream contentStream) throws IOException {
		OverallStatistics data = gui.model.gameDB.getOverallStatistics();

        contentStream.moveTextPositionByAmount(50, 650);
        contentStream.drawString("#Spiele (ohne weiter): " + data.getAnzahlSpieleGesamt()
        		+ " (gewonnen: "
        		+ String.format("%.2f", data.getGesamtWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(0, -20);
        contentStream.drawString("#Rufspiele: " + data.getAnzahlRufspiele() + " (gewonnen: "
        		+ String.format("%.2f", data.getRufspieleWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(50, -20);
        contentStream.drawString("-> teurstes Rufspiel: "
        + data.getTeuerstesRufspiel());

        contentStream.moveTextPositionByAmount(-50, -20);
        contentStream.drawString("#Soli gesamt: "
        		+ data.getAnzahlSoliGesamt() + " (gewonnen: "
        		+ String.format("%.2f", data.getSoliGesamtWinPerc())
        		+ "%)");

        contentStream.moveTextPositionByAmount(0, -20);
        contentStream.drawString("#Soli normal: " + data.getAnzahlSoli()
        		+ " (gewonnen: "
        		+ String.format("%.2f", data.getSoliNormalWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(50, -20);
        contentStream.drawString("-> teurstes Solo: " + data.getTeuerstesSolo());

        contentStream.moveTextPositionByAmount(-50, -20);
        contentStream.drawString("#Solo Tout: " + data.getAnzahlSoliTout()
        		+ " (gewonnen: "
        		+ String.format("%.2f", data.getSoliToutWinPerc()) + "%)");

        contentStream.moveTextPositionByAmount(50, -20);
        contentStream.drawString("-> teurstes Solo Tout: "
        		+ data.getTeuerstesSoloTout());

        contentStream.moveTextPositionByAmount(-50, -20);
        contentStream.drawString("#Solo Sie: " + data.getAnzahlSoliSie());

        contentStream.moveTextPositionByAmount(50, -20);
        contentStream.drawString("-> teurstes Solo Sie: " + data.getTeuerstesSoloSie());

        contentStream.moveTextPositionByAmount(-50, -20);
        contentStream.drawString("#Weiter: " + data.getAnzahlWeiter());
	}
}


Throw a more useful exception if the ThreadConfigurableBeanFactory singleton instance has been set to null when we try to use it.

/*
 * Copyright (C) 2011 Archie L. Cobbs and other authors. All rights reserved.
 *
 * $Id: ThreadConfigurableAspect.aj 282 2012-02-16 20:48:06Z archie.cobbs $
 */

package org.dellroad.stuff.spring;

import java.io.ObjectStreamException;
import java.io.Serializable;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect;
import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;

/**
 * Aspect that autowires classes marked with the {@link ThreadConfigurable @ThreadConfigurable} annotation using
 * the Spring application context returned by {@link ThreadConfigurableBeanFactory#get()}.
 *
 * <p>
 * This implementation is derived from Spring's {@code AnnotationBeanConfigurerAspect} implementation
 * and therefore shares its license (also Apache).
 * </p>
 *
 * @see ThreadConfigurableBeanFactory
 * @see ThreadConfigurable
 */
public aspect ThreadConfigurableAspect extends AbstractConfigurableAspect {

// Stuff copied from AbstractInterfaceDrivenDependencyInjectionAspect.aj

    public pointcut beanConstruction(Object bean) :
        initialization(ThreadConfigurableObject+.new(..)) && this(bean);

    public pointcut beanDeserialization(Object bean) :
        execution(Object ThreadConfigurableDeserializationSupport+.readResolve()) &&
        this(bean);

    public pointcut leastSpecificSuperTypeConstruction() : initialization(ThreadConfigurableObject.new(..));

    declare parents:
        ThreadConfigurableObject+ && Serializable+ implements ThreadConfigurableDeserializationSupport;

    static interface ThreadConfigurableDeserializationSupport extends Serializable {
    }

    public Object ThreadConfigurableDeserializationSupport.readResolve() throws ObjectStreamException {
        return this;
    }

// Stuff copied from AnnotationBeanConfigurerAspect.aj

    public pointcut inConfigurableBean() : @this(ThreadConfigurable);

    public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);

    declare parents: @ThreadConfigurable * implements ThreadConfigurableObject;

    private pointcut preConstructionConfigurationSupport(ThreadConfigurable c) : @this(c) && if(c.preConstruction());

	declare parents: @ThreadConfigurable Serializable+ implements ThreadConfigurableDeserializationSupport;

// Our implementation

    @Override
    protected BeanFactory getBeanFactory(Object bean) {
        ThreadConfigurableBeanFactory threadConfigurableBeanFactory = ThreadConfigurableBeanFactory.getInstance();
        if (threadConfigurableBeanFactory == null) {
            throw new IllegalStateException("can't configure @" + ThreadConfigurable.class.getName()
              + "-annotated bean of type " + bean.getClass().getName()
              + " because the ThreadConfigurableBeanFactory singleton instance has been set to null");
        }
        BeanFactory beanFactory = threadConfigurableBeanFactory.get();
        if (beanFactory == null) {
            throw new IllegalStateException("can't configure @" + ThreadConfigurable.class.getName()
              + "-annotated bean of type " + bean.getClass().getName()
              + " because no BeanFactory has been configured for the current thread via "
              + ThreadConfigurableBeanFactory.class.getName() + ".set()");
        }
        return beanFactory;
    }

    @Override
    protected BeanWiringInfoResolver getBeanWiringInfoResolver(Object bean) {
        return new ThreadConfigurableBeanWiringInfoResolver();
    }
}

/*
 * Copyright (C) 2011 Archie L. Cobbs and other authors. All rights reserved.
 *
 * $Id: ThreadConfigurableAspect.aj 282 2012-02-16 20:48:06Z archie.cobbs $
 */

package org.dellroad.stuff.spring;

import java.io.ObjectStreamException;
import java.io.Serializable;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect;
import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
import org.springframework.beans.factory.wiring.BeanWiringInfoResolver;

/**
 * Aspect that autowires classes marked with the {@link ThreadConfigurable @ThreadConfigurable} annotation using
 * the Spring application context returned by {@link ThreadConfigurableBeanFactory#get()}.
 *
 * <p>
 * This implementation is derived from Spring's {@code AnnotationBeanConfigurerAspect} implementation
 * and therefore shares its license (also Apache).
 * </p>
 *
 * @see ThreadConfigurableBeanFactory
 * @see ThreadConfigurable
 */
public aspect ThreadConfigurableAspect extends AbstractConfigurableAspect {

// Stuff copied from AbstractInterfaceDrivenDependencyInjectionAspect.aj

    public pointcut beanConstruction(Object bean) :
        initialization(ThreadConfigurableObject+.new(..)) && this(bean);

    public pointcut beanDeserialization(Object bean) :
        execution(Object ThreadConfigurableDeserializationSupport+.readResolve()) &&
        this(bean);

    public pointcut leastSpecificSuperTypeConstruction() : initialization(ThreadConfigurableObject.new(..));

    declare parents:
        ThreadConfigurableObject+ && Serializable+ implements ThreadConfigurableDeserializationSupport;

    static interface ThreadConfigurableDeserializationSupport extends Serializable {
    }

    public Object ThreadConfigurableDeserializationSupport.readResolve() throws ObjectStreamException {
        return this;
    }

// Stuff copied from AnnotationBeanConfigurerAspect.aj

    public pointcut inConfigurableBean() : @this(ThreadConfigurable);

    public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);

    declare parents: @ThreadConfigurable * implements ThreadConfigurableObject;

    private pointcut preConstructionConfigurationSupport(ThreadConfigurable c) : @this(c) && if(c.preConstruction());

	declare parents: @ThreadConfigurable Serializable+ implements ThreadConfigurableDeserializationSupport;

// Our implementation

    @Override
    protected BeanFactory getBeanFactory(Object bean) {
        BeanFactory beanFactory = ThreadConfigurableBeanFactory.getInstance().get();
        if (beanFactory == null) {
            throw new IllegalStateException("can't configure @" + ThreadConfigurable.class.getName()
              + "-annotated bean of type " + bean.getClass().getName()
              + " because no BeanFactory has been configured for the current thread via "
              + ThreadConfigurableBeanFactory.class.getName() + ".set()");
        }
        return beanFactory;
    }

    @Override
    protected BeanWiringInfoResolver getBeanWiringInfoResolver(Object bean) {
        return new ThreadConfigurableBeanWiringInfoResolver();
    }
}


Suppress incorrect AJ warnings (AJDT does not recognize joinpoints in dependency bundles)

git-svn-id: 7acc490bd371dbc82047a939b87dc892fdc31f59@22174 76a6fc44-f60b-0410-a9a8-e67b0e8fc65c

package org.lamport.tla.toolbox.test.threading;

import org.aspectj.lang.annotation.SuppressAjWarnings;

/**
 * The purpose of this advice is to intercept method execution in the backend
 * code - namely all code in the packages tlc2, tla2sany, tla2tex, pcal and util.
 *
 * It notifies the {@link MonitorAdaptor} about the method execution.
 */
public aspect MonitorAspect {

	public MonitorAspect() {
		MonitorAdaptor.setAspect(this);
	}

	// known places where backend call within UI thread are acceptable
	pointcut inFilter() :
		withincode(public boolean org.lamport.tla.toolbox.util.ResourceHelper.isValidSpecName(String));

	// catch all method calls (static and object ones)
	pointcut callToBackend() :
		   execution(* tlc2..*.*(..))
		|| execution(* tla2sany..*.*(..))
		|| execution(* tla2tex..*.*(..))
		|| execution(* pcal..*.*(..))
		|| execution(* util..*.*(..));

	// capture calls to backend, but not within ourself or in filter
	@SuppressAjWarnings
	before(): (callToBackend()
			&& !cflowbelow(callToBackend()) && !cflowbelow(inFilter())) {
		MonitorAdaptor.enter(thisJoinPoint);
	}
}

package org.lamport.tla.toolbox.test.threading;

/**
 * The purpose of this advice is to intercept method execution in the backend
 * code - namely all code in the packages tlc2, tla2sany, tla2tex, pcal and util.
 *
 * It notifies the {@link MonitorAdaptor} about the method execution.
 */
public aspect MonitorAspect {

	public MonitorAspect() {
		MonitorAdaptor.setAspect(this);
	}

	// known places where backend call within UI thread are acceptable
	pointcut inFilter() :
		withincode(public boolean org.lamport.tla.toolbox.util.ResourceHelper.isValidSpecName(String));

	// catch all method calls (static and object ones)
	pointcut callToBackend() :
		   execution(* tlc2..*.*(..))
		|| execution(* tla2sany..*.*(..))
		|| execution(* tla2tex..*.*(..))
		|| execution(* pcal..*.*(..))
		|| execution(* util..*.*(..));

	// capture calls to backend, but not within ourself or in filter
	before(): (callToBackend()
			&& !cflowbelow(callToBackend()) && !cflowbelow(inFilter())) {
		MonitorAdaptor.enter(thisJoinPoint);
	}
}


added marked rollback only behaviour

added marked rollback only behaviour

/**
 * palava - a java-php-bridge
 * Copyright (C) 2007-2010  CosmoCode GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */

package de.cosmocode.palava.jta;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

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;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

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

    private Provider<UserTransaction> provider;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);

        final boolean local;

        try {
            local = tx.getStatus() == Status.STATUS_NO_TRANSACTION;
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (local) {
            LOG.trace("Beginning automatic transaction");
            try {
                tx.begin();
            } catch (NotSupportedException e) {
                throw new IllegalStateException(e);
            } catch (SystemException e) {
                throw new IllegalStateException(e);
            }
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (Exception e) {
            LOG.error("Exception inside automatic transaction context", e);
            try {
                if (local && tx.getStatus() == Status.STATUS_ACTIVE) {
                    tx.rollback();
                } else {
                    tx.setRollbackOnly();
                }
            } catch (SystemException inner) {
                throw new IllegalStateException(inner);
            }
            throw new IllegalStateException(e);
        }

        final int status;

        try {
            status = tx.getStatus();
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (local) {
            if (status == Status.STATUS_MARKED_ROLLBACK) {
                try {
                    tx.rollback();
                } catch (SystemException e) {
                    throw new IllegalStateException(e);
                }
            } else {
                try {
                    tx.commit();
                    LOG.trace("Committed automatic transaction");
                } catch (Exception e) {
                    LOG.error("Commit in automatic transaction context failed", e);
                    try {
                        tx.rollback();
                    } catch (SystemException inner) {
                        throw new IllegalStateException(inner);
                    }
                    throw new IllegalStateException(e);
                }
            }
        }

        return returnValue;
    }

}

/**
 * palava - a java-php-bridge
 * Copyright (C) 2007-2010  CosmoCode GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 */

package de.cosmocode.palava.jta;

import javax.transaction.NotSupportedException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

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;

public abstract aspect AbstractUserTransactionAspect extends AbstractPalavaAspect issingleton() {

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

    private Provider<UserTransaction> provider;

    @Inject
    void setProvider(Provider<UserTransaction> provider) {
        this.provider = Preconditions.checkNotNull(provider, "Provider");
    }

    protected abstract pointcut transactional();

    @SuppressAjWarnings("adviceDidNotMatch")
    Object around(): transactional() {
        final UserTransaction tx = provider.get();
        LOG.trace("Using transaction {}", tx);

        final boolean localTx;

        try {
            localTx = tx.getStatus() == Status.STATUS_NO_TRANSACTION;
        } catch (SystemException e) {
            throw new IllegalStateException(e);
        }

        if (localTx) {
            LOG.trace("Beginning automatic transaction");
            try {
                tx.begin();
            } catch (NotSupportedException e) {
                throw new IllegalStateException(e);
            } catch (SystemException e) {
                throw new IllegalStateException(e);
            }
        } else {
            LOG.trace("Transaction already active");
        }

        final Object returnValue;

        try {
            returnValue = proceed();
        } catch (Exception e) {
            LOG.error("Exception inside automatic transaction context", e);
            try {
                tx.rollback();
            } catch (SystemException inner) {
                throw new IllegalStateException(inner);
            }
            throw new IllegalStateException(e);
        }

        try {
            if (localTx && tx.getStatus() == Status.STATUS_ACTIVE) {
                tx.commit();
                LOG.trace("Committed automatic transaction");
            }
            return returnValue;
        } catch (Exception e) {
            LOG.error("Commit in automatic transaction context failed", e);
            try {
                tx.rollback();
            } catch (SystemException inner) {
                throw new IllegalStateException(inner);
            }
            throw new IllegalStateException(e);
        }
    }

}