8054465: Add --permit-artifact=bar to sjavac
authorohrstrom
Sat, 09 Aug 2014 00:56:29 +0200
changeset 26089 196b7a50a266
parent 26088 f479ca655ba1
child 26090 9e2489a79aca
8054465: Add --permit-artifact=bar to sjavac Summary: Add --permit-artifact=bar to white-list files that have been written to the destination directory and that sjavac should not delete. Reviewed-by: jjg, alundblad
langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java
langtools/src/share/classes/com/sun/tools/sjavac/Main.java
langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java
langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java
langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java
langtools/test/tools/sjavac/OptionDecoding.java
langtools/test/tools/sjavac/SJavac.java
--- a/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/JavacState.java	Sat Aug 09 00:56:29 2014 +0200
@@ -127,7 +127,11 @@
     // Where to send stdout and stderr.
     private PrintStream out, err;
 
-    JavacState(Options options, boolean removeJavacState, PrintStream o, PrintStream e) {
+    // Command line options.
+    private Options options;
+
+    JavacState(Options op, boolean removeJavacState, PrintStream o, PrintStream e) {
+        options = op;
         out = o;
         err = e;
         numCores = options.getNumCores();
@@ -147,7 +151,7 @@
             // We do not want to risk building a broken incremental build.
             // BUT since the makefiles still copy things straight into the bin_dir et al,
             // we avoid deleting files here, if the option --permit-unidentified-classes was supplied.
-            if (!options.isUnidentifiedArtifactPermitted()) {
+            if (!options.areUnidentifiedArtifactsPermitted()) {
                 deleteContents(binDir);
                 deleteContents(gensrcDir);
                 deleteContents(headerDir);
@@ -511,7 +515,8 @@
         allKnownArtifacts.add(javacState);
 
         for (File f : binArtifacts) {
-            if (!allKnownArtifacts.contains(f)) {
+            if (!allKnownArtifacts.contains(f) &&
+                !options.isUnidentifiedArtifactPermitted(f.getAbsolutePath())) {
                 Log.debug("Removing "+f.getPath()+" since it is unknown to the javac_state.");
                 f.delete();
             }
@@ -604,13 +609,16 @@
     /**
      * Recursively delete a directory and all its contents.
      */
-    private static void deleteContents(File dir) {
+    private void deleteContents(File dir) {
         if (dir != null && dir.exists()) {
             for (File f : dir.listFiles()) {
                 if (f.isDirectory()) {
                     deleteContents(f);
                 }
-                f.delete();
+                if (!options.isUnidentifiedArtifactPermitted(f.getAbsolutePath())) {
+                    Log.debug("Removing "+f.getAbsolutePath());
+                    f.delete();
+                }
             }
         }
     }
--- a/langtools/src/share/classes/com/sun/tools/sjavac/Main.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/Main.java	Sat Aug 09 00:56:29 2014 +0200
@@ -305,7 +305,7 @@
         // For examples, files that have been manually copied into these dirs.
         // Artifacts with bad timestamps (ie the on disk timestamp does not match the timestamp
         // in javac_state) have already been removed when the javac_state was loaded.
-        if (!options.isUnidentifiedArtifactPermitted()) {
+        if (!options.areUnidentifiedArtifactsPermitted()) {
             javac_state.removeUnidentifiedArtifacts();
         }
         // Go through all sources and taint all packages that miss artifacts.
--- a/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Option.java	Sat Aug 09 00:56:29 2014 +0200
@@ -231,7 +231,14 @@
             helper.logLevel("info");
         }
     },
-    PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Keep unidentified artifacts in destination directory") {
+    PERMIT_ARTIFACT("--permit-artifact=", "Allow this artifact in destination directory") {
+        @Override
+        protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
+            String a = iter.current().substring(arg.length());
+            helper.permitArtifact(Paths.get(a).toFile().getAbsolutePath());
+        }
+    },
+    PERMIT_UNIDENTIFIED_ARTIFACTS("--permit-unidentified-artifacts", "Allow unidentified artifacts in destination directory") {
         @Override
         protected void processMatching(ArgumentIterator iter, OptionHelper helper) {
             helper.permitUnidentifiedArtifacts();
--- a/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/OptionHelper.java	Sat Aug 09 00:56:29 2014 +0200
@@ -80,6 +80,9 @@
     /** Record path for reference source list */
     public abstract void compareFoundSources(Path referenceList);
 
+    /** Record a single permitted artifact */
+    public abstract void permitArtifact(String f);
+
     /** Record the fact that unidentified artifacts are permitted */
     public abstract void permitUnidentifiedArtifacts();
 
--- a/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/src/share/classes/com/sun/tools/sjavac/options/Options.java	Sat Aug 09 00:56:29 2014 +0200
@@ -32,6 +32,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
 
 import com.sun.tools.sjavac.Transformer;
 
@@ -51,7 +53,8 @@
 
     private String logLevel = "info";
 
-    private boolean permitUnidentifiedArtifact = false;
+    private Set<String> permitted_artifacts = new HashSet<>();
+    private boolean permitUnidentifiedArtifacts = false;
     private boolean permitSourcesInDefaultPackage = false;
 
     private Path sourceReferenceList;
@@ -119,10 +122,15 @@
         return logLevel;
     }
 
+    /** Returns true iff the artifact is permitted in the output dir. */
+    public boolean isUnidentifiedArtifactPermitted(String f) {
+        return permitted_artifacts.contains(f);
+    }
+
     /** Returns true iff artifacts in the output directories should be kept,
      * even if they would not be generated in a clean build. */
-    public boolean isUnidentifiedArtifactPermitted() {
-        return permitUnidentifiedArtifact;
+    public boolean areUnidentifiedArtifactsPermitted() {
+        return permitUnidentifiedArtifacts;
     }
 
     /** Returns true iff sources in the default package should be permitted. */
@@ -249,7 +257,11 @@
         if (permitSourcesInDefaultPackage)
             args.addArg(Option.PERMIT_SOURCES_WITHOUT_PACKAGE);
 
-        if (permitUnidentifiedArtifact)
+        for (String f : permitted_artifacts) {
+            args.addArg(Option.PERMIT_ARTIFACT, f);
+        }
+
+        if (permitUnidentifiedArtifacts)
             args.addArg(Option.PERMIT_UNIDENTIFIED_ARTIFACTS);
 
         // Translation rules
@@ -400,8 +412,13 @@
         }
 
         @Override
+        public void permitArtifact(String f) {
+            permitted_artifacts.add(f);
+        }
+
+        @Override
         public void permitUnidentifiedArtifacts() {
-            permitUnidentifiedArtifact = true;
+            permitUnidentifiedArtifacts = true;
         }
 
         @Override
--- a/langtools/test/tools/sjavac/OptionDecoding.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/test/tools/sjavac/OptionDecoding.java	Sat Aug 09 00:56:29 2014 +0200
@@ -25,7 +25,7 @@
 
 /*
  * @test
- * @bug 8035063
+ * @bug 8035063 8054465
  * @summary Tests decoding of String[] into Options.
  *
  * @build Wrapper
@@ -192,13 +192,16 @@
         assertEquals(17, options.getNumCores());
         assertEquals("debug", options.getLogLevel());
         assertEquals(false, options.isDefaultPackagePermitted());
-        assertEquals(false, options.isUnidentifiedArtifactPermitted());
+        assertEquals(false, options.areUnidentifiedArtifactsPermitted());
+        assertEquals(false, options.isUnidentifiedArtifactPermitted(Paths.get("bar.txt").toFile().getAbsolutePath()));
 
         options = Options.parseArgs("--permit-unidentified-artifacts",
+                                    "--permit-artifact=bar.txt",
                                     "--permit-sources-without-package");
         assertEquals("info", options.getLogLevel());
         assertEquals(true, options.isDefaultPackagePermitted());
-        assertEquals(true, options.isUnidentifiedArtifactPermitted());
+        assertEquals(true, options.areUnidentifiedArtifactsPermitted());
+        assertEquals(true, options.isUnidentifiedArtifactPermitted(Paths.get("bar.txt").toFile().getAbsolutePath()));
     }
 
     // Test server configuration options
--- a/langtools/test/tools/sjavac/SJavac.java	Fri Aug 08 21:26:23 2014 +0200
+++ b/langtools/test/tools/sjavac/SJavac.java	Sat Aug 09 00:56:29 2014 +0200
@@ -25,7 +25,7 @@
 /*
  * @test
  * @summary Test all aspects of sjavac.
- * @bug 8004658 8042441 8042699 8054461 8054474
+ * @bug 8004658 8042441 8042699 8054461 8054474 8054465
  *
  * @build Wrapper
  * @run main Wrapper SJavac
@@ -101,6 +101,7 @@
         incrementalCompileTestFullyQualifiedRef();
         compileWithAtFile();
         testStateDir();
+        testPermittedArtifact();
 
         delete(gensrc);
         delete(gensrc2);
@@ -527,6 +528,36 @@
                                      "bar/javac_state");
     }
 
+    /**
+     * Test white listing of external artifacts inside the destination dir.
+     * @throws Exception If test fails
+     */
+    void testPermittedArtifact() throws Exception {
+        System.out.println("\nVerify that --permit-artifact=bar works.");
+        System.out.println("-------------------------------------------");
+
+        delete(gensrc);
+        delete(bin);
+
+        previous_bin_state = collectState(bin);
+
+        populate(gensrc,
+                 "alfa/omega/A.java",
+                 "package alfa.omega; public class A { }");
+
+        populate(bin,
+                 "alfa/omega/AA.class",
+                 "Ugh, a messy build system (tobefixed) wrote this class file, sjavac must not delete it.");
+
+        compile("--log=debug", "--permit-artifact=bin/alfa/omega/AA.class", "-src", "gensrc", "-d", "bin", serverArg);
+
+        Map<String,Long> new_bin_state = collectState(bin);
+        verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state,
+                                     "bin/alfa/omega/A.class",
+                                     "bin/alfa/omega/AA.class",
+                                     "bin/javac_state");
+    }
+
     void removeFrom(Path dir, String... args) throws IOException {
         for (String filename : args) {
             Path p = dir.resolve(filename);