| /******************************************************************************* |
| * Copyright (c) 2005, 2007 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(); |
| } |
| } |
| |
| |
| |
| } |