blob: 83491d7a91718a175868a4905eca05296e41b1e4 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 BEA Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* tyeung@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.apt.tests;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.apt.core.internal.AptPlugin;
import org.eclipse.jdt.apt.core.util.AptConfig;
import org.eclipse.jdt.apt.tests.annotations.BaseProcessor;
import org.eclipse.jdt.apt.tests.annotations.ProcessorTestStatus;
import org.eclipse.jdt.apt.tests.annotations.generic.GenericFactory;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.tests.builder.BuilderTests;
import org.eclipse.jdt.core.tests.builder.Problem;
import org.eclipse.jdt.core.tests.util.Util;
import com.sun.mirror.apt.AnnotationProcessor;
/**
* Setup a project for common APT testing.
*/
public abstract class APTTestBase extends BuilderTests{
public APTTestBase(final String name)
{
super(name);
}
/**
* Set up a basic project with the following properties.
* - java compliances level is 1.5
* - 'src' is the source folder
* - 'bin' is the output folder
* - add java class library into teh build class path
* - create and add an annotation jar.
*/
public void setUp() throws Exception
{
runFinalizers();
ProcessorTestStatus.reset();
super.setUp();
env.resetWorkspace();
TestUtil.enableAutoBuild(false);
// project will be deleted by super-class's tearDown() method
final String projectName = getProjectName();
if( projectName == null )
throw new IllegalStateException();
IJavaProject jproj = createJavaProject(projectName);
AptConfig.setEnabled(jproj, true);
}
/**
* Create a java project with java libraries and test annotations on classpath
* (compiler level is 1.5). Use "src" as source folder and "bin" as output folder.
* APT is not enabled.
*
* @param projectName
* @return a java project that has been added to the current workspace.
* @throws Exception
*/
protected IJavaProject createJavaProject(final String projectName )
throws Exception
{
IPath projectPath = env.addProject( projectName, "1.5" );
env.addExternalJars( projectPath, Util.getJavaClassLibs() );
// remove old package fragment root so that names don't collide
env.removePackageFragmentRoot( projectPath, "" ); //$NON-NLS-1$
env.addPackageFragmentRoot( projectPath, "src" ); //$NON-NLS-1$
env.setOutputFolder( projectPath, "bin" ); //$NON-NLS-1$
final IJavaProject javaProj = env.getJavaProject( projectPath );
TestUtil.createAndAddAnnotationJar( javaProj );
return javaProj;
}
protected void tearDown()
throws Exception
{
AptPlugin.trace("Tearing down " + getProjectName() );
runFinalizers();
GenericFactory.PROCESSOR = null;
super.tearDown();
}
private static void runFinalizers() {
// GC in an attempt to release file lock on Classes.jar
System.gc();
System.runFinalization();
System.gc();
System.runFinalization();
}
public String getProjectName()
{
return this.getClass().getName() + "Project"; //$NON-NLS-1$
}
public IPath getSourcePath()
{
IProject project = env.getProject( getProjectName() );
IFolder srcFolder = project.getFolder( "src" ); //$NON-NLS-1$
IPath srcRoot = srcFolder.getFullPath();
return srcRoot;
}
private String concate(String[] messages){
final int len = messages == null ? 0 : messages.length;
StringBuilder buffer = new StringBuilder();
for(int i=0; i<len; i++ ){
buffer.append(messages[i]);
buffer.append('\n');
}
return buffer.toString();
}
private String concate(IMarker[] markers){
final int len = markers == null ? 0 : markers.length;
StringBuilder buffer = new StringBuilder();
for(int i=0; i<len; i++ ){
try{
buffer.append(markers[i].getAttribute(IMarker.MESSAGE));
}
catch(CoreException ce){
assertTrue("unexpected core exception" + ce.getMessage(), false); //$NON-NLS-1$
}
buffer.append('\n');
}
return buffer.toString();
}
protected void clearProcessorResult(Class<? extends AnnotationProcessor> processor) {
String propertyName = BaseProcessor.getPropertyName(processor);
System.clearProperty(propertyName);
}
/*
* Processors can set a result message with BaseProcessor.reportError() or reportSuccess().
* This method will cause the test to fail if the processor reported an error. The result
* value will be cleared regardless of success or failure.
*/
protected String checkProcessorResult(Class<? extends AnnotationProcessor> processor) {
String propertyName = BaseProcessor.getPropertyName(processor);
String result = System.getProperty(propertyName);
System.clearProperty(propertyName);
if (!BaseProcessor.SUCCESS.equals(result)) {
fail(result);
}
return result;
}
/*
* Processors can set a result message with BaseProcessor.reportError() or reportSuccess().
* This method returns the message reported by the processor, and clears the result value.
*/
protected String getProcessorResult(Class<? extends AnnotationProcessor> processor) {
String propertyName = BaseProcessor.getPropertyName(processor);
String result = System.getProperty(propertyName);
System.clearProperty(propertyName);
return result;
}
protected void expectingMarkers(String[] messages)
{
final IMarker[] markers = getAllAPTMarkers(env.getWorkspaceRootPath());
final Set<String> expectedMessages = new HashSet<String>();
for(String msg : messages ){
expectedMessages.add(msg);
}
boolean fail = false;
try{
for( IMarker marker : markers ){
final String markerMsg = (String)marker.getAttribute(IMarker.MESSAGE);
if( expectedMessages.contains(markerMsg) )
expectedMessages.remove(markerMsg);
else{
fail = true;
break;
}
}
if( !expectedMessages.isEmpty() )
fail = true;
}catch(CoreException ce){
assertTrue("unexpected core exception" + ce.getMessage(), false); //$NON-NLS-1$
}
if( fail )
assertEquals(concate(messages), concate(markers));
}
protected void expectingNoMarkers() {
expectingNoMarkers(env.getWorkspaceRootPath());
}
protected void expectingNoMarkers(IPath path)
{
final IMarker[] markers = getAllAPTMarkers(path);
if( markers != null && markers.length != 0 ){
try{
assertTrue("unexpected marker(s) : " + markers[0].getAttribute(IMarker.MESSAGE), false); //$NON-NLS-1$
}
catch(CoreException ce){
assertTrue("unexpected core exception" + ce.getMessage(), false); //$NON-NLS-1$
}
}
}
@SuppressWarnings("unchecked")
protected IMarker[] getAllAPTMarkers(IPath path){
IResource resource;
if(path.equals(env.getWorkspaceRootPath())){
resource = env.getWorkspace().getRoot();
} else {
IProject p = env.getProject(path);
if(p != null && path.equals(p.getFullPath())) {
resource = env.getProject(path.lastSegment());
} else if(path.getFileExtension() == null) {
resource = env.getWorkspace().getRoot().getFolder(path);
} else {
resource = env.getWorkspace().getRoot().getFile(path);
}
}
try {
IMarker[] markers = null;
int total = 0;
final IMarker[] processorMarkers = resource.findMarkers(AptPlugin.APT_BATCH_PROCESSOR_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
total = processorMarkers.length;
markers = processorMarkers;
final IMarker[] factoryPathMarkers = resource.findMarkers(AptPlugin.APT_LOADER_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
if( factoryPathMarkers.length != 0 ){
if( total != 0 ){
final int len = factoryPathMarkers.length;
final IMarker[] temp = new IMarker[len + total ];
System.arraycopy(markers, 0, temp, 0, total);
System.arraycopy(factoryPathMarkers, 0, temp, total, len);
markers = temp;
total += len;
}
else
markers = factoryPathMarkers;
}
final IMarker[] configMarkers = resource.findMarkers(AptPlugin.APT_CONFIG_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
if( configMarkers.length != 0 ){
if( total != 0 ){
final int len = configMarkers.length;
final IMarker[] temp = new IMarker[len + total];
System.arraycopy(markers, 0, temp, 0, total);
System.arraycopy(configMarkers, 0, temp, total, len);
markers = temp;
total += len;
}
else
markers = configMarkers;
}
return markers;
} catch(CoreException e){
return null;
}
}
/**
* Verifies that the given element has specifics problems and
* only the given problems.
* @see Tests#expectingOnlySpecificProblemsFor(IPath, Problem[]), and
* @see Tests#expectingSpecificProblemsFor(IPath, Problem[], boolean).
* Unfortunately this variant isn't implemented there.
*/
protected void expectingOnlySpecificProblemsFor(IPath root, ExpectedProblem[] expectedProblems) {
if (DEBUG)
printProblemsFor(root);
Problem[] rootProblems = env.getProblemsFor(root, AptPlugin.APT_COMPILATION_PROBLEM_MARKER);
for (int i = 0; i < expectedProblems.length; i++) {
ExpectedProblem expectedProblem = expectedProblems[i];
boolean found = false;
for (int j = 0; j < rootProblems.length; j++) {
if(expectedProblem.equalsProblem(rootProblems[j])) {
found = true;
rootProblems[j] = null;
break;
}
}
if (!found) {
printProblemsFor(root);
}
assertTrue("problem not found: " + expectedProblem.toString(), found); //$NON-NLS-1$
}
for (int i = 0; i < rootProblems.length; i++) {
if(rootProblems[i] != null) {
printProblemsFor(root);
assertTrue("unexpected problem: " + rootProblems[i].toString(), false); //$NON-NLS-1$
}
}
}
/** Verifies that the given element has specific problems.
*/
protected void expectingSpecificProblemsFor(IPath root, ExpectedProblem[] problems) {
if (DEBUG)
printProblemsFor(root);
Problem[] rootProblems = env.getProblemsFor(root, AptPlugin.APT_COMPILATION_PROBLEM_MARKER);
next : for (int i = 0; i < problems.length; i++) {
ExpectedProblem problem = problems[i];
for (int j = 0; j < rootProblems.length; j++) {
Problem rootProblem = rootProblems[j];
if (rootProblem != null) {
if (problem.equalsProblem(rootProblem)) {
rootProblems[j] = null;
continue next;
}
}
}
for (int j = 0; j < rootProblems.length; j++) {
Problem pb = rootProblems[j];
if (pb == null) continue;
System.out.print("got pb: new Problem(\"" + pb.getLocation() + "\", \"" + pb.getMessage() + "\", \"" + pb.getResourcePath() + "\"");
System.out.print(", " + pb.getStart() + ", " + pb.getEnd() + ", " + pb.getCategoryId());
System.out.println(")");
}
assertTrue("missing expected problem : " + problem, false);
}
}
/** Verifies that the given element has a specific problem and
* only the given problem.
*/
protected void expectingOnlySpecificProblemFor(IPath root, ExpectedProblem problem) {
expectingOnlySpecificProblemsFor(root, new ExpectedProblem[] { problem });
}
protected static void sleep( long millis )
{
long end = System.currentTimeMillis() + millis;
while ( millis > 0 )
{
try
{
Thread.sleep( millis );
}
catch ( InterruptedException ie )
{}
millis = end - System.currentTimeMillis();
}
}
}