Bug 530665: Filer.getResource must not flag output file as written for
spring-boot-configuration-processor compatibility

Change-Id: I8eb3026d6fe97f7cc0a1e2b2cf46e287f08d1c8e
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
index 69a7439..00ae9b8 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug530665Proc.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug530665Proc.java
new file mode 100644
index 0000000..01c79e2
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug530665Proc.java
@@ -0,0 +1,87 @@
+package org.eclipse.jdt.compiler.apt.tests.processors.AnnotationProcessorTests;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Set;
+
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+
+import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
+
+@SupportedAnnotationTypes("*")
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class Bug530665Proc extends BaseProcessor {
+
+	private Filer filer;
+
+	@Override
+	public synchronized void init(ProcessingEnvironment processingEnv) {
+		super.init(processingEnv);
+		filer = processingEnv.getFiler();
+	}
+
+	@Override
+	public void reportError(String value) {
+		super.reportError(value);
+		throw new RuntimeException(value);
+	}
+	
+	@Override
+	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+		if (roundEnv.errorRaised()) {
+			return false;
+		}
+
+		try {
+			filer.getResource(StandardLocation.CLASS_OUTPUT, "targets/AnnotationProcessorTests/bug530665", "nonexists.txt");
+			reportError("Filer.getResource(nonexists.txt) did NOT throw!");
+		} catch (IOException e) {
+			// ignored
+		}
+		try {
+			// can be done multiple times...
+			filer.getResource(StandardLocation.CLASS_OUTPUT, "targets/AnnotationProcessorTests/bug530665", "preexists.txt");
+			filer.getResource(StandardLocation.CLASS_OUTPUT, "targets/AnnotationProcessorTests/bug530665", "preexists.txt");
+		} catch (IOException e) {
+			reportError("Filer.getResource(preexists.txt) threw: " + e);
+		}
+
+		if (roundEnv.processingOver()) {
+			try {
+				FileObject fo = filer.createResource(StandardLocation.CLASS_OUTPUT, "targets/AnnotationProcessorTests/bug530665", "nonexists.txt");
+				try(Writer writer = fo.openWriter()) {
+					writer.append("Test");
+				}
+			} catch(IOException e) {
+				reportError("Filer.createResource(nonexists.txt) threw: " + e);
+			}
+			try {
+				filer.createResource(StandardLocation.CLASS_OUTPUT, "targets/AnnotationProcessorTests/bug530665", "nonexists.txt");
+				reportError("Filer.createResource(nonexists.txt) second attempt did NOT throw!");
+			} catch(IOException e) {
+				// ignored
+			}
+	
+			try {
+				FileObject fo = filer.createResource(StandardLocation.CLASS_OUTPUT, "targets/AnnotationProcessorTests/bug530665", "preexists.txt");
+				if (!fo.delete()) {
+					reportError("FileObject.delete() failed!");
+				}
+			} catch(IOException e) {
+				reportError("Filer.createResource(preexists.txt) threw: " + e);
+			}
+
+			reportSuccess();
+		}
+		return false;
+	}
+	
+}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/targets/AnnotationProcessorTests/bug530665/A.java b/org.eclipse.jdt.compiler.apt.tests/resources/targets/AnnotationProcessorTests/bug530665/A.java
new file mode 100644
index 0000000..132e1e2
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/targets/AnnotationProcessorTests/bug530665/A.java
@@ -0,0 +1,3 @@
+package targets.AnnotationProcessorTests.bug530665;
+
+public class A {}
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AnnotationProcessorTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AnnotationProcessorTests.java
index ae091ac..7be23b6 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AnnotationProcessorTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AnnotationProcessorTests.java
@@ -175,4 +175,29 @@
 		assertEquals("incorrect number of messages", 0, diagnosticListener.count);
 		assertNull(System.getProperty(PROC));
 	}
+
+	public void testBug530665() throws IOException {
+		JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+		File srcFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), "targets", "AnnotationProcessorTests", "bug317216");
+		BatchTestUtils.copyResources("targets/AnnotationProcessorTests/bug530665", srcFolder);
+		File binFolder = TestUtils.concatPath(BatchTestUtils.getBinFolderName(), "targets", "AnnotationProcessorTests", "bug530665");
+		binFolder.mkdirs();
+		File preexistsFile = new File(binFolder, "preexists.txt");
+		assertTrue(preexistsFile.createNewFile());
+		File nonexistsFile = new File(binFolder, "nonexists.txt");
+		assertTrue(!nonexistsFile.exists());
+
+		List<String> options = new ArrayList<String>();
+		final String PROC = "org.eclipse.jdt.compiler.apt.tests.processors.AnnotationProcessorTests.Bug530665Proc";
+		options.add("-processorpath");
+		options.add(" ");
+		options.add("-processor");
+		options.add(PROC);
+		DiagnosticReport<JavaFileObject> diagnosticListener = new DiagnosticReport<JavaFileObject>();
+		BatchTestUtils.compileTree(compiler, options, srcFolder, false, diagnosticListener);
+		assertEquals("succeeded", System.getProperty(PROC));
+
+		assertTrue(!preexistsFile.exists()); // deleted
+		assertTrue(nonexistsFile.exists()); // rewritten
+	}
 }
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
index c7a784e..31a29ea 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchFilerImpl.java
@@ -161,8 +161,6 @@
 		if (_createdFiles.contains(uri)) {
 			throw new FilerException("Resource already created : " + location + '/' + pkg + '/' + relativeName); //$NON-NLS-1$
 		}
-
-		_createdFiles.add(uri);
 		return fo;
 	}